Почему Elasticsearch нельзя сделать источником истины

Вопрос звучит почти провокационно: «у вас всё лежит в ES, зачем вам ещё Postgres». Проверяют не знание API, а понимание того, зачем вообще в системе два хранилища.

Первая причина — near-realtime, а не realtime. Документ попадает в индекс не мгновенно: есть refresh interval, по умолчанию секунда. Записал — тут же прочитал тем же запросом — иногда не найдёшь. Для источника истины это неприемлемо: банковская транзакция не может «подождать секунду, чтобы стать видимой».

Вторая причина — транзакционная модель. В ES нет ACID-транзакций в привычном смысле. Bulk-запрос может частично выполниться: часть документов проиндексируется, часть упадёт по ошибке маппинга, и откатить это одной операцией нельзя. В реляционной БД это ROLLBACK, здесь — ручная разборка по кускам.

Третья причина — durability слабее, чем у БД. Данные пишутся в translog, но по умолчанию fsync происходит не на каждую операцию, а раз в 5 секунд либо по запросу. Между fsync возможна потеря последних операций при падении ноды до репликации.

Четвёртая, менее очевидная — эволюция схемы. Поменял тип поля в маппинге — ES не умеет мигрировать существующие документы. Нужна полная переиндексация в новый индекс с alias-свитчем. Для источника истины, где схема меняется регулярно, это дорогая операция на каждый релиз.

Следующий вопрос обычно: «а как тогда держать ES и БД согласованными?». Ответ в двух словах — БД пишет события, отдельный процесс (CDC через Debezium или outbox) двигает их в ES асинхронно. Нужно сразу проговорить, что консистентность между ними eventual, и окно рассинхронизации нужно явно оценить, а не замалчивать.

ES — витрина для поиска и агрегаций, а не хранилище, которому доверяют единственную копию данных.

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки