Комментарии 41
Спасибо за наглядную демонстрацию работы с Tarantool. Не был знаком, но теперь имею представление. Вообще, у вас отличная подача материала, как в текстовом, так и видео формате. С удовольствием смотрю и читаю.
Спасибо за наглядную демонстрацию работы с Tarantool.


Это и грустно. Tе первый год по конференциям ходят люди с разного рода PoC на базе tarantool (на прошлогоднем bigdatadays, например, рассказывали о tg боте написанном в инфраструктуре сабжа), а что с реальным применением — как-то не совсем ясно.
А в реали получается сложновато работать из системой, у которой документация написана для инопланетян.

У меня самого десятки PoC были на тарантуле. В итогое рано или поздно нервы сдают и все переписывается на python+pgsql…
документация написана для инопланетян.

А можете сказать, что конкретно вам не нравится в документации и какой бы вы хотели её видеть?

А мы тут как раз запилили удобный инструмент для фидбека на документацию прямо на сайте, может придёте и напишете о своей проблеме?


В правом нижнем углу страницы есть кнопка:



Откроется форма:



Из этой формы фидбек попадает прямо в задачи.

у которой документация написана для инопланетян.

Да нормальная там документация. Примеров не хватает, но на «для инопланетян» не тянет. Вот когда у вас вместо документации автогенерированная простыня с формальным описанием методов и того, что они возвращают-принимают, вот там сложно бывает.

Мне этот подход чем-то де-факто напомнил… FoxPro на NoSQL. Прикольно.

Соответственно, у нас порядка 3500 запросов в секунду на маленькой машинке, где 2 ядра и 4 гигабайта памяти


А как эта радость внутри устроена? Write ahead log гарантирует сохранность данных? Если так, то tarantool должен писать на диск каждую запись в режиме прямой записи, а это где-то 20-30 МБ в секунду на хорошем серверном диске.

Подозреваю, что пишется WAL в какой-нибудь mmap, поэтому все быстро. А грустно станет как только память кончится или как только большой snapshot надо будет на диск сохранить.

Статья хорошо, а исходник лучше. Идём туда и видим что и ожидалось в wal.c


if (wal_mode == WAL_FSYNC)
    writer->wal_dir.open_wflags |= O_SYNC;

Нормальная запись в WAL будет только если указать специальный флаг в конфиге tarantool. Если его указать, то вся производительность на запись улетучится. Напомню, что без O_SYNC запись почти всегда будет в кеш ОС, а не на диск. Похожий трюк использовала mongo в своё время, чтобы показать высокую производительность на запись.


Ещё по ходу изучения исходника видим какие-то разговоры про MVCC… Видимо идут по пути mongo — огребли с производительностью и надежностью и начали делать нормальную БД. Ещё 10 лет и будет что-то подобное pg, но зачем?


Если про статью говорить, то про запись там рассказываются сказки, а измеряется скорость записи в кеш ОС. О чтении тоже смешно — нас пугают локами и загрузкой данных с диска. Но если БД читает из кеша то локов столько же, а диска нет. И не понятно с чего бы это tarantool был быстрее.

Нормальная запись в WAL будет только если указать специальный флаг в конфиге tarantool. Если его указать, то вся производительность на запись улетучится. Напомню, что без O_SYNC запись почти всегда будет в кеш ОС, а не на диск.

Что такое "нормальная запись в WAL" и зачем так нужна запись на диск? Если ваш ответ — чтобы данные не пропали случайно при блекауте, то фсинк тут мало на что влияет — сервер ведь и вместе с диском сгореть может. И тогда мы перейдем к разговору о репликации, желательно синхронной, но это будет уже совсем другая история.

Что такое "нормальная запись в WAL" и зачем так нужна запись на диск?

Нормальная это O_DIRECT, чтобы при краше процесса данные не терялись. Есть ещё один вариант нормальности. Это когда данные в несколько реплик попадают и после этого только возникает ответ от сервера о завершении транзакции.


Лучший вариант для tarantool — сказать честно, что пишем в память, сбрасываем на диск как прийдется и это плата за скорость, имейте в виду. Ещё лучше дать настройки, чтобы это сбрасывание на диск подкручивать. Вот только тогда прибегут любители PG и начнут тыкать в async commit, который ровно это и делает и начнут задавать неудобные вопросы о преимуществе перед классической БД.


Если ваш ответ — чтобы данные не пропали случайно при блекауте, то фсинк тут мало на что влияет

Мой ответ — чтобы данные не терялись при падении самого tarantool или ОС. И кажется вы путаете блекаут (потеря электроснабжения) с пожаром или падением метеорита на дата центр.


Дисковый кеш ОС может занимать гигабайты, запросто всю свободную память. Представляете сколько данных можно потерять если на нагружённом сервере у tarantool случится out of memory? Ещё чаще OOM будет случаться если запустить tarantool в k8s или докере с лимитом по памяти. А это чуть ли не основной способ развёртывания сейчас.

Представляете сколько данных можно потерять если на нагружённом сервере у tarantool случится out of memory?

Столько, сколько транзакций происходит за единицы миллисекунд, которые составляют лаг репликации.
Вы ведь не пытаетесь всерьёз рассматривать однонодовую систему, рассуждая о сохранности данных?

Вы ведь не пытаетесь всерьёз рассматривать однонодовую систему, рассуждая о сохранности данных?

А почему нет? RAID придумали давно, любое вменяемое облако будет хранить две и более копий ваших данных совершенно прозрачно для вас. Выход одного диска из строя вам не навредит. Но для этого данные должны попасть на диск.


Как только вы включили синхронную репликацию, вы опять же убили производительность вставки и обновления. БД будет платить за запись на диск, tarantool за запись в сеть, результат будет похожий. И чего мы добились? Скорость вставки такая же как у БД, но у есть кластер из 3 нод, много потраченных денег, времени и нервов. 3 ноды нужны чтобы когда одна упадёт и будет индексы восстанавливать или снепшот читать и обновлять осталось хотя бы две.

Любая более или менее критичная продакшен система не сможет ждать, пока админы пойдут переставлять диски из вышедшего из строя сервера. Если ваш сервис может лежать часы, то да — RAID вас спасет.
Поэтому однонодовую систему можно всерьез рассматривать только когда у вас есть надежный SAN, который за минуту-другую можно перекинуть на другой сервер.
Вы можете возразить что в облаках есть сетевые диски, которые при этом еще и с бэкапами. Но и это не панацея, потому что эти сетевые диски тоже выходят из строя.

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

Если в RAID умер один диск, то БД этого даже не заметит, админ замерит диск и все станет ок. Если вас беспокоит, что сгорит железо кроме диска, то настроить hot standby в pg можно и это весьма стандартная и изученная процедура.

Так а я что сказал в своем ответе? Хотите отказоустойчивость, которая совместима с реальными сценариями — используйте репликацию. Вы мне говорите по сути то же самое: «используйте hot standby».
В чем ваше возражение?

Возражение мое состоит в том, что далеко не все «реальные сценарии» требуют hot standby и high availability. С учетом крайне невысокой вероятности потери данных или простоя с хорошим RAID в большинстве случаев хватит просто БД. Кроме того этот high availability имеем почти бесплатно в Amazon RDS.

Вот только тогда прибегут любители PG и начнут тыкать в async commit, который ровно это и делает и начнут задавать неудобные вопросы о преимуществе перед классической БД.

Извините, PG пишет на диск в B-tree, а Tarantool только в WAL. Это большая разница. Далее, PG читает данные с диска, а Тарантул из RAM. Вот таким нехитрым способом Тарантул захватывает мир обеспечивает высокое быстродействие.

Все не так. PG пишет WAL, а затем, потихоньку пишет на диск в heap (таблицы) и B-tree (индексы, чаще всего), но вас это не касается и происходит асинхронно. Транзакция завершается когда данные попали в WAL. PG также все прекрасно читает из памяти. Отдайте под кеш всю свободную оперативу и наслаждайтесь. Статья приводит неубедительные аргументы про разницу в скорости поиска в кеше и памяти.


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

Ой, все. «Сейчас я вам за 5 минут из своей Посгри сделаю Тарантул (<place-here-your-favourite-system-name>)». Это мы уже слышали.

А что асинхронная нагрузка iops-ы не поднимает? Любим обогревать космос или хотим проверить через какое время при стабильно высокой нагрузке очередь на запись дорастет до таких размеров что диски лягут?

Далее. Кэш не есть in-memory DB! Кэш надо как минимум один раз считать с диска (предварительно поискав там и обломавшись). Ну и классическая проблема всех кэшей — это синхронизация. Отредактировали страницу — флашим ее на диск и дальше по схеме…

Раз уже проходили, то может объясните чем принципиально тарантул отличается от БД и что конкретно позволяет ему быть быстрым? Пока ваши высказывания о работе PG просто не соответствуют действительности и по факту PG делает то же самое, что и тарантул.


Про IOPS и асинхронщину не понял от слова совсем. При интенсивной работе у вас забьётся либо буфер диска либо буфер сетевой карты и все встанет колом. Не важно тарантул или PG, если железо перегружено, вам ничего не поможет.


Про чтение из кеша — разница в двух моментах а) прогрев кеша б) поиск элемента, которого в БД нет. В остальных случаях работы по поиску, включая блокировки будет сделано столько же. Что-то вроде такого «дай страницу индекса — вот держи из кеша; дай следующую, вот держи, опять из кеша; дай страницу с данными, пожалуйста, опять из кеша» Если все данные влезает в кеш, то на диск БД сходит ровно один раз для каждой страницы. И да, в PG MVCC поэтому блокировок при чтении не будет, от слова совсем, если специально не озадачиться.


В тарантуле будет «дай узел b-дерева индекса — вот держи из памяти; дай следующий, вот держи, опять из памяти; дай данные, пожалуйста, опять из памяти». Если учесть, что размер страницы индекса часто совпадает с размером узла b-дерева, то ситуации вообще зеркальные, замерите «страница» на «узел b-дерева» в тексте о БД.


При обновлении всего этого обе системы сделают одно и то же. Запишут в WAL, обновят данные в памяти, отрапортуют о завершении транзакции, запишут данные на диск когда-то позднее.

Давайте так: мне не хочется бросать эту тему, потому что люди эти вопросы задают часто. Поэтому предлагаю так: я напишу отдельную статью с простым примером, который показывает что Postgres не вытянет сравнение с in-memory в сценарии большого потока простых запросов. Для этого достаточно сделать несложный пример и нагрузочный сценарий на Go.

Простой ответ на ваш вопрос такой: мы похожи на Redis по устройству, и Redis имеет свою нишу и используется обычно вместе с традиционными базами данных. Если бы Postgres справлялся с задачами так же хорошо как Redis, его бы использовали вместо Redis везде. То есть если бы повышение перфоманса можно было бы сделать только выкручиванием кэшей, то рынка in-memory баз просто не существовало бы. Я понимаю что вы можете с этим не согласиться, сказав что это хайп и люди просто не понимают Postgres. И тогда мы вернемся к практическому тесту, без которого этот спор не решить.

Если отвечать по существу более полно, то:

— в Tarantool сделан компромисс в дизайне и реализации. Мы расчитаны на большое количество достаточно простых запросов (выборки единичных объектов по индексам)
— это позволяет нам максимально упростить реализацию, что снижает константные издержки на каждый запрос
— все что можно — мы максимально стараемся обработать в виде батчей, то есть между обработкой отдельных запросов не происходит дорогих переключений контекста. это возможно благодаря тому, что мы расчитаны на относительно небольшие запросы. если бы мы были расчитаны на любые типы запросов, то батчинг такого типа был бы не эффективен, потому что длинные запросы блокировали бы более короткие, и их latency бы сильно возрастал
— при обработке индивидуальных запросов мы часто не используем блокировки (мьютексы). за счет этого получается экономить на времени обработки одного запроса
— по этой причине нам приходится использовать только один поток на экземпляр. это и плюс (сокращение затрат на блокировки), и минус — для масштабирования можно применять только шардинг, а не добавление ядер в экземпляр.
— ну и то что у нас нет сложного кода, который был бы нужен для реализации более «генерализованной» БД, тоже уменьшает константные накладные расходы на каждый запрос

В целом вы правы — выкручивание кэшей в постгресе делает его своего рода «in-memory БД». Но дьявол в деталях и константных накладных расходах которые в постгресе выше на каждый запрос, по сравнению с тарантулом.

Еще что важно — пока кэш в postgres не прогреется, вы не сможете выдавать максимальную производительность. Некоторое время каждый запрос будет идти на диск. В реальных продакшен сценариях это приведет к тому, что после отказа мастера в hot standby, вся система будет работать существенно медленнее некоторое время, потому что кэш на реплике не прогрет.
Поэтому предлагаю так: я напишу отдельную статью с простым примером, который показывает что Postgres не вытянет сравнение с in-memory в сценарии большого потока простых запросов. Для этого достаточно сделать несложный пример и нагрузочный сценарий на Go.

Не думаю, что только синтетические тесты могут быть достаточно убедительны. Всегда будут вопросы вида «а если подкрутить такой-то параметр в PG, то все будет хорошо». Эти вопросы можно убрать только если показать, что tarantool и pg делают похожие вещи по разному, а из этой разницы вытекает разность в производительности.

Это обсуждение могло бы выглядеть так — «tarantool делает так-то, а PG так-то. PG иначе делать не может, потому что фича XYZ. А тарантул может, потому что в нем XYZ нет.» Например, tarantool не пишет в WAL в режиме O_DIRECT/O_SYNC, а рассчитывает на репликацию для сохранности данных. Это означает, что данные из WAL попадают на диск по мере заполнения буфера ОС, что помогает ОС эффективнее использовать диск. Платой за скорость вставки является недопустимость использования тарантула без репликации в продакшене.

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


PG справляется c большинством задач Redis не хуже чем он сам. Но вы не можете поставить 100 серверов PG и заставить их работать вместе, а Redis + application specific code позволяют это сделать. PG не кеширует результат сложного запроса, вы можете их закешировать в Redis. То есть Redis это либо условная дополнительная память для кеша PG, либо кеш результатов сложных запросов. Оба этих сценарий не похожи на целевое использование тарантула, который скорее позиционируется как основное хранилище для данных.

— в Tarantool сделан компромисс в дизайне и реализации. Мы расчитаны на большое количество достаточно простых запросов (выборки единичных объектов по индексам)

Интересно было бы сравнить скорость выборки с помощью hash индекса в pg и тарантуле. А если PG медленнее, то разобраться что позволяет тарантулу быть быстрее. Уже на таком простом примере можно показать важные отличия между подходами. Честно говоря, я не вижу причин почему PG должен тут существенно проиграть. Если я не прав, то буду рад узнать что-то новое.

— по этой причине нам приходится использовать только один поток на экземпляр. это и плюс (сокращение затрат на блокировки), и минус — для масштабирования можно применять только шардинг, а не добавление ядер в экземпляр.

Это принципиальнейшее отличие с далеко идущими последствиями о которых крайне важно говорить. Именно такие вещи и хочется обсуждать сравнивая тарантул с БД.

Я понимаю преимущества одного потока, особенно в части упрощения внутренней реализации. Обратной стороной медали видимо будет
— Сложности с CPU bound вещами типа JOIN или ORDER BY в памяти.
— Нереальность синхронной записи в WAL — O_SYNC, O_DIRECT становятся слишком дорогими, так как замедляют единственный поток исполнения.
— Долгоживущие транзакции это проблема
Не важно тарантул или PG, если железо перегружено, вам ничего не поможет.

Запись в b-дерево — большой объем холостой работы не зависимо от того, в каком режиме она выполняется — синхронном или асинхронном. С PG отказ железа наступит при существенно меньшей нагрузке, не?

Еще у нас есть сервер приложений. Код работает в одном адресном пространстве с БД. racktear может в статью еще нагрузочный пример на Lua добавить? :)

Запись в b-дерево это не холостая работа, это запись в b-дерево :) В БД транзакция завершится сразу после записи в WAL и до записи данных в b-дерево индекса или в таблицу. Отдельный поток(и) работы с диском, который разгребает WAL и пишет на диск прекрасно загрузит все мощности железа. При таком подходе синхронная или асинхронная запись не очень важно.


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


Сервер приложений в чем-то лучше скриптов и хранимок в БД?


Я правильно понимаю, что репликация работает в pull режиме, то есть реплики запрашивают данные с мастера когда им удобно?

Если tarantool не пишет индексы на диск, то это ещё один компромис, о котором нужно говорить.

На роль волшебного продукта Tarantool не претендует. Претендует на то, что он удобен и эффективен для highload. Естественно, все достигается за счет компромиссов.

Сервер приложений в чем-то лучше скриптов и хранимок в БД?

Ну как вам сказать. Полноценный язык программирования с реактивным джитом и развитой экосистемой против процедурного PL/SQL…

Я правильно понимаю, что репликация работает в pull режиме, то есть реплики запрашивают данные с мастера когда им удобно?

Да, асинхронная репликация работает так:
A replica gets all updates from the master by continuously fetching and applying its write ahead log (WAL).
На роль волшебного продукта Tarantool не претендует.

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

Ну как вам сказать. Полноценный язык программирования с реактивным джитом и развитой экосистемой против процедурного PL/SQL…

В PG есть python из коробки, можно пользовать JavaScript. Логика в самой БД плохо работает когда эта логика делает еще какое-то IO кроме БД. Поэтому все и пишут код где-то в других процессах. Так как тарантул однопоточный, то становится интересно как он эту логику запускает.

Я правильно понимаю, что репликация работает в pull режиме, то есть реплики запрашивают данные с мастера когда им удобно?

Да, асинхронная репликация работает так:

Это провал. В случае падения мастера вот что будет:
— Клиент уже увидел commit и ожидает, что данные надежно сохранены. Возможно он тоже закомитил свою транзакцию в своей БД.
— Реплика еще не успела с мастера запросить данные.
— Мастер упал и потерял содержимое WAL из буфера ОС.
В итоге клиент считает, что данные есть, а тарантул о них ничего не знает. Есть вариант покруче — реплика успела данные загрузить, а мастер упал и данные потерял. Запросы на реплику данные вернут, а запросы на мастер нет.

Это выглядит как нечто, что нельзя исправить не меняя архитектуру тарантула. При этом выше в этом треде мне советовали использовать репликацию как средство решения проблем с отложенной записью в WAL…
> Логика в самой БД плохо работает когда эта логика делает еще какое-то IO кроме БД.

Кооперативная многозадачность. Тарантул йилдит в этом случае.

> Это провал

Ой да ну вы так не пугайте. Есть уже и синхронная репликация.

Ну и в целом, спорить на тему того, работоспособна/эффективна ли система, активно использующаяся в продакшене, конечно, можно, но это немного бессмысленно. Поэтому я, пожалуй, завершаю разговор. Рекомендую почитать tarantool.io. После этого многие вопросы отпадут сами собой.
Ой да ну вы так не пугайте. Есть уже и синхронная репликация.


Синхронная репликация + однопоточная архитектура это тоже провал, к сожалению.
Видимо идут по пути mongo — огребли с производительностью и надежностью и начали делать нормальную БД.

Тут вы не правы. Tarantool используется более 10 лет во многих проектах MRG. С производительностью не огребали, с надёжностью тоже. А вот добавление новой функциональности и возможностей, таких, как MVCC, может дать новые точки роста и применения


И да. У вас в комментариях довольно много слов нормальный. Не поделитесь ли критерием нормальности?

Нормально, это когда производитель решения раскрывает компромисы, на которые он идёт ради достижения заявленных характеристик. Не нормально когда говорят ACID, а на деле фиг. Или сравнивают запись в память с записью на диск.


Если вам хватает tarantool, то возможно вам хватило бы и pg с асинхронным комитом.

«А почему под эту задачу не использовать Tarantool?».

А почему не MemSQL ;) Ваш же соотечественник разработал или придумал, неважно.
Не как апликейшен сервер, а как базу в которую влетают миллионы записей в секунду, а скорсть выборки сопоставима с OLAP кубами и это на чистом SQL.

MemSQL это closed source, и больше 128 Гб и 4 узлов в бесплатной версии не позволяет делать. А так — можно и его, и еще многие другие решения платные использовать, если вы готовы платить.

Closed source имеет значение? Как на меня, чем меньше я занимаюсь не делом — тем лучше.


можно и его, и еще многие другие решения платные использовать, если вы готовы платить

Скупой платит дважды а то и больше. Какие еще платные решения можете посоветовать? Я пока только MemSQL эвалюэйтил. Быстрый чертяка, без танцев с бубном.

Есть еще Microsoft SQL Server. Там есть in-memory вариант. Есть Ignite. Их довольно много.

Но в целом вы должны понимать, что как только вы берете любую шардированную базу данных — про нетривиальные распределенные JOIN-ы можно смело забыть (или забыть про перформанс).

Хороших баз много. Если говорить про отличие конкретно Tarantool, то при необходимости «поджать» перформанс в конкретном случае, это можно без особого труда сделать через программирование модулей. Обратная сторона в том, что Tarantool может быть сложнее использовать, если вам нужно все «из коробки» и максимально просто.
Есть еще Microsoft SQL Server. Там есть in-memory вариант. Есть Ignite. Их довольно много.

Меня больше интересует смогут ли они поддержать кластер из 100+ нод без привличения орды девопсов и маинтейнеров.
MemSQL гибридный вариант: есть in-memory для быстрой OLTP нагрузки и Column Store (диск) для скоростной анвлитики. Петабайт в пямять дороговато закидывать )


Но в целом вы должны понимать, что как только вы берете любую шардированную базу данных — про нетривиальные распределенные JOIN-ы можно смело забыть (или забыть про перформанс).

Вот тут вы ошибаетесь, именно по этому я и говорю про MemSQL — нету у них проблем с JOIN https://www.memsql.com/blog/performance-for-memsql-67/ просто посмотрите на милисекунды. Я такие умопомрачительные квери пускал (1500 строк) без тюнинга индексов что глазам не поверил. Кластер как пчелка задействовал все ядра чтобы выдать результат как можно быстрее.

Любой инженер который собирается работать с тарантулом должен четко понимать то как «отлично» он масштабируется вертикально и какая «прекрасная» у них политика платной поддержки. Но как-то об этом не пишут.
В документации сказано довольно четко про модель многопоточности, и что у тарантула один поток: www.tarantool.io/en/doc/2.2/book/box/atomic
Поэтому вертикального масштабирования у нас нет, только горизонтальное.

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

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

Очень дорогая платная поддержка при хоть сколько нибудь нормальной нагрузке по QPS была одна из причин почему моя организация отказалась от Tarantool в пользу собственного решения.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Информация
Дата основания

11 февраля 2019 г.

Местоположение

Россия

Численность

11–30 человек

Дата регистрации

22 июля