Мда, отследил я , сколько запросов идет от Друпал к базе с переводом( да и основным текстом) и ужаснулся.На главной например у меня подсчитывает 560 запросов, и это еще только пока, так как никакого функционала ещё нет. Как же это серверы то терпят? А если 2000 пользователей? Что, никто не пробовал перевести это всё из базы в текстовые файлы? Кто нить пробовал и не вышло или никто и не пытался? Если я это сделаю - это кому-нибудь тут понадобится? Костыль, конечно, я посмотрел - там переписать пару функция да пару конвертеров изобразить простеньких - из .ро файлов .Это пока никто из программеров не добрался до Друпала или все скрывают ?
Комментарии
Обсуждалось уже.
http://drupal.ru/node/2118
Переводы кэшируются.
Некоторые правда переводят прямо в модулях.
Ходят слухи что axel делал модуль для переводов без баз. Но он молчит.
http://drupal.ru/node/2118#comment-9637
Да темка интересная, спасибо за ссылку. Я провел один простой эксперимент - подсчитать, куда же в основном в смысле таблиц в базе лазиет Друпал.И выяснилась достаточно странная вещь - больше всего запросов даже не на locale идет ( хотя там запросы двойные - то есть сразу одним запросом в две базы лезет), а на url_alias - по 60 запросов за раз, хотя у меня счас алиасов этих всего 12.Вотгде поле для улучшения.Для примера статистика некоторых страниц( моя, а не devel? который нихрена не считает)
главная -
добавить категорию
добавить Запись в дневнике
Это при отсутствии кэша всё, так как в основном предполагаются зарегистрированные пользователи.
Видно, куда тут копать, чем и собираюсь заняться в ближайшее время.
P.S Подсчитывалось всё втупую, путем правки кода.
Считалось кол-во обращения в функцию _db_query($query, $debug = 0) из
database.mysql.inc , которая собственно и делает запросы. Там проверялся запрос на содержания имен баз.
генерируется функцией l(). C ее помощью формируются все ссылки в друпале кроме тех которые сделанны напрямую через html. если в баз ть хоть один алиас будут запрашиавться все если нет, то небудет.
Как придумаете поделитесь.
вот еще мои замеры
http://drupal.ru/node/2063#comment-9833
чё тут думать - лезть в код и править
файл [b]path.inc[/b]
Вместо
if (!empty($_GET['q'])) {
$_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
}
else {
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
}
}
ставить
global $map_alias;
$c=count($map_alias);
if (empty($c))
{
$sql = "Select src,dst FROM {url_alias} ";
$res=db_query($sql);
while( $row=db_fetch_array($res))
{
$map_alias[$row['src']]=$row['dst'];
}
}
if (!empty($_GET['q'])) {
$_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
}
else {
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node'));
}
}
вместо
static $map = array();
static $count = NULL;
if ($count === NULL) {
$count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
}
if ($action == 'wipe') {
$map = array();
}
elseif ($count > 0 && $path != '') {
if ($action == 'alias') {
if (isset($map[$path])) {
return $map[$path];
}
if ($alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path))) {
$map[$path] = $alias;
return $alias;
}
else {
$map[$path] = $path;
}
}
elseif ($action == 'source') {
if ($alias = array_search($path, $map)) {
return $alias;
}
if (!isset($map[$path])) {
if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) {
$map[$src] = $path;
return $src;
}
}
}
}
return FALSE;
}
ставим
global $map_alias;
static $map = array();
if ($action == 'wipe') {
$map = array();
}
elseif ($path != '') {
if ($action == 'alias') {
if (!isset($map_alias[$path])) $map_alias[$path]=$path;
return $map_alias[$path];
}
elseif ($action == 'source') {
if (is_array($map_alias) and $alias = array_search($path, $map_alias)) {
return $alias;
}
else return False;
}
}
return FALSE;
}
В итоге получаем один запрос к базе вместо 60-70.
А что на Drupal.org говрят по этму поводу - если так все просто - то это серьезный баг в друпале - представьте - 70 лишних запросов на страницу - не думаю что там такой ляп пропустили...
в общем отправил на http://drupal.org/node/88544 - посмотрим что скажут
Решил попробовать Ваше решение в 6-1 версии Друпала - и вот что получается: 1-й кусок кода можно заменить - он без изменений, а вот во втором есть изменения - там добавилась еще $path_language = '' и т.д.
Можете переделать ваше решение для 6-й версии?
Заранее спасибо ...
Мда , переводы кешируются, ага, только не всегда, они там сбрасываются, вот при сложном редактировании контейнера обнаружил новый рекорд:
count sql-locale: 580
count sql-cache: 51
count sql-url: 2
count sql-category: 16
count other: 49
count sql-all: 719
719 запросов, из них 580 - locale.
Для того, чтобы сработало на локалке на pentium 2.8 - пришлось увеличить max_execution_time( Максимальное возможное время выполнения сценария ) до двух минут.
Когда чего-то на сайте меняется (админом, в основном), то все кэши (или часть их) сбрасываются. Но ведь это не штатный режим работы сайта? Т.е. основную часть времени - они (кэши) используются.
Про max_execution_time: да, есть такое дело.
Сделал такое, в local.module исправил ф-ю local на
// Задаем текущий язык проекта
putenv("LANG=ru_RU");
// Задаем текущую локаль (кодировку)
setlocale (LC_ALL,"ru_RU");
// Указываем имя домена
$domain = 'messages';
// Задаем каталог домена, где содержатся переводы
bindtextdomain ($domain, "./locale");
// Выбираем домен для работы
textdomain ($domain);
// Если необходимо, принудительно указываем кодировку (эта строка не
// обязательна, она нужна, если вы хотите выводить текст в отличной от
// текущей локали кодировке).
bind_textdomain_codeset($domain, 'UTF-8');
return _($string);
}
В корне друпала создаю папки locale/ru_RU/LC_MESSAGES/
в папку LC_MESSAGES ложим .po и .mo файлы с переводом. Вроде работает, и базу за переводом не лезет.
...правда с множественными формами глючит, может кто доделает.
Поясни, что имеется ввиду - не очень пока привык к терминологии
Не переводит слова в множественном числе.
Например показывает "На данный момент в онлайне 0 users, 0 guests."
а если все слова в единственном числе пишет нормально "На данный момент в онлайне 1 пользователь, 1 гость."
Или "1 неделя 6 days назад", "2 weeks 1 день назад"...
Не разобрался как работать с множественными формами.
Замечтально, только зачем же
putenv() .. bind_textdomain_codeset(..)
при каждом-то запросе? Может лучше тогда добавить в locale.module обработкуhook_init()
и туда запихнуть инициализацию?Ну и если пошла такая пляска... Вот сюда ещё можно глянуть: может оказаться ползным. Это модуль для Дрюпала 4.6, который и реализует перевод через
gettext
. Правда статус этого молуя - "экспериментальный".Просто это альфа версия
Ясно
Сорри - глюк случился.
2Модератор: удалите, пожалуйста это сообщение...
[url]http://drupal.org/node/66844[/url]
вот кстати чувак тоже озадачился алиасами, я правда не разобрался в чем суть, но может поможет
Да он тоже самое сделал, только несколько хуже - у меня вообще нет запросов к базе в этой функции - единственный запрос при инициализации модуля path , а дальше все данные берутся из глобального массива - он же просто немного оптимизировал код - на вскидку - только хуже стало.Жаль, английским не владею, чтобы сказать ему это сам. Да, может быть мой код при алиасах порядка 100000 начнет подтормаживать( с памятью), но обычно алиасов не больше тысячи.
Это смотря какого сайта.Сайты с активным коммьюнити как раз и нагрузят этот кэш мама не горюй
Возможно. Я пока не изучал этот вопрос...
а нельзя этот код впихнуть в ядро, если он лучше. Или есть какие-то грабли?
Да ради бога, впихивайте - предложите разработчикам,я по английскому не говорю.
А вообще - какого чёрта кеш в базе делает? Это то чья была светлая идея? В чём смысл?
Чья идея - думаю можно узнать подняв архив переписки разработчиков и ознакомившись с историей изменения исходников
Отчего кэш в БД? Могу предположить, что разработчикам:
cache_clear_all('menu:', TRUE);
например)Ну и к тому же БД и так используется, так что кэш в БД - это не очень большие дополнительные расходы при таком раскладе (повторюсь: тут мне надо ещё разобраться - а вдруг окажется, что файловые операции будут вообще медленее?! не забываем про всякие-разные проверки наличия, доступа, про блокировки...)
Подчеркну, что это мои измышления (IMHO, то есть...)
Кстати, а Вы не смотрели в сторону проекта файлового кэша? (не помню как модуль называется..) и ещё на drupal.org есть раздел, о том, как переводить страницы в статику и кэшировать их таким образом. Не пробовали? (Ссылок не дам - лень сейчас искать
вот в эту сторону гляньте
[url]http://drupal.org/project/fastpath_fscache[/url]
Во-во - я про это
Где-то я читал что Dries говорил что выигрыш по сравнению с базой не стоит тех сложностей так как блоки все равно из базы берутся и для зарегистрированных пользователей тоже все из базы, правда не учитывали локализацию.
все сделал по инструкции - но папка cache пустая
Выход вижу один - отключать locale ( чтоб всё бралось через include() ) и заодно( это второй этап, менее очевидный)вырубать кеш, потому что всё равно предполагается, что в основном на сайте зарегистрированные пользователи будут.
[b]чё тут думать - лезть в код и править
файл path.inc[/b]
так как это рабочий хак? на самом деле уменьшает запросы к БД? или он ещё экспериментальный и не работает нормально?
[b]Добавлено:[/b]
на самом деле работает... очень быстро стало всё обрабатываться... странички прямо за мгновение открываются... тормоза исчезли при добавлении постов... класс...
Странные результаты показывает модуль devel
До установки патча на главной странице было 326 запросов за 87мсек и 3.3с на всю страницу.
После установки стало 210 запросов за 84 мсек и 3с на всю страницу.
Странно не то что слабый эффект дало а то что визуально страница стала открываться как минимум в два раза быстрее! Сайт почти без графики и быстро грузится даже на медленном канале и раньше напрягало вольяжное открытие стартовой даже с хорошей выделенки, теперь всё ок!
Биг тебе человеческий tnx
этот devel сам много кушает, полагаться на него нельзя, тесты надо проводить какими-нибудь сторонними способами...
реально раза в два (визуально) работает быстрее. джейсон, мега-респект!
напрягает только одна тема: после новой версии опять придется в этом всем разбираться.
Да понятно, что скажут. Скажут, что при большом количестве алиасов запрс будет слишком большим( там много маленьких запросов заменяется одним большим), что приведет к большому расходу памяти. Но для небольших сайтов( ИмХО меньше 10000 алиасов) всё это несущественно.
а как вообще отключить эти алиасы если мне они не нужны, или например их в .htaccess засунуть?
Очистить таблицу алиасов или грохнуть все в http://site.ru/admin/path
с mysql кешем тоже прям беда - не работает он так как надо - автоматически ничего не хранит и тут-же забывает, а если включить время жизни например 15 минут - то по прошествии их все забывается и странички опять начинают дико тормозить, при чем на обслуживание этого "кеша" в mysql и обратно гоняются огромные массивы, друпал в плане кеша просто разочаровал - может его вообще выкинуть из друпала? слишком много он ресурсов отбирает.
действительно, заметно быстрее стало постить материал.
не возражаешь если я об этом напишу в рассылке про Друпал?
пока рано для 6-й версии делать - сам на неё ещё не перешёл ))
А теперь?
Мега респект тебе и уважуха, jason32!
Я было начал сам переписывать path.inc а потом нашол твой код. Это то, что мне было надо. У меня на бисер.инфо около 10 строк в url_alias а запросов туда по 100 штук на каждой странице.
Недавно я поставил модуль-патч Модуль кеширования алиасов путей
от seaji. Вначале мне показалось, что работает хорошо а потом выяснилось что не очень.
Ешё раз спасибо!
Ребята, поставил этот хак. Сайт стал летать, но почему-то перестали работать алиасы страницы профиля. При логине на сайт страница профиля грузиться, а при последующем обновлении страницы выдает 404. Друпал 6.13
Неудивительно, потому что писалось ещё для 5-ки и на 6-м Друпале не тестировалось
Да, переводы в Drupal это больная тема) В принципе сейчас ценой долгих мучений заставил таки расширение PHP Gettext заработать под Windows. Есть свои нюансы, но вполне можно сделать кросс-платформенное решение. Этот недописанный модуль для 4-и совсем неплох, единственное конечно что в Drupal столько поменялось, что его легче переписать. Сейчас пытался сравнить производительность системы, если:
Точно сказать не могу, что быстрее, но (imho) второй способ более правильный. Ведь Gettext в принципе и рассчитан на компиляцию переводов после их редактирования.
Так что задам такой вопрос: кому-нибудь кроме меня нужно, чтобы я написал модуль для Drupal 6, который заменит функциональность модуля Locale и позволит работать с файлами .mo напрямую, вместо базы данных? Сейчас у меня это хак, но если кому-то будет нужен, сделаю модуль.
Даже на хак интересно бы было взглянуть.
Ты хочешь заработать или помочь сообществу?
Помочь сообществу. Моего в модуле толком не будет, разве я изобрел Gettext?) Конечно бесплатно... Просто это кому-то кроме меня нужно? Если нужно, сделаю модулем.
Думаю что нужно, все будут в восторге, давно такие запросы были
Реанимирую эту тему, так как сейчас для drupal 8 пересматривается хранилище переводов. если есть какие-то пожелания или идеи то http://drupal.org/node/532512