СУБД Cache + Erlang

в 11:25, , рубрики: cache, erlang, Erlang/OTP, nosql, Веб-разработка, СУБД, метки: , ,

В этой статье я расскажу о том, как мы подружили Cache + Erlang, и зачем нам это нужно. СУБД Cache была выбрана в качестве хранилища данных. Также мы создали и эксплуатируем MCA(Middleware for Cache Applications) — промежуточное программное обеспечение, обеспечивающее конкурентную модель взаимодействия Erlang и Cache.

Для взаимодействия Erlang и Intersystems Cache реализованы возможности:

  • Обрабатывать в Cache сообщения из Erlang, транслируя Erlang tuples (внутренний древовидный формат данных Erlang) в глобалы Cache.
  • Посылать из Cache сообщения процессам Erlang, транслируя глобалы Cache в Erlang tuples.

Разработанное MCA состоит из трёх основных компонент:

  • Message Dispatcher(MD) — управляет обменом сообщениями в конкурентных условиях между различными Erlang-node(EN) и Cache-процессами, обеспечивает кэширование сообщений по определенным правилам. Запускается в соответствующем EN.
  • C-node — обеспечивает подгрузку С/C++ библиотек и обмен сообщениями между ними, взаимодействие системы с shared-memory, EN, CallIn/CallOut (функциональностью, реализованной в Cache на языке С) и т.д. На данный момент к С-node, для веб-приложений, c использованием Cache, нами подключены библиотеки для поддержки XSLT преобразования, обработки регулярных выражений.
  • Porte – шлюз обмена сообщениями (Messaging Gateway) c MD для Cache. Запускается как отдельный background job, который будем называть Porte-job(PJ).

MD

В MD поступают запросы из веб-сервера yaws (напомню: yaws, также, написан на Erlang). MD проверяет нет ли такого запроса в очереди, обрабатывающейся в данный момент, или в кеше ответов. Если везде пусто — запрос добавляется в очередь. Когда будет готов ответ — MD вернёт его всем, кто за это время его запросил. Настройки MD позволяют на этом уровне хранить кеш ответов, мемкеш используется на более верхних уровнях. Справедливости ради — скажу что мы не используем кеширование на уровне MD — но такая возможность есть. Количество одновременно обрабатываемых запросов MD — равно количеству запросов поступивших от веб-сервера yaws — то есть величина случайная.

C-Node

C-Node обеспечивает ожидание сообщений от EN, передачу запросов к подключенным библиотекам и к Cache, отправку назад результата запроса. На каждый запущенный C-Node — существует один запущенный PJ (процесс в каше обрабатывающий запрос). В PJ данные запроса заносятся в уникальный узел глобала (средствами CallIn). При этом параметры запроса в виде Erlang-туплов преобразуются в ветви глобала. Сразу после завершения записи в глобал начинается обработка запроса. По сути, благодаря наличию C-Node, каждый PJ, по отношению к Erlang выглядит, как набор обычных EN (Erlang-node). Тажке с помощью C-node, в частности, происходит вызов XSLT преобразования для XML-файла, сгенерированного в Сache. После выполнения XSLT, получается готовый HTML, который и возвращается обратно в MD — и далее веб серверу.

Porte

Porte — это процесс, запущенный непосредственно в Cache. Обработка запроса происходит по типу упрощённой логической машины вывода. Есть глобал запроса и глобал правил — на основании глобала запроса выбираются те или иные правила — выполняются те или иные действия в Cache. Также на этом уровне происходит определение набора преобразований, которые необходимо выполнить после обработки внутри Cache (как правило это выбор того или иного XSLT-преобразования).

Зачем нам это нужно

Промежуточное программное обеспечение используется для общения Cache с запросами из внешнего мира. С помощью него система может справляться с большими нагрузками при условиях ограниченных вычислительных ресурсов или недостатка количества PJ. Также появляется удобная возможность использовать для разработки интерфейсов не только встроенные в Cache средства csp/zen — но и все остальные способы реализации интерфейсов (в нашем случае это цепочка xml-xslt-html). Erlang выбран потому, что внутренний формат данных в нём, как и в Cache — древовидный, обмен деревьями не требует серьёзных промежуточных преобразований. Yaws выбран также из-за того что он написан на Erlang — таким образом достигается высокая степень однородности всей системы в целом.

Само хранилище данных, реализовано, в Cache, на принципе глобалов правил. То есть, даже внутренние процессы, которые не взаимодействуют с внешним миром напрямую, получают на входе глобал данных («фактов») и на основании глобала правил выбирают набор необходимых действий и преобразований.

P.S.: Некоторые части статьи были скопированы из наших внутренних документов, ссылки на которые я привести не могу. Непосредственного участия в разработке промежуточного ПО я не принимал, однако постараюсь ответить на все возникшие вопросы, в случае чего обращусь за советом к старшим товарищам. Я принимал участие в проектировании и реализации хранилища данных, то есть всего того что происходит после того, как данные попали в Porte, и до того как ответ будет возвращён EN. Если интересно — могу подробно описать как реализовано хранилище, какие подсистемы в нём используются (словари, индексирование, вывод) и прочее прочее прочее.

Автор: multik

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js