ermouth: (ang)

В бете нового Двиналэнда применено довольно много технологических решений, снижающих нагрузку на облака. Одна из стратегий, которая попутно даёт мгновенный отклик некоторых интерфейсов – обработка, рендер и поиск на клиенте.

Называется это у нас “словари” и работает это примерно так.

Источники данных

Существует крупная категория данных, которые обновляются в подборках не по частям (как, например, новости), а разом. Это, скажем, ежемесячные отчёты об исполнении бюджета, какие-то списки организаций или услуг, телефонные справочники.

В силу характера документооборота это практически всегда или экселевские файлы (иногда с имитацией иерархии), или SQL-выгрузки, или веб-сервисы. Так или иначе, это всегда таблицы. Чаще – эксель.

Типичные объёмы – от сотен до единиц тысяч строк в 5-15 колонок. Связность обеспечивается в момент приёма до уровня гиперссылочной целостности – куда надо подставляются пермалинки.

Хранение

Такие данные неразумно хранить в “разобранном” виде – проще их в момент поступления в систему конвертировать в жестко унифицированный формат и хранить единой записью. В силу того, что у нас вся система – javascript, эта запись, понятно дело, json. Вопрос, какой структуры.

Коль скоро мы собираемся искать на клиенте, нам эти данные надо туда передать. Также очевидно, что перед поиском их можно будет обработать. Стало быть, надо делать представление с минимальной избыточностью, хорошо пакуемое gzip-пером уровня выдачи на скоростных режимах (ритмичное, то-есть).

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

То-есть не [{name:"John", year:1980}, {name:"Ann", year:1990}],
а примерно {cols:["name","year"], data:[["John",1980],["Ann",1990]]}

Передача

Только в силу структуры экономия против по-объектного, и, тем более, против HTML-формата, получается многократная.

Раз оно получается короткое (100Кб словарь пакуется до 10-15Кб), хранится единым куском и не требует сборки, его можно и нужно инлайнить. И мы действительно до определённого порога инлайним эти данные прямо в страницы выдачи.

То-есть, когда страница догрузилась, данные не просто тоже загружены, они уже даже разобраны и проиндексированы. В силу того, что большинство даже мобильных систем нынче двухпроцессорные, рендер и индексирование разносятся браузером по разным потокам и для пользователя это незаметно.

Рендер

Рендерятся данные после рендера всей содержательной статики. За выдачу данных с вкусным интерактивом отвечают jquerymy-манифесты.

Причём к одним и тем же данным могут быть привязаны разные манифесты, а к одному манифесту – разные данные. Например, в материале о расходах бюджета http://new.dvinaland.ru/budget/-e0ut55ow вверху бюджет диаграммой, а внизу – таблицей. Это одни и те же данные. Сама страница весит 450Кб, и эти данные занимают большую часть её объёма. При передаче это всё сжимается до 65Кб, размер небольшой картинки.

Там чуть менее 3000 строк данных в 5 уровнях иерархии.

Гибкость

С точки зрения редактора это выглядит как “поставить в этом вот место виджет Таблица с поиском и привязать к ней вот эти данные”. Это всё в админке интерактивное, драг-н-дроп, можно выбрать оформление, ширины колонок, фильтры и тп.

В силу того, что чётко разделены и стандартизированы попадание в систему, хранение, выдача и обработка, любое звено можно менять, не трогая остальные. Также любое звено легко форкается в целях тестирования.

С точки зрения юзера это выглядит как мгновенный отклик итерфейсов – все данные уже на клиенте и проиндексированы. Скажем, если на странице http://new.dvinaland.ru/gov внизу в справочнике наколотить gmail, можно увидеть, сколько ещё деятелей юзают вражью почту ггг.

За последние полгода эта цифра уменьшилась кратно, но остались ещё несознательные.

ermouth: (ang)

Открыли публичную бета-версию обновлённого портала областного правительства, в продолжение их пресс-центра (ровно год прошёл, да). Сначала скриншотики, кликабельны

2
1

Теперь чем оно всё круто.

0. Скорость

Вся система целиком, до последней строчки – javascript, и при этом практически любая страница после первого захода видна менее чем через секунду после клика (в России, в 120мс пинга до хостинга). Всё потому, что как и на пресс-центре применено блочное кэширование и в 99% случаев страницы отдаются целиком из кэша в RAM, даже без обращения к БД.

1. Облачная распределённая платформа

Оно плотно интегрировано с пресс-центром, это не просто одна CMS и стилистика, это единая платформа в облаках. Из соображений усиления периметра безопасности платформа состоит из нескольких компонентов, связанных только по https – скажем, головной сайт не хранит и не обрабатывает данные форм и авторизации, это делает специальный ресурс. Также на фронтэнде невозможно авторизоваться в админку – её там просто нет.

2. Импорт данных

Эта платформа импортирует данные из других систем – телефонные справочники приходят в SQL-формате, ежемесячные обновления бюджета – в CSV, афиши – в JSON и т.д. После импорта данные приводятся в унифицированный внутренний формат, а потом отображаются в виде табличек, диаграмм, списков ссылок и т.д.

Особенно полезны для вдумчивого читателя интерактивные диаграммы бюджета. На секторы можно кликать. Смею предположить, что такое представление бюджета для народа – лучшее по простоте навигации из всех, что я видел. Оно основано на одной заброшенной австралийской инициативе 5-летней давности по раскрытию open data. Мы из этого сделали технологию, в которой данные обновляются в один клик.

3. Контроль устаревания

Все материалы имеют “срок годности” – дату, после которой система начнёт напоминать о необходимости обновления. Такой фичи я просто вообще нигде в CMS не встречал, а для большого госпортала она абсолютно необходима. На предыдущей версии портала нереальные завалы неактуального старья – и про то, что информация протухла редактор портала мог узнать только случайно.

Мы сделали механику для исключения такого рода бардака.

4. Обращения и вообще формы

Когда мы это всё начинали, планировалась авторизация через соцсети. Эта идея быстро отвалилась, потому что в принципе не позволяла сделать хоть сколь-нибудь квалифицированное обращение к власти, а мне хотелось, чтобы эта форма на каждой вообще странице была.

Использовать СНиЛС как на госуслугах – не вариант, это другой класс защиты персональных данных, мы бы не поместились в сроки и бюджет. Да и неудобный он до смерти, “интернет по паспорту”.

Остался мобильник. Вообще нам стоило существенных усилий убедить коллег из правительства, что это приемлемая авторизация. И примерно в тот момент, что мы всё же убедили, что это концептуально верно, Медведев предложил простые госуслуги оказывать через авторизацию по SMS. К июлю. Ну вот мы и сделали к июлю под это целую платформу.

---

Вообще, работа проделана колоссальная – переработано почти 400 страниц информационного контента, урегулированы вопросы поставки обновлений из ведомств, масса данных уточнено. Ну и портал правительства, наконец то, для простого человека стал не бесполезен.

Началось всё вот с такой картинки:

image

Ну и да,  вся эта система управляется приложениями jquerymy. Внутри системы даже IDE есть простенький для горячей замены кода системы из браузера прямо, тоже на $.my.

Такие дела.

ermouth: (Default)

Движок двинаньюса написан на не самом быстром языке и работает на не самой быстрой БД – тем не менее показывает прекрасную производительность. Это при том что каждая страница содержит динамические подборки, выбираемые по тегам и “радиусу” на оси времени.

Производительность достигается за счёт того, что страницы двинаньюса собраны из блоков и кэшируются не страницы целиком, а отдельные блоки. То-есть подавляющее большинство страниц при сборке даже если и требуют обращения к БД, то буквально единственного. Остальные блоки берутся из кэша.

Кэш – в оперативной памяти, полностью синхронный. Используется просто очень большой javascript-объект, hash table. Главные ключи формируются из параметра вызова шаблонизатора блока.

Получается, что каждый экземпляр приложения (при многопоточной реализации) имеет свой полный экземпляр кэша. Это неэкономно, на первый взгляд, с точки зрения использования RAM. Тем не менее, при моих прикидках у меня получалось, что мне никогда не нужно будет больше гигабайта памяти на ядро процессора – и Амазон EC2 прекрасно подошел.

Главная фича – как блоки инвалидировать, как кэшу узнать, что блок пора пересчитать при следующем запросе.

Для этого помимо главной хэш-таблицы сформированы ещё несколько индексов из указателей. Они содержат группировки блоков по разным признакам, в частности по тегам и по временнЫм диапазонам. Помещение блока в кэш автоматически помещает его во все связанные таблицы. Как только наступает соответствующий признак, инвалидируется вся таблица.

В какие именно таблицы указателей помещать, решает конкретный шаблонизатор – на основании параметров, с которыми он был вызван. Например, если мы запросили вывод списка заголовков по теме Культура, только с картинками – результат будет положен и в таблицу тега “Культура”, и в таблицу признака “С картинками”, и в таблицу блоков, отрендерённых шаблонизатором “Список заголовков”. Это называется “полностью ассоциативный кэш”.

Теперь надо узнать, когда эти таблицы инвалидировать.

CouchDB имеет интерфейс, уведомляющий подключеного клиента о появлении или обновлении документа в той или иной БД. По такому уведомлению новый док загружается и кэшируется в RAM, а все блоки, на которые он мог бы повлиять, отмечаются как устаревшие. Это очень быстрая операция, потому что итератор просто обходит все объекты по нужным хэш-таблицам и сбрасывает признак готовности.

Физически объекты из памяти не удаляются – потому что они скорее всего будут вскоре заново сгенерированы и поверх переписаны, это раз. И потому, что удаление, скажем, 50К объектов (например, мы обновили какой-то часто используемый шаблонизатор) вызовет stall на время сборки мусора.

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

В однопроцессорной системе можно удалять по ttl, причём это вполне можно делать асинхронно. Но так как у нас система многопоточная (несколько одинаковых экземпляров js-процесса, по которым раскидываются запросы), гораздо проще по минимуму нагрузки эти потоки по очереди рестартовать – так и сделано.

С помощью этой же механики происходит рестарт потока при падении – оно очень живучее.

Со старта обслужено примерно 1.5М запросов к серверу, даже не чихнуло ничего.

Profile

ermouth: (Default)
ermouth

November 2021

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
282930    

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 10th, 2025 06:29 pm
Powered by Dreamwidth Studios