У меня есть несколько клиентских веб-приложений электронной коммерции, работающих на одной виртуальной машине, каждое веб-приложение представляет собой приложение node.js express.
Веб-приложение Express взаимодействует с бэкэндом через API для извлечения контента для страниц, списка продуктов и т. д. Однако для ускорения поиска продуктов в настоящее время мы используем базу данных в памяти (lokijs) для всех поисковых запросов, на данный момент это работает для нас довольно хорошо, поскольку средний каталог продукции для каждого клиента составляет всего около 80 наименований, у нас есть простой cron, работающий в веб-приложении каждого клиента для обновления базы данных в памяти с последним списком продуктов через вызов API.
Некоторые из недостатков этого подхода заключаются в том, что поскольку мы используем PM2 для запуска каждого приложения в кластере из 2 узлов, базу данных в памяти приходится дублировать, поскольку невозможно совместно использовать память между узлами. Чтобы гарантировать синхронизацию баз данных в памяти, мы используем IPC для передачи сообщений всем процессам в кластере.
Поскольку мы привлекаем более крупных клиентов с более крупными каталогами продукции, мы не хотим хранить дублирующиеся базы данных в памяти для каждого дочернего процесса.
Наше предложение работает следующим образом: хотя каталоги продукции невелики для каждого клиента, объем поиска довольно велик, поэтому клиент с 80 товарами все равно может получить тысячи поисковых запросов в день.
У меня на примете было несколько вариантов, но я не был уверен, какой из них будет лучшим:
Вариант 1 — Единый глобальный кластер Elasticsearch
Я обсуждал и думал об использовании Elasticsearch, а затем связывал каждое клиентское веб-приложение с одним глобальным кластером Elasticsearch для выполнения поиска товаров. Таким образом, мы сможем использовать события для поддержания базы данных Elasticsearch в актуальном состоянии в режиме реального времени.
Однако я не знаю, как это будет работать при масштабировании. Я не хочу, чтобы Elasticsearch стал узким местом.
Вариант 2 — Локальная база данных nosql
Второй вариант заключался в том, чтобы просто заменить использование lokijs в качестве базы данных в памяти и иметь общую базу данных nosql (например, mongo) для каждой виртуальной машины, все веб-приложения затем используют локальную базу данных для запросов, каждое веб-приложение по-прежнему отвечает за обновление каталога продуктов для своего собственного магазина. Затем, по мере добавления дополнительных виртуальных машин, каждая виртуальная машина будет иметь свою собственную локальную базу данных для любых приложений, работающих на ней, для использования
Мы активно используем фасетный поиск и агрегации по фасетам для получения подсчетов по фасетам.