Как стать автором
Обновить

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

Можно сразу вопрос — если ставить таким образом на сервера, где по 16 vCPU, будут ли они все задействованы?


Мы как-то экспериментировали, и загружался только один из vCPU.

Да, тарантул условно говоря однопоточный. Запросы обрабатываются в файберах (корутинах), которые поочередно запускаются на одном железном треде.


Почему «условно говоря» — потому что внтури тарантула есть еще два служебных железных треда для io операций.


Таким образом мы рекомендуем на каждые полтора ядра запускать один тарантул.


Чтобы расшардить данные на все эти инстансы, у нас есть фреймворк бакетного шардирования — https://github.com/tarantool/vshard

А как синхронная репликация дружит с однопоточностью и с транзакциями?

А как синхронная репликация дружит с однопоточностью и с транзакциями?

Разве у Тарантула синхронная репликация?

С однопоточностью и транзакциями идея в том, что Tarantool изначально очень быстрая СУБД in-memory и транзакция отрабатывает моментально, освобождая СУБД для следующего запроса. Плюс там еще бизнес-логика внутри СУБД живет, что позволяет транзакциям еще быстрее отрабатывать.

По утверждению разработчиков — именно один поток и позволяет проводить операции настолько быстро, что позволяет обойтись без блокировок, которыми вынуждены пользоваться другие СУБД.
Без синхронной репликации наступает печалька с возможной потерей данных. Тут я об этом беседую с людьми из тарантула — habr.com/ru/company/rebrainme/blog/521556/#comment_22146644

Там все было примерно так
1. Запись в WAL асинхронная, транзакция может закомититься, а данные на диск не приедут. Это делает тарантул таким быстрым на запись по сравнению с тем же PG. Синхронная запись в WAL возможна и даст надежность, но это больно для однопоточной архитектуры и все будет очень медленно.
2. Мне отвечают — реплицируйте и будем вам счастье. Нормальный и известный подход — вместо записи в WAL пишем в N реплик и надеемся, что они не упадут вместе с мастером.
3. Я выясняю, что мастер данные не пушит в реплики, а реплика их забирает с мастера раз в какое-то время — это называется асинхронная репликация. Возникает вопрос — сервер упадет, реплика данные не забрала — будет печалька.
4. Мне советуют использовать синхронную репликацию, которую завезли в какой-то версии тарантула.
5. Я прошу объяснить как это будет работать в однопоточной архитектуре. Но ответа не получаю.

Поэтому буду ходить по тредам с тарантулом и спрашивать :) Вот такой я тролль.
Запись в WAL асинхронная, транзакция может закомититься, а данные на диск не приедут. Это делает тарантул таким быстрым на запись по сравнению с тем же PG. Синхронная запись в WAL возможна и даст надежность, но это больно для однопоточной архитектуры и все будет очень медленно.


Разве асинхронная?
В свое время разработчики Тарантула как раз хвастали, что успевают данные записывать на диск.

Скорость записи на современные диски — довольно велика. А с учетом того, что Тарантул пишет не полностью данные, а только изменения — может быть и быстрее сетевых запросов на изменение данных.
Разве асинхронная?

Да, асинхронная, можете в исходник посмотреть. Тарантул пишет с помощью write в файл без O_DIRECT или O_SYNC, а значит данные лягут в буфер ОС, а на диск отправятся когда-то потом. Есть опция это поведение отключить, но это убьёт скорость.

Скорость записи на современные диски — довольно велика.

Вы можете удивиться, но без буферизации на десктоп SSD можно получить 2-3 Мб/с, на серверном 20-30 Мб/с. Но дело даже не в этом — если писать WAL «честно», то скорость на вставку/обновление будет не выше чем у того-же PG. Возможно разница и будет, но не принципиальная.

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

Изменения пишут все известные мне БД, это не то чтобы фишка тарантула.
Вы можете удивиться, но без буферизации на десктоп SSD можно получить 2-3 Мб/с, на серверном 20-30 Мб/с.


При переполненном диске, когда TRIM отключен и удаление не успевает до записи? Зачем на сервере в таком режиме эксплуатировать диск?

А в нормальном режиме эксплуатации даже при отключенном кэше записи даже на десктопе — цифры на порядок выше, чем те, что привели вы. Как бы даже не на 2 порядка.

Чувствую скепсис, попробую развеять.


Все быстро пока вы можете загрузить pipeline диска. И все очень медленно как только вы пишите по 100 байт и каждый раз ждёте подтверждения записи. Второй режим характерен для БД, которая пишет в WAL результаты небольших транзакций. Аналогичная штука с сетью происходит. Вот тут можете посмотреть результаты теста дисков — https://m.habr.com/ru/company/selectel/blog/521168/ аналогичных тестов навалом в сети. В тесте по ссылке десктоп как раз даёт 3 Мб/с на запись.

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

Это влияет на скорость если у БД только одно соединение с одним клиентом. Когда есть поток запросов, можно в WAL писать относительно большими пачками (batching).

Это влияет на скорость если у БД только одно соединение с одним клиентом. Когда есть поток запросов, можно в WAL писать относительно большими пачками (batching).


Безусловно.
Но Tarantool однопоточный (это принципиальное решение разработчиков, так по их мнению получается существенно быстрее) и с пачками клиентов там всё непросто.

Хочется надеяться, что разрабатывая систему под highload разработчики всё это учли. Но как именно учли?

Если их решение — это шардинг на 100 000 экземпляров Тарантула запросов 100 000 пользователей, но при этом каждый экземпляр из за однопоточности обрабатывает только 1 запрос при этом — тогда такое решение очень нишевым получается.
Но Tarantool однопоточный (это принципиальное решение разработчиков, так по их мнению получается существенно быстрее) и с пачками клиентов там всё непросто.

Непросто, если на одно клиентское соединение приходится один CPU. Но это какая-то экзотика, а "в среднем" не должно быть проблем с собиранием пачек для записи в WAL.

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

Естественно, мы размениваем latency на throughput. Конкретные пропорции этого размена сильно зависят от конфигурации теста, на каком-то этапе производительность растет быстро (если собираемые в пачки запросы невелики по размеру), а задержка практически не меняется.

Чем больше вы делаете размер пачки тем лучше для диска, но тем дольше ждет тот, кто оказался вначале пачки.


В реальности в подобных системах есть 2 параметра:

Размер буфера, по достижению которого производится сброс на диск.
И таймаут, по достижению которого производится сброс на диск даже если в буфере всего лишь одна транзакция.
Без синхронной репликации наступает печалька с возможной потерей данных. Тут я об этом беседую с людьми из тарантула — habr.com/ru/company/rebrainme/blog/521556/#comment_22146644


Там вы еще вот что интересное пишете:

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

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


Есть еще разрушение файловой системы, которое зеркально отразиться на всех зеркалирующих дисках RAID.
Нет, RAID недостаточно…
Все правильно. А еще есть такой сюрприз: диск сказал операционке OK, но в реальности это сообщение оказалось несколько преувеличено…

https://en.wikipedia.org/wiki/Disk_buffer#Write_acceleration

Если мы переходим к разговору о синхронной репликации, то сейчас состоялся релиз Tarantool, в котором реализована эта синхронная репликация наряду с mvcc. Или если быть точнее — с помощью.


https://github.com/tarantool/tarantool/releases/tag/2.6.1

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

Будет ли тарантул ждать пока данные уйдут на синхронную реплику прежде чем начинать следующую транзакцию?

Да. Производительность будет зависеть от настроек replication_synchro_quorum, replication_synchro_timeout и железа.

Мы как-то экспериментировали, и загружался только один из vCPU.


Тарантул принципиально однопоточный.

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

А, говорят, если нужно задействовать все ядра — просто запускайте несколько Тарантулов. И делайте шардинг или еще как делите между ними данные.

sarcasm on
Ай-ай-ай, 2020, корпоративный блог, а у вас слово «мастер», как же так неполиткорректно, и как ревьювер пропустил?
sarcasm off
Зануда спойлер
в русском языке слово «мастер» не несет той же коннотации, что «master» в английском.
Ну, мне конечно пофиг, но вообще как раз таки в русском языке я слово «мастер» в контексте отношений воспринимаю с куда более негативным оттенком, нежели в английском. Потому что нормальное значение этого слова в русском языке — специалист, человек, умеющий что-то делать хорошо, профессионал, эксперт. А в контексте «главный» это уже БДСМ какое-то и это несет в себе негативный подтекст больше, нежели master в английском (по крайней мере для не-нейтива)
А в контексте «главный» это уже БДСМ какое-то

Но в русском БДСМ слово «мастер» в смысле «главный» не употребляется (точнее даже не «главный», а «верхний», если использовать правильную БДСМ-терминологию).
Слово «хозяин» — может использоваться, да.

А то что с английского слово master переводится еще и как «хозяин» для русскоязычных БДСМ-щиков по барабану. Возможно, англоязычные БДСМ-щики и используют слово master, но какое это имеет отношение к русскому языку?

Непонятно как конфликты разгуливаются. На одной реплике игрок А поставил бомбу и умер от взрыва другой бомба. А на другой реплике он сначала умер, а затем поставил бомбу.

Я думаю, это выглядит как неконсистентность игрового мира в некотором моменте. В идеале, чтобы такого не происходило, необходимо пользоваться «неотрицательным репликационным счётчиком» — но у меня такого под рукой пока нет.

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


«неотрицательного репликационного счетчика» скорее всего в природе не бывает. Такой счётчик будет точкой синхронизации для всех реплик сводя все преимущества master-master к нулю.


Вопрос я задал надеясь на обсуждение нюансов master-master в тарантуле. Пока на разные мастера летят события, которые модифицируют несвязанные объекты — все хорошо. Это коммутативные события, ab = ba. Интересно становиться когда два мастера получают события, которые взаимосвязаны, некоммутативны, ab != ba. Известные мне решения предполагают централизованный координатор транзакций, который эти штуки будет разруливать. Но, кажется, в тарантуле этого нет. И тогда возникает вопрос что делать?

В конкретно статье используются только коммутативные транзакции.

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

Не уверен, что это так… если бомба уменьшает здоровье персонажа до 0 на одной реплике, но этот же самый персонаж что-то делает на другой. Как это будет разруливаться?

В одном из других проектов это решалось версионированием и оптимистичными блокировками

Непонятно как версионирование должно работать в среде master-master. Кажется это означает, что все реплики должны синхронизироваться до завершения транзакции. Иначе на одной реплике закомитилась транзакция с версией 10, на другой тоже закомитилась транзакция с версией 10. Зачем при обмене данными получится печаль.

Оптимистичная блокировка также требует глобально упорядоченных событий. Мастер 1 заблокировал ряд X, в то же время Мастер 2 сделал то же самое. Через 5 секунд они оба закомитили свои транзакции, каждый сделал это успешно, потому что не было конфликтов. Но через 10 секунд они пытаются обменяться данными и...?

Известные мне способы решать подобные задачи это
— Sticky session, есть выделенные сервер (возможно с hot standby) которые обрабатывать конкретный объект. Тогда все обновления объекта можно упорядочить.
— Консенсус по типу RAFT или PoW
— CRDT
— Центральный координатор транзакций

Ничего этого в тарантуле вроде как нет, отсюда и мой интерес.
Как это будет разруливаться?

В целом «координатор игры» уже есть, можно пропускать все «опасные» операции через него. В этом случае игрок должен по netbox протоколу отправить свои пожелания и подождать получиться ли их исполнить координатору. В текущем варианте игры это не разруливается — минус возможен.


Непонятно как версионирование должно работать в среде master-master.

Такое решение было сделано на уровне апп серверов. Сохранение данных происходило на только один сервер в репликасете.


Sticky session, есть выделенные сервер (возможно с hot standby)

В этом случае изнутри Tarantool вам доступна топология, можно организовать свой код таким образом, чтобы отправлять транзакции на выделенный сервер (у которого будет в том числе локальный hot standby).


Консенсус по типу RAFT или PoW

Доступно в Tarantool >= 2.6.1


CRDT

На уровне движка хранения в Tarantool принцип Commutative Replicated Data Type.
Конкретно в игре из статьи используется Op-based счётчик.
Мы также можем создать Регистр Last-Write-Wins, в этом случае стоит дополнять данные timestamp-ами и в триггере выбирать last объект.
Растущее множество можно представить как просто таблицу, над которой нельзя проводить операцию remove.
LWW-element Set можно представить как две таблицы с генерацией timestamp для операций над объектами.


Центральный координатор транзакций

Реализовывался поверх Tarantool в одном из проектов, но не мной, прокомментировать не могу.

Как это будет разруливаться?

В случае игры, это не разруливается — минус возможен. В целом «координатор игры» уже есть, можно пропускать все «опасные» операции через него. В этом случае игрок должен по netbox протоколу отправить свои пожелания и подождать получиться ли их исполнить координатору.

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