KamoCRM

Уровень распределенных данных, выбранный специально

Распределенный SQL, широкий столбец, кэш, объектное хранилище и векторы — каждый по своей причине

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

Каждое число здесь называет, откуда оно пришло и когда оно было измерено.
МераСтоимостьИсточникИзмеряемые
Отдельные хранилища данных в производственной среде5 (YugabyteDB, ScyllaDB, Redis/Valkey, MinIO, Qdrant)kubectl get statefulsets,deployments --all-namespaces
Распределённая топология SQLyb-master and yb-tserver as separate stateful setskubectl get statefulsets -n kamo
Файлы миграции SQL под управлением версиями90find . -name '*.sql' across all service repositories
Завершение перехода на рабочий модуль базы данных1 (CockroachDB to YugabyteDB, live data)service configuration history; port 26257 retired in favour of 5433

Чему здание нас научило

По умолчанию ответ на вопрос, куда идут данные, зависит от того, какой проект использовался в последний раз. Таким образом, бизнес в конечном итоге запускает аналитические агрегации с базой данных, принимающей заказы клиентов, или хранит тридцать гигабайт загруженных файлов в строках таблиц. Мы выбрали каждый магазин с учетом рабочей нагрузки, и мы переместили его, когда мы ошиблись — платформа ранее работала на другом распределенном SQL-движке и переместилась с него, что действительно сложно делать с производственными данными и стоит больше, чем любое количество обсуждений архитектуры.

Распределенный SQL не является заменой для одноузловой базы данных, и его отличия являются существенными. Транзакция видит один момент на протяжении всего своего жизненного цикла даже в режиме закрепления чтения, так что второе чтение строки внутри одной транзакции не наблюдает за записью другой транзакции, закрепленной между ними — код, который был правильным на одном узле, здесь неправилен. Конфликты чтения и записи появляются как повторяемые ошибки в транзакциях, которые никогда ничего не записывали. Это не экзотические крайние случаи; они являются вторничными, и именно поэтому мы осторожны с тем, что обещаем в работе с данными.

Объектное хранилище переносит каждый загруженный файл, с дедупликацией по содержимому, и это имеет свой урок: неудачная загрузка может оставить строку, которую позднее повторная попытка дедупликации может использовать, создавая файл, который система считает существующим и не может обслуживать. Мы обнаружили это в производственной среде. Теперь мы проверяем это в любой системе, которую мы создаем, которая дедупликирует что-либо.

Построен с

  • YugabyteDB
  • ScyllaDB
  • Redis
  • Valkey
  • MinIO
  • Qdrant
  • PostgreSQL wire protocol
  • Hibernate

Для чего это нас квалифицирует

Data engineering and migrationMoving data between systems without losing any of itCustom web applicationsThe system your business actually runs on, built properlyPlatform and DevOps engineeringKubernetes, pipelines and the deployment safety nobody notices until it is missing

Расскажите нам, что вы пытаетесь сделать

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

Начать разговорЯ уже использую KamoCRMКак мы цитируем