Привет! Меня зовут Пётр, я менеджер по отказоустойчивости в QIWI. В этом посте мы поговорим про выбор новых классов продуктов. Как-то раз мы с одним разработчиком из другой компании стали обсуждать, почему бы не выбрать для работы какую-то распределенную СУБД, поддерживающую SQL? Из этой дискуссии родился мой доклад для нашей QIWI Server Party. Представляю вам его текстовую версию.
В эпоху, предшествующую всеобщему проникновению интернета, большие базы данных могли преспокойно жить себе на одном большом сервере, вообще без проблем. Но когда появился интернет, мощностей стало немножко не хватать, и как следствие – понадобились новые подходы для хранения данных. Так появились распределенные базы данных, живущие сразу на многих серверах. Подход хороший, но есть довольно весомый минус: консистентность в базе данных становилась дорогой, был необходим двухфазный коммит, который с практической точки зрения слишком медленный.
Как альтернатива, появилось NoSQL-движение с key/value БД, спасибо ребятам из Google. Они тогда подумали, что заодно неплохо было бы избавиться не только от строгой консистентности, но и от схемы данных — пускай вообще не будет никакой схемы данных, а приложение просто само будет знать, как правильно записывать данные в БД. Будет много узлов, у которых не будет какого-то вменяемого API, кроме того, что зашито в самом приложении (вида “ключ-значение”), и СУБД сможет легко обслуживать миллионы простых запросов.
Как показало время, такой подход помог сделать большие сайты в интернете очень быстрыми. И в целом всё было здорово, но оставалась одна проблема — консистентность всё ещё оставалась очень важным фактором, который нельзя было списывать со счетов.
NewSQL
В середине 2010-х появился новый класс алгоритмов, позволяющих ускорить консистентную запись сразу на несколько узлов. Вмест с ним свет увидел и новый класс продуктов, который сейчас принято называть NewSQL — с одной стороны, они распределенные, с другой — консистентные, поддерживают классические API в виде языка SQL.
В Google придумали базу под название Spanner — она живет у них в облаке, но при этом она строго консистентная, распределенная и поддерживает стандартные интерфейсы. Значимость консистентности было сложно переоценить: спустя 10 лет после создания NoSQL в Google решили, что раз консистентность это критичный аспект, на поддержание которого тратится много времени и денег, то пусть уж лучше в СУБД будут строгие транзакции — разработчики будут в состоянии с ними разобраться. И это будет дешевле, чем если они будут постоянно заниматься синхронизацией данных на стороне приложения.
Такая архитектура тоже требовала платы, на этот раз — серьезными инвестициями в сеть и в диски. За это небольшое время появилось довольно много NewSQL-продуктов.
И то — на картинке не всё, их на самом деле больше. Но мы в этом посте прежде всего пройдёмся по критериям выбора, а там уже — кому что больше подойдет в зависимости от вашего продукта. Так что давайте сравнивать.
Критерии выбора
Мне в своё время сильно помогла система с весом голоса, я так школу выбирал. Можно оценивать и работодателей.
Для других важных выборов она тоже годится, тут самое главное — на старте быть максимально честным, не жульничать и не подгонять веса критериев для оправдания того или иного выбора. Так что в идеале сначала чётко расписать веса и определить главное для вас, а уже потом ставить оценки продукту.
Вот на этой таблице я привел так все, что я смог придумать для того, чтобы оценить, как выбрать новый класс продуктов. Давайте теперь поподробнее про сами критерии.
Функциональность
Все мы знаем, что база данных хранит данные. Мы пишем в базу и читаем из нее. Если мы хотим написать новый сервис, использующий СУБД, с нуля, эти критерии могут быть не такими важными. Но если мы хотим смигрировать сервис на какую-то другую базу данных в силу внешних причин (например, импортозамещение), то эти вопросы становятся достаточно актуальными, поскольку диалектов языка SQL очень много. Конечно, было бы очень здорово, если бы были какие-то общие и совместимые подходы, они бы нам сильно сократили время миграции.
CockroachDB и TiDB я выбрал чисто как пример для сравнения.
Вот одна база использует совместимость с Postgres, а другая с MySQL. Если у вас уже команда привыкла писать на одном синтаксисе, то совместимость с ним даст вам хороший рывок вперед при миграции на новую СУБД.
Иногда получается, что продукты позиционируют себя так, что у нас, кроме транзакционного, есть еще такой кусочек сбоку, аналитический. Если вы не хотите посылать весь ваш транзакционный поток, например, в Hadoop через Kafka, то вот у СУБД есть такой рядышком кусочек, и вы можете быстро в нем некие аналитические запросы обрабатывать. Это называется гибридным транзакционным аналитическим процессингом. И иногда иногда вам тоже может такое пригодиться, если оно есть.
Уровни изоляции и блокировки влияют на обработку ошибок. Как правило, переезжать с одного способа, с одного метода уровня изоляции транзакций на другой бывает не то, что дорого, — это прежде всего неудобно, потому что у вас появляется новый класс ошибок, который надо заново обрабатывать в приложении. От этого будет зависеть и общая скорость миграции с одной СУБД на другую.
Сейчас уже все СУБД поддерживают изменение схемы данных в онлайне, но раньше было не так
Одна из фич распределенных баз — это живучесть. Де-факто это признак, отвечающий на вопрос «Сколько у нас может узлов упасть, прежде чем система совсем выйдет из строя?». Так называемый replication factor, который вы могли встречать и в Kafka.
Производительность
Есть несколько тестов — есть стандартный TPC-С, который имитирует условный интернет-магазин. Есть тест, который называется Yahoo Cloud Service Benchmark, который имитирует поведение социальной сети или новостного портала. Там немножко другие паттерны чтения и записи. Конечно, лучше всего было бы сравнить все СУБД именно с вашим приложением. Но это не всегда возможно.
Поэтому если при миграции вам придется потратить в два раза больше времени при сравнении двух продуктов — вам надо решить, оно того стоит или нет.
Не самые очевидные критерии
ОК, функциональность и скорость — критерии важные и очевидные. А есть еще менее очевидные, на которые, тем не менее, стоит обратить внимание.
Если вы выбираете продукт с открытым кодом, у вас появляется возможность его развивать их самим, если у вас есть соответствующие специалисты. У нас в QIWI, например, есть коммитер в Cassandra.
Поскольку у разных продуктов могут быть разные лицензионные подходы (платные и бесплатные, открытый код, закрытый код), наличие соответствующих специалистов будет для вас несомненным плюсом, особенно, если они пишут на том же самом языке, на котором написан продукт.
Важная вещь. Когда вы выбираете базу данных, обычно это серьезные отношения и надолго, это будет legacy, который будет с вами на 10 и более лет. Поэтому очень важно, что будет с этим продуктом происходить.
Вот вы выбрали какой-то продукт, который вы видите первый раз в жизни. Не загнется ли он завтра по каким то причинам, например, того, что инвесторы решили, что все, хватит, мы больше не имеем с ним никакого дела? Или разогнали команду разработки, например. Всякое бывает. Поэтому важно, кто вообще основатель, кто клиент этого продукта, сколько в него вложено сил и времени. Если этим пользуется какая-то большая известная компания, почему бы нам тоже не попробовать?
Ещё есть вопрос с поддержкой. Он всегда очень сложный, особенно, если это опенсорс — как правило, на такие продукты находятся платные консалтинги, которые могут его поддерживать.
Если сам вендор закрывает исходники, то он, естественно, сам занимается поддержкой. Тут всегда есть нюансы, например, в нынешней ситуации не всегда есть возможность эту поддержку получать. Так что на этот фактор тоже стоит внимательно смотреть.
Сложность архитектуры. Например, в архитектуре, у которой все узлы в базе данных одинаковые, так называемая coupled-архитектура, каждый узел всегда выполняет одну и ту же функцию. То есть чтобы его масштабировать, мы просто размножаем эти узлы, до тех пор, пока нам не станет хорошо.
Что делать, если продукт сложный, например, из-за того, что в TiDB гибридный подход? Там есть специальные узлы другого назначения — не только для транзакций, но и для аналитических запросов. Надо масштабировать эти узлы отдельно, надо за этим следить. Возможно, надо держать больше людей или больше мониторинга, потратить больше денег еще на что-нибудь.
А вот субъективный критерий, про который тоже надо помнить. Storage Engine. Вообще, для чего нам база данных нужна? Чтобы надежно хранить данные. Вот я что-то записал в нее, и я хочу быть уверен, что потом эти данные обязательно достану. Мой опыт работы в Oracle говорит, что бывают такие баги, которые приводят к повреждениям данных в месте их хранения. Думаю, это самое плохое, что вообще бывает с заказчиком — когда он не может прочитать свои данные.
Так что движок хранения данных — это важная штука, от которой зависит очень много. На рынке много таких популярных движков. RockDB как раз один из движков key-value, которые используются для хранения данных. Он установлен на миллионах серверов. ОК, даже если и меньше — если он популярный и используется в Фейсбуке и ещё во многих компаниях, значит, он проверен временем. Уже можно надеяться, что почти все корнер-кейсы были пройдены, а баги — найдены.
Некоторые NewSQL-продукты пишут свои движки сами. И тут главный вопрос — насколько вы верите в этих разработчиков?
Jepsen.io
Допустим, вы выбрали конкретного производителя распределенной консистентной СУБД. Насколько то, что он обещает, вообще соответствуют реальности? Как это проверяется?
Есть специальная консалтинговая компания, которая проводит тесты, которые бы мы назвали сейчас «Хаос-инжиниринг» — вносит возмущение в кластер таким образом, чтобы что-то сломать, и сломать так, чтобы мы могли проверить, при каких именно условиях и что может пойти не так.
Например, если я отстрелил случайным образом какие-то узлы кластера или внес задержки между какими-то сетями. Или часы неправильно показывают время на каких-то узлах — насколько это вообще влияет на консистентность данных, на скорость? Соответствуют ли данные, которые мы получаем, уровню изоляции транзакций, который определен и записан в документации? Нормальные вендоры NewSQL СУБД встраивают этот тест в свои CI/CD флоу.
Так что при генерации нового релиза у них срабатывают автотесты. Появляется определенная картинка, сколько тестов прошло, сколько не прошло. Много интересного (но не всегда приличного) можно найти в поиске гитхаба по запросу «jepsen».
Практической ценности тут не так много — вряд ли вы будете сами запускать эти тесты на своих инсталляциях, если только не совсем параноики. Лучше оставить это специалистам. Но вот если компания-производитель распределенной СУБД использует эти тесты внутри себя для того, чтобы проверить, все ли у них хорошо — это очень здорово.
NewSQL в QIWI
Мы достаточно давно присматривались к NewSQL. Cockroach DB мы заметили лет пять назад. Он был еще, прямо скажем, сырой. Там не было важных вещей, таких как select for update. А вот когда они появились, мы решили попробовать.
Запилили тестовый продовый кластер, написали приложения, которые его используют. Всё достаточно долго работало, хотя оно было не очень нагружено. Мы могли проверить и оценить, как вообще нам с ним работать, легко ли им управлять, легко ли устранять какие-то проблемные ситуации? В принципе, нам все понравилось, и мы пошли в прод.
Мы перенесли на Cockroach DB достаточно критичную базу из Oracle. Она, конечно, достаточно скромная, про этот опыт я уже писал пост. Там не так много данных было, 10 миллионов строк, которые мы за полчаса мы мигрировали из Оракла в Cockroach DB. И вроде бы — ничего особенного, но это дает уверенность в том, что этот класс продуктов реально повышает отказоустойчивость системы по сравнению с одноузловыми. Прямо очень серьезно. И у нас прям не было простоев с тех пор, мы обновляли версии в онлайне и прочее.
В общем, опыт позитивный. Будет здорово, если сможете поделиться в комментах своим опытом с NewSQL.
Ваш Дядя Петя.
Автор:
PeterBobrov