Как стать автором
Обновить

Комментарии 31

Почему бы не переложить весь рендер на клиент, и передавать только данные, которые кешируются на отлично?
У них и так CPU на нуле — зачем замедлять загрузку сайта клиентской шаблонизацией?
Что значит «у них и так CPU на нуле»? Клиентский рендер сейчас даже на телефонах за 3000 рублей работает с нормальной скоростью.
Суммарный CPU 50 000 пользовательских машин значительно превышает мощность вашего сервера :-)
С нормальной скоростью — не значит мгновенно.

Хороший сервак отдает страницу из мемкеша за 20-30 мс. Учитывая пинг и все прочие накладные расходы, выходит макс 100 мс. JSON будет отдаваться не намного быстрей, но потребует еще столько же на рендер шаблона.

Далее, отдавая чистый HTML, страница появится сразу почти не нагружая проц, пусть в слегка худшем качестве, в случае с клиентской шаблонизацией пользователь будет созерцать белый лист, пока не отработает JS.

И кстати, часто тупят даже топовые железки, особенно на сайтах с кучей клиентского кода (это я могу утверждать про ipad air, nexus 7, iphone 6). Для меня «тупят» — это когда открываемый мгновенно на компе сайт открывается на этих девайсах 1-1,5 секунды.

Клиентская шаблонизация — довольно специфичная технология, и пихать ее повсюду не стоит.
Я утверждаю что скорость загрузки при таком подходе, как минимум, не медленнее.
Учитывая пинг и все прочие накладные расходы, выходит макс 100 мс

Ага, так я и поверил. Довольно бесхитростная страница на 2013 yac'е грузилась не менее 450-500мс, ещё столько же, в среднем, браузер на отрисовку тратил.
В секунду можно уложиться в обоих подходах. Лучий вариант — комбинированый, когда изначальные данные приходят вместе со страницей, но собираются на клиенте.

И кстати, часто тупят даже топовые железки, особенно на сайтах с кучей клиентского кода

Это проблема плохой реализации и не более. Я встречал такие проекты, которые по 5мб пакованого JS'a на клиенте пытаются исполнять. Конечно всё тормозит. Если в феррари загрузить пол тонны картошки, то она тоже не такой шустрой окажется :-)
Ко всему нужно разумно подходить.

и пихать ее повсюду не стоит.

Скорее, последнее время, мест, куда её пихать не стоит, всё меньше. Есть редкие и очень специфичные исключения, которые даже в «уникальных» проектах редко проскакивают.
Да, тут я, наверное, не сказал, но требовалась так же жёсткая совместимость по браузерам. На тот момент ещё использовался (не поверите) IE 7. В Дагестане, например… И это факт!
А так, как вариант, идея использовать фронтенд-фреймворк принимается, хорошая идея.
Если нет желание «ручками» делать, то тот же jquery позволяет делать ajax запросы, которые работают даже в IE 6 :-)
Методы для отрисовки шаблонов на клиенте, в принципе, всегда были.
В простейшем случае достаточно будет .innerHTML = someTemplate.render(), где рендер делает пачку .replace()'ов и всё.
Хорошо, допустим, но какое это имеет отношение к моей задаче?
Погоди, давай разговаривать в контексте.
Мой комментарий был ответом на:
требовалась так же жёсткая совместимость по браузерам. На тот момент ещё использовался (не поверите) IE 7.

и рассказывал о том, что рендер на стороне клиента не коррелирует с поддержкой браузеров. Исключение — браузеры без поддержки (или с ограниченой поддержкой) JS'a, а это, например, старые кнопочные телефоны. Сомневаюсь что у вас хотя бы 1% пользователей с таких телефонов — иначе и статья о другом бы была.

Касательно задачи — выполнять значительную часть вычислений на клиенте экономно для сервера и позволяет выдерживать большую нагрузку.
В данном контексте — ok, я согласен. Действительно можно сделать нечто вроде шаблонизации на стороне клиента даже в старом браузере. Но по поставленной задаче не совсем то. У нас нет проблемы с передачей большого объёма HTML. В конце концов — gzip. Проблема вовсе не в том.

И давайте всё же на Вы, как знак уважения к собеседнику.
У нас нет проблемы с передачей большого объёма HTML.

Ещё раз: трюк не в передачи «большого объема HTML», а в экономии ресурсов (как минимум) рендера на сервере. А при грамотном подходе еще и экономия на ACL и других плюшках, что позволяет свести всю работу вашего сервера к работе с бд/кешем.
Я вас поздравляю, вы изобрели велосипед с квадратными колёсами.

При таких характеристиках «слабенького» на ваш взгляд сервера, 70к в час уников в пике(19 запросов в сек), даже со всеми поисковыми роботами(ну пусть еще 10 запросов в сек, это при грамотной построеной системе, так сказать «вообще ни о чем».

Если у вас куча статики, просто закешируйте её Nginx, если есть блоки на статике которые меняются, так подгрузите их через ajax, это прозрачно для пользователя и не напрягает ваш сервер.

Оптимизируйте индексы, проверьте через Explain все что генерирует двиг к БД и куча вызовов к memcached просто будет не нужна.

Разграничьте не авторизованных юзеров с авторизованными, например с помощью кукисов, и проверяйте в nginx, если юзер не авторизован, отдайте его голую статику, счётчики на сайте отдавайте аяксом, а значения генерируёте кроном раз в 5 минут, кому нужны точные данные которые нельзя проверить?

Если у вас Innodb, настройте buffer_pool и query_cacheесли таблицы меняются редко, то он будет не хуже мемкешеда.

Ваша CMS, я думаю, создаёт огромный оверхед, хотя вы не сказали на чём написана ваша CMS.

Как пример для 2ух xeon 8 core, 32 GB RAM, HDD. Один сервер под БД + memcached, второй под NGINX+PHP, БД общим кол-вом данных более 50ГБ, где таблицы сессий юзеров по 40 млн, все это отбивает больше 2 тысяч запросов в секунду и нагрузка держится в районе 50% обоих серверов, при среднем отзыве 0,2 сек
Я примерно за это полюбил программирование.
Хорошо зная свою область можно реализовывать наикрутейшие вещи с минимальными телодвижениями за минимальное время.
Как я понял, Вы не читали мой пост или читали не внимательно. Потому что не увидели даже входных данных, не говоря уже о технологии.

Где Вы увидели «70к уников в час» как предел возможностей?
Где увидели «кучу статики»?
Где увидели авторизацию пользователей?

Про язык — указано. Так же указано, что сервер только один, и очень слабый (вопрос денег).
Вы совершенно не учитываете вопрос ширины канала.

Так что, предлагаю не полениться и вникнуть в суть дела.
Где Вы увидели «70к уников в час» как предел возможностей?

Про предел он и не писал, между тем. А так по графику видно что примерно так и выходит.

Где увидели «кучу статики»?

сайт, основанный на пользовательском контенте — записям из блогов

Я уверен более чем графика составляет большую часть трафика. Очень странно, если не так.

Где увидели авторизацию пользователей?

По умолчанию, так сказать, считается что есть минимум 2 версии сайта — для авторизованных и для не авторизованных.
Так вот для не авторизованных, в большинстве случаев, можно закешировать вообще в усмерть, т.к. динамики (контента для конкретного пользователя) минимум.

Про язык я не понял вообще.
Про сервер — он писал что даже слабый сервер при грамотном подходе тянет всё. Причем более менее сказал что и как настроить.

Вы совершенно не учитываете вопрос ширины канала.

А что с шириной канала? Запросы контента аяксом, при грамотной реализации, трафика кушают ощутимо меньше и работают быстрее. Я тоже самое написал первым комментарием, но без пояснений.

Я уверен более чем графика составляет большую часть трафика. Очень странно, если не так.


Нет, речь идёт именно о 500 Мб текстовых данных, находящихся в БД. И именно их мы кэшируем.
Статика, разумеется, отдаётся напрямую.

По умолчанию, так сказать, считается что есть минимум 2 версии сайта — для авторизованных и для не авторизованных.


В постановке задач и нигде по тексту об этом ничего нет.

Про сервер — он писал что даже слабый сервер при грамотном подходе тянет всё. Причем более менее сказал что и как настроить.


Практика показала, что не тянет. Вы полагаете, что его оптимизацией я не занимался? Пробовали, но нет — слабое место MySQL.

Интересное вообще решение — везде использовать Ajax )) Я не понимаю, в чём принципиальное преимущество по сравнению с тем подходом, который я изложил. Он даёт отличную совместимость и универсальность. Отличный запас прочности сервера (самые востребованные материалы отдаются наиболее быстрым образом). Никакой догрузки ждать не нужно.

Мне бы хотелось услышать мнение по данной конкретной поставленной задаче, имеющимся исходным данным и результате. Возможно, в качестве интересного варианта.
Не корректно говорить о «принципиальном преимуществе» — это, скорее, ощутимое дополнение, позволяющее снять часть нагрузки с серверов.
Очень странно что 500мб MySQL из памяти медленно достаёт. На деле Memory таблицы работают со схожей мемкешу скоростью, если всё правильно настроено.

В постановке задач и нигде по тексту об этом ничего нет.

А в чем заключалась «динамика» контента тогда, расскажи подробнее, пожалуйста.
AJAX ведь снимет лишь проблему передачи большого количества трафика, верно? Но не проблему перерасхода ресурсов при обращении к БД? Число соединений — так только увеличится. Можно делать рендер на клиенте, но с этим у нас нет никаких проблем.

Над сайтом работает редакция, которая ищет по интернету «посты на тему». Компилирует их в общественно-важные темы (иногда они разрастаются до 10 и более страниц с постами). Добавляет другие материалы по теме — новости, похожие темы, отдельные тексты по теме и т.п. Если посмотреть иллюстрации, то это хорошо видно. Если не лениться и внимательно смотреть :) Например, из чего состоит шаблон страницы. И какие параметры у модулей.

По поводу работы сайта подредактирую в тексте, чтобы было понятно читателям.
AJAX ведь снимет лишь проблему передачи большого количества трафика, верно?

Нет, эту проблему, как раз, вообще не решает :-) Точнее совсем немного, но это не главная причина. Экономия CPU на генерации шаблонов, обработки всяких ситуаций и т.п., чего не требуется при подходе, когда гоняются только данные.

Но не проблему перерасхода ресурсов при обращении к БД?

Выше уже пару раз писали. БД не тянет 500мб текста? Неправильные настройки или плохо спроектировали.

Над сайтом работает редакция, которая ищет по интернету «посты на тему». Компилирует их в общественно-важные темы (иногда они разрастаются до 10 и более страниц с постами). Добавляет другие материалы по теме — новости, похожие темы, отдельные тексты по теме и т.п. Если посмотреть иллюстрации, то это хорошо видно.

Погоди, так где тут динамический контент? Я не вижу его совсем.

Если не лениться и внимательно смотреть :)

Прости, но разбираться досконально в обрывках информации что есть в посте, не имеется возможным, и особо смысла не представляет.
Да и это несколько неуважительно к собеседнику. Я твой пост прочитал, разобрался, задаю вопросы, а ответы получаю не по ним.
А во что вникать?

Хотите сказать «у нас все супер», дайте код — посмотрим.
Хотите сказать «мы выжали максимум» — дайте код — посмотрим.
Хотите сказать «БД не тянет, все закешировали» — дайте схему БД и запросы — посмотрим.

А то, что вы написали, что у нас тут «из var,modules выполняется метод getDependencies($tableName, $action, $id=0)», тут у нас «getDependencies()», а там «getParameters()», от этого, я лично вспоминаю мем с господином Жириновским и ничего более.

Сферический мемкешед php-движок в вакууме…
Не хотите — не вникайте.
Нет, исходный код я предоставить не готов.
Не хотите — не вникайте.

повторюсь
А во что вникать?
соглашусь с вами, пост ни о чем.
По сути вы описали некий самописный Full Page Cache, но как мне кажется не в лучшей реализации все-же.
Вариантом реализации может быть много и все зависит от архитектуры самой системы. Мы у себя (а событий обновления кеша у нас происходит ой как много, т.к. это магазин) используем подход, что у каждой страницы (да не только у страницы — сами блоки тоже кешируются отдельно) есть набор привязанных к ней тегов, и сброс кеша происходит именно по этим тегам.
Т.е. для примера: есть страница с некой статьей, на ней выводится еще блок с анонсами 5 статей, и еще что-то там. таким образом у данной страницы будут определены теги article_1 (сама статья), article_5, article_6, article_7, article_8, article_9 Ну а при изменении любой статьи в админке соответственно будет отработано событие для сброса кеша у всех записей, где в тегах есть article_ID. Через memcached такое не реализуешь или сложнее как минимум, а вот redis самое оно для таких задач

Ну а далее на сколько хватит фантазии — можно делать отдельные теги для полной и частичной статьи и сбрасывать только по нужному тегу, если изменения произошли только частичные (т.е. если мы поменяли только полное описание, то незачем сбрасывать кеш для страниц с анонсами). Полностраничный кеш запоминает всю страницу всегда, а динамические/приватные блоки генерирует отдельно и вставляет в уже закешированную страницу частями или через аджакс с клиента. при заходе роботов часть контента вообще не генерирует (всякие баннеры и плюшки только для клиентов)

И да — для удобства и избегания мешанины в коде все это сделано на событиях. Т.е. есть событие перед началом рендера, оно подхватывается модулем кеширования и проверяется страница в кеше. Есть событие сброса кеша или просто сохранения любой модели(таблицы в БД) и оно тоже подхватывается и по нему определяется по каким тегам почистить кеш.

В целом же вы описали некий подход, хотите получить фидбек, но при этом не показываете ни архитектуру БД ни примерный код… Думаю вам бы могли гораздо больше помочь если бы вы выложили примеры кода / структуры БД, тем более, что ничего нового вы не изобрели по сути
Спасибо за отзыв, очень интересно.

Идею с тегами учту. У Вас, конечно, другие исходные данные: частое обновление. Я сейчас думаю над тем, существует ли вообще универсальный подход. Хотелось бы довести концепцию до совершенства :) Я думаю, нужно думать в том направлении, что управление кэшем должно идти внутри nginx, в модуле lua, который либо сам компилирует страницу, либо обращается к бэк-енду.

Возможно, что я недостаточно чётко описал механизм. Честно говоря, когда описываешь, многое упускается. Это я понял по комментариям.

Исходный код открыть не могу, потому что это коммерческий проект под заказ.
Ну универсальные это varnish какой (о котором написано ниже) — многое умеет, конфигурация гибкая, но нам он не подходил по ряду причин. Честно скажу что не использовал lua и не знаю что за зверь — возможно тоже подходит для неких задач. в целом же много разных условий и специфики, поэтому правильней говорить наверно не об универсальных решениях в целом, а об универсальных подходах.
Абстрагируясь от конкретно вашей реализации, скажу, что идея с блоками и многоуровневым кэшем очень красивая, на мой взгляд.
Можно, например, закэшировать страницу целиком в varnish, вместо блоков с отличной стратегией кэширования (или с отсутствием оной) расставить <esi:include />, а дальше в зависимости от стратегии кэшировать вызываемые блоки на время, по зависимости, вставлять ajax загрузчик вместо контента или не кэшировать вовсе. В идеале, если условия кэширования совпадут для всех блоков на странице, страница будет в кэше полностью, если нет, то будет несколько быстрых подзапросов в другой кэш.
Грамотная инвалидация кэша по тегам, описанная выше, добавит прелести всей схеме.
Большое спасибо! Приятно слышать.
Да, слышал такую идею, правда, nginx+lua+memcached, чтобы не задействовать движок на PHP
Спасибо, буду думать над Varnish с тегами.
Изначально, в проектах, аггрегирующих данные в реальном времени, есть смысл использовать Redis.
Тем более что данных не так много, а оперативки достаточно. И не надо думать что вы потеряете данные
Для озвученных объемов данных Memory таблиц хватит более чем, да ещё и новые технологии вводить не придется.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории