0 Пользователей и 1 Гость просматривают эту тему.
  • 9 Ответов
  • 993 Просмотров
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
Joomla работает не очень комфортно, если число статей переваливает за 10-20 тысяч (в общем виде новостной сайт).
Вариантом решения является периодическая архивация (если структура данных позволяет). Представляется пока что два варианта "прозрачной" для пользователя архивации (чтобы он почти ничего не заметил):
1. Часть статей перегоняется в HTML (как выдает <jdoc:include type="component" />) вместе с комментариями jcomments, засовывается в архив. Затем в шаблоне в месте вставки компонента вставляем if .. then с выбором нужного источника - Joomla или адаптер для вытаскивания статьи из архива
2. Дублируем БД. У второй меняем префикс таблиц. Из основной вырезаем архивные материалы, во второй оставляем только их. В главном index.php определяем по номеру материала к какой БД он принадлежит и "на лету" меняем префикс таблиц $dbprefix в configuration.php

Плюсы 1 варианта:
уменьшаем базу, скорость
минусы:
теряем "поиск"

Плюсы 2 варианта:
можно переписать "поиск" для работы с двумя БД
минусы:
вторая база данных


Жду конструктивную критику.
« Последнее редактирование: 21.01.2018, 06:01:21 от ruslan13 »
*

kern.USR

  • Давно я тут
  • 805
  • 61 / 1
Настраиваем кэш, избавляемся от "тормрзных" модулей и не выдумываем велосипеды!
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
У меня база (_content) растет в среднем со скоростью 1Гб в год. И хочется еще больше. В любом случае рано или поздно придется архивировать.
А "избавиться" от тормозных модулей по трудозатратам примерно соответствует и 1, и 2 варианту.

2-ой вариант не подойдет как есть - иначе все модули тоже будут обращаться ко второй БД, это плохо. Нужно дублировать только таблицу _content и в компоненте выбирать, к которой из них обращаться. Или на уровне БД встроить логику определения по id из какой таблицы брать данные (если это возможно).

Но мне больше нравится 1-ый вариант. "Поиск" можно использовать гугловский по сайту. У них "винты" бездонные )
« Последнее редактирование: 09.01.2018, 18:41:11 от ruslan13 »
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
https://ruhighload.com/post/%D0%A8%D0%B0%D1%80%D0%B4%D0%B8%D0%BD%D0%B3+%D0%B8+%D1%80%D0%B5%D0%BF%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F
Да, sharding - именно второй вариант. Проблема только, что в Joomla так просто БД у запроса не поменяешь (без изменение коренных библиотек). И sharding не решает проблему тормозов ACL (кроме как добавлением мощности железа).
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
Реализовал первый вариант архива, все совсем просто.

Перегоняем этим скриптом статьи в HTML архив. Скрипт принимает два параметра - начало и конец диапазона id статей:

Код
for ($id = $argv[1]; $id < $argv[2]; $id++) {
getPage($id);
}
function getPage($id) {
$dir = (int)($id/1000);

if (file_exists("archive/" . $dir . "/" . $id . ".html")) {
   return;
}

echo $id . " ";

if( $curl = curl_init() ) {
curl_setopt($curl,CURLOPT_URL,"http://yoursite.com/" . $id . "-?tmpl=component&type=raw");
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_HEADER,false);
$data = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpcode<200 || $httpcode>=300) return;
}

if (!file_exists("archive/" . $dir)) {
   mkdir("archive/" . $dir, 0775, true);
}

$fd = fopen("archive/" . $dir . "/" . $id . ".html", 'w') or die("не удалось создать файл");
fwrite($fd, $data);
fclose($fd);
}

Архив создается директориями по 1000 файлов. Удаляем из архив те материалы, которые не нужно архивировать:

Код
include "../configuration.php";
$config = new JConfig();
$mysqli = new mysqli($config->host, $config->user, $config->password, $config->db);

$res = $mysqli->query("SELECT id FROM " . $config->dbprefix . "content WHERE catid < 9 OR catid IN (14,15,16)");
while ($row = $res->fetch_assoc()) {
    $id = $row['id'];
$dir = (int)($id/1000);
if (file_exists($file = "archive/" . $dir . "/" . $id . ".html")) {
   unlink($file);
}
}

Ну и собственно работа с архивом - в самое начало главного джумловского index.php инклюдим следующий файл:

Код
$i = strripos($_SERVER['REQUEST_URI'], "/") + 1;
$j = stripos($_SERVER['REQUEST_URI'], "-", $i);
$aid = substr($_SERVER['REQUEST_URI'], $i, $j-$i);

$dir = (int)($aid/1000);
$content = dirname(__FILE__). "/misc/archive/" . $dir . "/" . $aid . ".html";

if ($aid &&
$aid < 45000 &&
file_exists($content)) {

include_part("before");
include $content;
include_part("after");

exit;
}

function include_part($part) {
$file = $_SERVER['DOCUMENT_ROOT'] . "/templates/lightblog/comp_" . $part . "_cache.html";
if (!file_exists($file) || (time() - filemtime($file)) > 3600) {
file_put_contents($file, file_get_contents("http://" . $_SERVER['HTTP_HOST'] . "/?tmpl=comp_" . $part), LOCK_EX);
}
include $file;
}

Логика простая: вытаскиваем из url id статьи и проверяем - если она есть в архиве, берём оттуда; иначе - запускаем фреймворк.

Вокруг самой статьи есть шаблонная обертка из модулей и прочего. Делим ее на две части - до и после. И кэшируем самостоятельно с периодом 1 час. В корневой директории шаблона лежат файлы comp_before.php и comp_after.php - это код index.php шаблона до и после включения <jdoc:include type="component" />

Итого, все архивные статьи берутся с диска. Плюс 48 обращений в Joomla в сутки, чтобы обновить шаблонную обертку. Раз в месяц запускаем скрипт архивирования с нужными параметрами новых статей, и скрипт удаления материалов, которые не нужно архивировать.

Все материалы остаются (при желании) в БД, чтобы обеспечить полнотекстовый поиск.

В планах: запихать весь архив в один zip (если скорость чтения случайного файла будет приемлема), и использовать модель кэширования шаблонной обертки для активного кэширования - части обновляются тогда, когда меняются данные в базе.
« Последнее редактирование: 21.01.2018, 06:00:36 от ruslan13 »
*

ProtectYourSite

  • Завсегдатай
  • 1714
  • 97 / 4
  • Безопасность вебсайтов
Как-то очень костыльно и индивидуально.
Взять даже первый скрипт:
1) зачем обращаться cURL к своему собственному сайту,  если можно выцепить с бд?
2)даже используя cURL постоянно рвать соединение и не использовать keepalive достаточно не практично.
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
зачем обращаться cURL к своему собственному сайту,  если можно выцепить с бд?
Чтобы сохранился шаблон компонента статьи. Его, конечно, можно руками прописать, но проще запустить этот скрипт.
Код не оптимизирован ни разу для выборки из БД, с этим не спорю. Но свою задачу делает.
Затраты на HTTP соединение - ничто, по сравнению с запросами к БД.
*

ruslan13

  • Захожу иногда
  • 156
  • 2 / 0
Небольшой отчет по оптимизации Joomla с БД на 50000 статей.

Отключение ACL (в первую очередь для mod_articles_category и mod_articles_popular) снизило нагрузку на сервер раза в два (по-разному, иногда запросы зависали вообще на несколько секунд - возможно, у хостера в целом нагрузка на БД была большая в это время).

Чистка таблицы assets по этой схеме (https://www.itoctopus.com/creating-new-articles-on-your-joomla-website-is-taking-a-long-time-clean-your-assets-table) уменьшила нагрузку на сервер еще где-то в 1.5-2 раза

Перегонка в статичный архив старых статей (90% таблицы content) - еще в несколько раз, из-за поисковых ботов, которые дают много тысяч хитов каждые сутки по всему сайту.

Но основный эффект - от уменьшения таблицы content (пришлось пожертвовать "поиском"). Нагрузка на БД снизилась раз в 10. Вот скриншот (два всплеска - удаление записей из таблицы):


Я не большой спец в MySQL, но думаю, все-таки, что запросы Joomla очень не оптимизированы - 50000 записей это не такая большая таблица, чтобы стандартные модули  mod_articles_category и mod_articles_popular и остальные запросы в ней так тормозили (и это уже без ACL проверок).

Стандартное кэширование Joomla вообще не заметил, чтобы как-то влияло на нагрузку сервера.

Ну и необходимо изучать логи apache в поисках "черных дыр" (WebLog Expert - хороший инструмент). У меня сотни запросов со всего интернета шли на вот эти ненужные (мне) и не показываемые страницы, например:

Код
RewriteCond %{QUERY_STRING} view=registration [OR]
RewriteCond %{REQUEST_URI} /component/mailto
RewriteRule ^.*$  - [F]


Основной вывод: Joomla на больших сайтах нужно подрабатывать. В первую очередь - делать кастомное кэширование.
« Последнее редактирование: 24.01.2018, 04:51:53 от ruslan13 »
*

kep

  • Новичок
  • 13
  • 1 / 0
nginx тоже умеет кэшировать определенные URL.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

0 - Обнаружена ошибка. Call to undefined method Joomla\Registry\Registry::getVa

Автор Victor333

Ответов: 22
Просмотров: 372
Последний ответ 09.11.2018, 11:46:17
от Victor333
Как правильно задать формат в категории статей?

Автор Анна Леонтьева

Ответов: 5
Просмотров: 482
Последний ответ 03.11.2018, 21:23:30
от Анна Леонтьева
Редактирование шаблона админки Joomla. Формы размещения статьи [Решено]

Автор Eholov

Ответов: 8
Просмотров: 324
Последний ответ 18.10.2018, 21:16:55
от lexxbry
Медиа менеджер и редактор фоток в Joomla

Автор informprostor

Ответов: 13
Просмотров: 590
Последний ответ 17.10.2018, 20:05:33
от informprostor
Как исправить ошибку Error: 500 при обновлении Joomla до 3.8.1?

Автор Dmitry T.

Ответов: 7
Просмотров: 1184
Последний ответ 16.10.2018, 23:38:46
от Septdir