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

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

  • Давно я тут
  • 803
  • 60 / 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

  • Завсегдатай
  • 1546
  • 93 / 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

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

Joomla 3.5 ошибка Using $this when not in object context

Автор klara7

Ответов: 4
Просмотров: 2366
Последний ответ 18.09.2018, 13:32:26
от Nobillis
Вышел релиз Joomla! 3.8.12

Автор Apoca1ypto

Ответов: 51
Просмотров: 2130
Последний ответ 14.09.2018, 16:10:59
от web3.0
Выделение заголовков непрочитанных статей

Автор Almaziko

Ответов: 3
Просмотров: 85
Последний ответ 14.09.2018, 11:19:59
от lexxbry
Как убрать ссылку логотипа на себя на главной в Joomla 3.8?

Автор astinasty

Ответов: 12
Просмотров: 500
Последний ответ 05.09.2018, 15:15:52
от Kadimp
Вышел релиз Joomla 3.8.11

Автор Olg

Ответов: 40
Просмотров: 3104
Последний ответ 29.08.2018, 09:21:15
от Apoca1ypto