Обновить

Один primary в поле среди 800 миллионов пользователей — надо ли так делать?

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели6.3K
Всего голосов 3: ↑2 и ↓1+2
Комментарии14

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

В целом я с вами согласен, когда ты точно знаешь что строишь геораспределённую систему на несколько континентов, думать о том какие будешь использовать инструменты и подходы конечно же нужно. Посыл был в том, что многие не достигают даже части этой нагрузки, но уже спешат все переоптимизировать, не думая о том, что у всего есть цена. Та же Casandra которую вы упомянули, имеет ряд ограничений по работе с запросами, а в условиях какого-то стартапа просто может не быть возможностей заранее точно понять какие запросы будут нужны (с Сassаndra сам наткнулся в практике на такие проблемы, хотя как к инструменту у меня к ней нет никаких претензий).

Я полностью поддерживаю идею использовать Postgress в большинстве "начальных" случаев -- при условии наличия в команде соответствующих компетенций, конечно.

В основном полемика идёт вокруг тезиса "PostgreSQL могут ещё дать фору новомодным решениям".

Вот смотрите, Вы пишете: "когда ты точно знаешь что строишь геораспределённую систему на несколько континентов". Почему же сразу гео и на несколько континентов? А уметь переживать падение датацентра внутри континента - разве не является задачей, достойной рассмотрения?

Cassandra/Scylla решают это задачу так... Ну как решают - это у них в DNA прописано. RF=3, NetworkTopologyStrategy и т.д. Т.е. всё работает прямо "из коробки", не требуя особых усилий по конфигурации и доработке ПО.

Вот такой аспект, конечно, посложнее будет - "точно понять какие запросы будут нужны". С Cassandra надо работать в парадигме ключ-значение, CQL лишь способ придать некоторую структуру ключам и значениям, не более. Запрос на чтение - всегда по ключу или по подключу. Все сложные соединения и агрегации - через заранее подготовленные материализованные VIEW. У нас вот этот продукт сделан по такой технологии.

В основном всё круто работает. Основная проблема - получить развёрнутую статистику по всем клиентам. Тут пока думаем использовать ClickHouse. Ну т.е. Scylla/Cassandra - это OLTP профиль нагрузки, ClickHouse - OLAP. Это, к тому же, разные типы хранения - строковые и колоночные.

Пережить падение ДЦ, это очень важная задача, но это целый план DR. Так как не ограничивается только работой с БД. Именно для этих целей любое облако, например, просит работать минимум с двумя зонами доступности. И PostgreSQL вполне спокойно работает в таких условиях. Что удобнее и проще, вопрос философский, мой ответ - там где есть достаточные в команде компетенции. У каждого инструмента свои сильные и слабые стороны.

Денормализация данных и поддержка работоспособности в условиях активной разработки и последующего версионирования схем БД для Cassandra, отнюдь не самая тривиальная задача. Фактически нужно подстроить разработку под БД, тоже не все готовы на это пойти.

Плюс большие требования для железа, это будет 1,5-2 раза (субъективно) будет занимать больше места на то же количество информации в сравнении с реляционками. Главный же момент, который отталкивает именно бизнес, это сама парадигма: жертвуя консистентностью в пользу доступности (до этого понимания нужно дорасти).

И PostgreSQL вполне спокойно работает в таких условиях

Можно подробнее, как он работает? Вот есть три bare metal сервера в трёх ДЦ, что нужно сделать, чтобы обеспечить strict consistency и fault tolerance к выпадению одного ДЦ? Для cassandra/scylla это решается штатно незамысловатым конфигом.

Достаточно просто также добавить дискового пространства и вычислительных мощностей в систему путем добавления узлов - это тоже штатные процедуры. Как с этим у PostgreSQL?

Плюс большие требования для железа, это будет 1,5-2 раза (субъективно) будет занимать больше места на то же количество информации в сравнении с реляционками.

Ну тут таки да, три копии данных вместо двух (у Postgres) в стандартной HA-конфигурации.

Главный же момент, который отталкивает именно бизнес, это сама парадигма: жертвуя консистентностью в пользу доступности (до этого понимания нужно дорасти).

По опыту, бизнесу вообще это не очень важно или легко объясняется. Тут скорее вопрос в технарях, и как раз та самая "переоптимизация".

1) Если мы говорим про ванильный PostgreSQL, то действительно шатные средства отсутствуют. Но это не означает что задача не решаема в принципе, популярный стек: Patroni + Consul (ZooKeeper или etcd), для получения автоматического failover. Или использовать Citus который превратит БД в распределённую систему. Но смысл и сила PostgreSQL, как раз в реляционной модели и ACID. Вокруг PG сложилась обширная экосистема, которая решает сопутствующие проблемы.

2.1) Про размер: дело не только (и не столько) в количестве копий БД, а в самой структуре хранения данных и индексов.

Например:

Для быстрого запроса "получить все заказы пользователя" создаём таблицу orders_by_user_id, где ключ партиции будет поле user_id, а в строке будут хранится все данные заказов.

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

2.2) Кроме того PostgreSQL имеет продвинутые механизмы сжатия на уровне страниц для больших полей или NULL-значений. Cassandra же традиционно менее эффективна в сжатии отдельных строк и сжимает данные на уровне дисковой системы. Что не настолько эффективно, как комбинация сжатия страниц и отсутствие дублирования данных.

2.3) В силу специфики самого механизма работы, Cassandra хранит не только само значение, но и дополнительные метаданные: маркеры времени для разрешения конфликтов, TTL или например информацию о кластере внутри партиции.

2.4) Ну и механизм сборки мусора тоже не очень сильно эффективен по сравнению с PG.

То есть по этим пунктам Cassandra очень сильно проигрывает PostgreSQL. Но оно и не удивительно, как я выше написал, это плата за инструмент.


3) Про то что бизнесу всё равно: ему всё равно, пока не приходят счета))

Но это не означает что задача не решаема в принципе, популярный стек: Patroni + Consul (ZooKeeper или etcd), для получения автоматического failover.

Дык в принципе оно конечно решается, кто ж спорит. Но по рассматриваемому факту у OpenAI не решилось - они это дело аутсорсят вместо того, чтобы взять bare metal и сэкономить денег.

Но смысл и сила PostgreSQL, как раз в реляционной модели и ACID.

Это в каком-то смысле верно.

Но если целиться в распределённую систему, то сила реляционной модели превращается в её слабость. Для high-load OLTP нагрузки лучше подходят key-value базы, ибо для скорости требуется точечное чтение - запись. Для OLAP нужна колоночная база, там и скорость, и сжатие огромное.

Про то что бизнесу всё равно: ему всё равно, пока не приходят счета))

Так как раз счета придут больше, если обеспечивать strict consistency там, где этого не требуется. Именно через этот аргумент бизнес и убеждается легко в том, что давайте лучше eventual consistency, где можно - дешевле выйдет.

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

При заявленных нефункциональных требованиях и доступных ресурсах естественным выбором сегодня была бы распределённая NoSQL-СУБД вроде CosmosDB

был пример стартапа, который выбрал DynamoDB. При всей квалификации специалистов этого стартапа использование нереляционной базы привело к 15-часовому простою https://habr.com/ru/amp/publications/960394/

Как пример - интересно, как контраргумент - не очень убеждает.

Тут недавно Cloudflare лихорадило, при всей квалификации разрабов и надёжности языка Rust...

PS. А ничего, что система с бэком, который работает на PostgreSQL, мне показывала куски чатов от других пользователей?

Тут тоже прокомментирую про куски чатов: Контекст вашей проблемы не знаю. Но скорее всего это была проблема не БД, а генеративного ИИ и promt injection. Последнее время я такого не встречал (после 3.5 версии), но на тот момент у меня было исследование на эту тему, когда я добивался того, что бы мне куски других чатов становились доступны. Допускаю что такая ситуация могла воспроизвестись и у вас. Но обыкновенный баг с бекенда тоже никто не отменял. Нарушение же принципов ACID, только потому что это реляционная БД, это нууу... что-то феноменально маловероятное.

Но скорее всего это была проблема не БД, а генеративного ИИ и promt injection.

Интересно. Поясните, как это могло произойти? Я, причём, спрашиваю на русском или английском, а вижу фрагменты ответов на испанском (я в тот период был в Испании, если что).

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

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

На практике, баг мог быть и потому что, многие запросы пользователей объединялись в один так называемый "пакет", что бы разом его обработать на GPU. Если в логике обработки ответов вдруг возникла бы какая-то ошибка, то ответы от одного пользователя могли перепутаться с другим.

Тут недавно Cloudflare лихорадило, при всей квалификации разрабов и надёжности языка Rust...

Там тоже нереляционная база. По ссылке пишут «Объяснение заключалось в том, что файл генерировался каждые пять минут запросом, выполняемым в кластере баз данных ClickHouse, который постепенно обновлялся для улучшения управления разрешениями.» В более раннем варианте было «Настоящим виновником было обновление прав доступа к базе данных ClickHouse. Это небольшое изменение привело к неожиданному удвоению размера файла функции управления ботами.», что процитировали в https://habr.com/ru/news/967836/

А ничего, что система с бэком, который работает на PostgreSQL, мне показывала куски чатов от других пользователей?

PostgreSQL в таком не был замечен. Не думаю, что чат сохранялся в базу PostgreSQL из статьи, так как обьем чатов огромный, а у них еще и 50 реплик - в 50 раз больший объем бы был.

Вероятно, кусок чужого чата брался из структуры в памяти на сервере приложений. На чем у них сервер приложений не знаю, возможно питон. По аналогии из java что-нибудь типа артефактов при использовании несинхронизированных non-thread-safe коллекций.

Настоящим виновником было обновление прав доступа к базе данных ClickHouse

Намекаете, что если изменить права доступа к БД PostgreSQL то это никак не повлияет на результат запроса?

В статье же пишут: a single Rust .unwrap() in Cloudflare's edge network.

PostgreSQL в таком не был замечен.

Безусловно. В этом замечена монструозность архитектур - чем архитектура монструознее, тем больше вероятность прокола.

не намекаю. Какие-то технологии сподвигают ошибаться, какие-то наоборот затрудняют использование возможностей, которые приводят к ошибкам. В Cickhouse поменяли права и создались таблицы в схеме default, вместо r0. Запрос к системной таблице с order by, но без distinct.

OpenAI в PostgreSQL: «Изменения схемы ограничены существующими таблицами». В реляционных базах в эксплуатации не принято просто так выполнять DDL. Страсть к изменениям реализуют переписыванием selectов. С clickhouse selectам, наверное, уделяют меньше внимания и теряют навыки (distinct или where).

Согласен, что чем монструознее, тем больше вероятность ошибки. Основное - сложность в использовании плюс сподвигание к ошибкам или затруднения в использовании опасных возможностей. Переход на распределенные системы - резкий скачок сложности.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации