[NoSQL, Администрирование баз данных, Tarantool] Tarantool vs Redis: что умеют in-memory технологии
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В этой статье я хочу сравнить Redis и Tarantool. У меня нет цели сделать громогласный вывод «Tarantool лучше!» или «Redis круче!». Я хочу понять их сходства и отличия, разобраться, для каких задач какую технологию выбрать. Потому что это очень близкие на первый взгляд вещи, и вопросы про их отличия я вижу часто.
Для этого мы посмотрим на технологии в трёх частях:
- Вначале посмотрим глазами новичка. Что такое БД в памяти? Какие задачи они решают лучше дисковых БД?
- Потом посмотрим архитектурно. Как обстоит вопрос с производительностью, надёжностью, масштабированием?
- В третьей части лезем в технические вещи поглубже. Типы данных, итераторы, индексы, транзакции, ЯП, репликация, коннекторы.
Смело переходите сразу к наиболее интересной вам части. Или даже сразу к итоговой табличке сравнения, которую я прикладываю в заключении.
Поехали!
Содержание
- Вводная часть
- Что такое БД в памяти
- Зачем нужны решения в памяти
- Что такое Redis
- Что такое Tarantool
- Архитектурная часть
- Производительность
- Надёжность
- Масштабируемость
- Валидация схемы данных
- Технические особенности
- Какие типы данных можно хранить
- Вытеснение данных
- Итерация по ключам
- Вторичные индексы
- Транзакции
- Персистентность
- Язык программирования для хранимых процедур
- Репликация
- Коннекторы из других языков программирования
- Под какие задачи плохо подходят
- Экосистема
- Чем Redis лучше
- Чем Tarantool лучше
- Вывод
- Ссылки
1. Вводная часть
Что такое БД в памяти
Redis и Tarantool — это in-memory технологии. Их ещё называют «резидентными БД», но я буду писать короче — «в памяти» или in-memory. Так что такое БД в памяти?
Это база, которая весь объём данных хранит целиком в оперативной памяти. Размер такой базы лимитирован ёмкостью оперативной памяти узла, что может ограничивать нас в количестве данных, но увеличивает скорость на порядок.
Если данных слишком много, БД в памяти способны сохранять данные на диск. Можно перезагрузить узел и не потерять информацию. Стереотип про ненадёжность БД в памяти сильно устарел, их можно использовать как основное хранилище в production. Например, Mail.ru Cloud Solutions использует Tarantool как основную БД для хранения метаинформации в своём объектном хранилище [1].
БД в памяти нужны для высокой скорости доступа к данным, условно от 10 000 запросов в секунду. Например, запросы к ленте новостей Кинопоиска в день релиза Снайдерката «Лиги Справедливости», Яндекс.Маркет перед Новым Годом или Delivery Club вечером в пятницу.
Зачем нужны решения в памяти
Кеш. БД в памяти традиционно используют как кеш для более медленных баз данных. Это логично, память быстрее диска (даже SSD). Но в жизненном цикле любого кеша случаются перезагрузки, падения, сетевая недоступность, нехватка памяти и прочие инфраструктурные беды.
С течением времени кеши стали уметь в персистентность, резервирование и шардирование.
- Персистентность — кеши сохраняют данные на диск. После перезагрузки восстанавливаем своё состояние без обращений к основному хранилищу. Если этого не делать, то обращение к холодному кешу будет очень долгим или даже положит основную БД.
- Резервирование — кеши содержат функции репликации данных. Если упал один узел, то второй возьмёт на себя запросы. Основное хранилище не упадёт от перегруза, нас спасает резервная нода.
- Шардирование — если горячие данные не помещаются в оперативную память одного узла, мы используем несколько узлов параллельно. Это горизонтальное масштабирование.
Шардирование — это большая система. Резервирование — это надёжная система. Вместе с персистентностью получается кластерное хранилище данных. Можно положить туда терабайты информации и крутить их на скорости 1 000 000 RPS.
OLTP. Расшифровывается как Online Transaction Processing, обработка транзакций в реальном времени. In-memory решения подходят для такого типа задач благодаря своей архитектуре. OLTP — это большое количество коротких on-line транзакций (INSERT, UPDATE, DELETE). Главное в OLTP-системах — быстро обработать запросы и обеспечить целостность данных. Эффективность чаще всего определяется количеством RPS.
Что такое Redis
- Redis называет себя «in-memory хранилище структур данных».
- Redis — это key-value.
- Больше всего известен по кешированию дисковых баз. Если вы будете искать по ключевым словам «кеширование баз данных», то в каждой статье найдёте упоминания Redis.
- Redis поддерживает первичные индексы, не поддерживает вторичные.
- Redis содержит в себе механизм хранимых процедур на Lua.
Что такое Tarantool
- Tarantool называет себя «платформа для in-memory вычислений».
- Tarantool умеет в key-value. А еще в документы и реляционную модель данных.
- Создан для горячих данных — кеширования MySQL в соцсети. С течением времени развился в полноценную базу данных.
- Tarantool может строить произвольное количество индексов по данным.
- В Tarantool тоже можно написать хранимую процедуру и тоже на Lua.
Разобрались с основами, давайте переходить на следующий уровень.
2. Архитектурная часть
Производительность
Это самый любимый запрос про БД в памяти — а насколько вы быстрые? «Сколько миллионов РПС можно снять с одного ядра?» Проведём простой синтетический тест, в нём максимально приблизим настройки баз данных. Скрипт на Go наполняет хранилище случайными ключами со случайными значениями.
MacBook Pro 2,9 GHz Quad-Core Intel Core i7
Redis version=6.0.9, bits=64
Tarantool 2.6.2
Redis
redis_test.go
package main
import (
"context"
"fmt"
"log"
"math/rand"
"testing"
"github.com/go-redis/redis"
)
func BenchmarkSetRandomRedisParallel(b *testing.B) {
client2 := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379", Password: "", DB: 0})
if _, err := client2.Ping(context.Background()).Result(); err != nil {
log.Fatal(err)
}
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
key := fmt.Sprintf("bench-%d", rand.Int31())
_, err := client2.Set(context.Background(), key, rand.Int31(), 0).Result()
if err != nil {
b.Fatal(err)
}
}
})
}
Tarantool
tarantool>
box.cfg{listen='127.0.0.1:3301', wal_mode='none', memtx_memory=2*1024*1024*1024}
box.schema.user.grant('guest', 'super', nil, nil, {if_not_exists=true,})
box.schema.space.create('kv', {if_not_exists=true,})
box.space.kv:create_index('pkey', {type='TREE', parts={{field=1, type='str'}},
if_not_exists=true,})
tarantool_test.go
package main
import (
"fmt"
"math/rand"
"testing"
"github.com/tarantool/go-tarantool"
)
type Tuple struct {
_msgpack struct{} `msgpack:",asArray"`
Key string
Value int32
}
func BenchmarkSetRandomTntParallel(b *testing.B) {
opts := tarantool.Opts{
User: "guest",
}
pconn2, err := tarantool.Connect("127.0.0.1:3301", opts)
if err != nil {
b.Fatal(err)
}
b.RunParallel(func(pb *testing.PB) {
var tuple Tuple
for pb.Next() {
tuple.Key = fmt.Sprintf("bench-%d", rand.Int31())
tuple.Value = rand.Int31()
_, err := pconn2.Replace("kv", tuple)
if err != nil {
b.Fatal(err)
}
}
})
}
Запуск/ Чтобы полностью прогрузить базы данных, используем больше потоков.
go test -cpu 12 -test.bench . -test.benchtime 10s
goos: darwin
goarch: amd64
BenchmarkSetRandomRedisParallel-12 929368 15839 ns/op
BenchmarkSetRandomTntParallel-12 972978 12749 ns/op
Результаты. Среднее время запроса к Redis составило 15 микросекунд, к Tarantool — 12 микросекунд. Это даёт Redis 63 135 RPS, Tarantool — 78 437 RPS.
Тест нужен, чтобы показать уровень производительности БД в памяти, а не для замера, кто быстрее. Каждый из вас может измерить так, что быстрее окажется нужный вариант, я это тоже понимаю.
Надёжность
Для надёжности хранения данных используют две основные техники:
- Персистентность. При перезагрузке БД загрузит свои данные с диска, не будет запросов в сторонние системы.
- Репликация. Если упал один узел, то есть копия на втором. Бывает асинхронная и синхронная.
И Redis, и Tarantool содержат эти функции. Технические подробности мы рассмотрим далее.
Масштабируемость
Масштабирование может рассматриваться для двух задач:
- Зарезервировать дополнительные узлы, которые могут заменять друг друга в случае, если сосед вышел из строя.
- Данные не помещаются на один узел, и их необходимо распределить на несколько.
Redis
Узлы Redis можно соединить друг с другом асинхронной репликацией. Такие узлы будем называть репликационной группой, или replica set. Управлением такой репликационной группой занимается Redis Sentinel.
Redis Sentinel — это один или несколько объединенных в кластер специальных процессов, которые следят за узлами Redis. Они выполняют четыре основные задачи:
- Мониторинг узлов в группе: живой или мертвый.
- Уведомление администратора или какой-то системы, если что-то случилось в группе.
- Автоматическое переключение мастера.
- Провайдер конфигурации для внешних клиентов, чтобы они знали, к кому подключиться.
В случае, когда данные необходимо расшардировать на несколько узлов, Redis предлагает open source-версию Redis Cluster. Она позволяет построить кластер, состоящий из нескольких репликационных групп. Данные в кластере шардируются по 16 384 слотам. Диапазоны слотов распределяются между узлами Redis.
Узлы в кластере общаются по отдельному открытому порту, чтобы понимать состояния соседей. Приложение при работе с Redis Cluster должно использовать специальный коннектор.
Tarantool
Tarantool также содержит в себе оба механизма масштабирования: персистентность и репликацию. Основной инструмент управления масштабированием — Tarantool Cartridge. Он объединяет узлы в репликационные группы. В этой ситуации вы можете построить одну такую репликационную группу и использовать её аналогично Redis Sentinel. Tarantool Cartridge может управлять несколькими репликационными группами и шардировать данные между ними. Шардирование выполняется с помощью библиотеки vshard.
Различия
Администрирование
- Администрирование Redis Cluster — с помощью скриптов и команд.
- В Tarantool Cartridge администрирование — с помощью web-интерфейса или через API.
Корзины шардирования
- Количество корзин шардирования в Redis фиксированное, 16 тыс.
- Количество корзин шардирования Tarantool Cartridge (vshard) произвольное. Указывается один раз при создании кластера.
Ребалансировка корзин (решардинг)
- В Redis Cluster настройка и запуск вручную.
- В Tarantool Cartridge (vshard) — автоматически.
Маршрутизация запросов
- Маршрутизация запросов в Redis Cluster происходит на стороне клиентского приложения.
- В Tarantool Cartridge маршрутизация запросов происходит на узлах-роутерах кластера.
Инфраструктура
- Tarantool Cartridge также содержит:
Валидация схемы данных
В Redis основная схема данных — ключ-значение. Но в значениях могут быть разные структуры. На стороне сервера нет механизма для задания правил. Мы не можем указать, в каком ключе какой тип данных должен использоваться и какая именно структура должна быть у значения. Валидацией схемы должен заниматься или коннектор, или клиентское приложение.
В Tarantool на стороне сервера можно использовать валидацию по схеме данных:
- с помощью встроенной валидации box.space.format, которая затрагивает только верхний уровень полей;
- с помощью установленного расширения avro-schema.
3. Технические особенности
Какие типы данных можно хранить
В Redis ключом может быть только строка. В Redis можно хранить и манипулировать следующими типами данных:
- строки;
- списки строк;
- неупорядоченные множества строк;
- хешмапы или просто строковые пары ключ-значение;
- упорядоченные множества строк;
- Bitmap и HyperLogLog.
В Tarantool можно хранить и манипулировать следующими типами данных:
- Атомарными:
- строки;
- логический тип (истина, ложь);
- целочисленный;
- с плавающей запятой;
- с десятичной плавающей запятой;
- UUID.
- Комплексными:
- массивы;
- хешмапы.
Типы данных Redis лучше подходят для счётчиков событий, в том числе уникальных, для хранения небольших готовых витрин данных. А типы данных Tarantool лучше подходят для хранения объектов и/или документов, как в SQL и NoSQL СУБД.
Вытеснение данных
Redis и Tarantool содержат в себе механизм ограничения занимаемой памяти. Когда клиент попытается добавить ещё, базы ответят ошибкой.
Перейдём к другому механизму, когда мы можем настроить алгоритм удаления «больше ненужных» данных. Redis содержит в себе несколько механизмов вытеснения:
- TTL — вытеснение объектов по завершении срока жизни;
- LRU — вытеснение давно использованных данных;
- RANDOM — вытеснение случайно попавшихся под руку объектов;
- LFU — вытеснение редко используемых данных.
Все механизмы могут быть настроены либо на весь объем данных, либо только на те объекты, которые помечены как вытесняемые.
В Tarantool для вытеснения данных можно использовать расширения expirationd или indexpiration, или создать собственную фоновую процедуру, которая будет проходить по вторичному индексу (с таймштампом) и удалять ненужные данные.
Итерация по ключам
В Redis можно это сделать с помощью операторов:
- SCAN;
- итерация по ключам.
Операции возвращают страницы с результатами. Для получения каждой новой страницы, необходимо передать «идентификатор» предыдущей. Операции поддерживают фильтрацию по шаблону. Для этого используется параметр MATCH. Фильтрация происходит на момент выдачи страницы, поэтому некоторые страницы могут оказаться пустыми. Это не будет означать, что страниц больше не осталось.
В Tarantool доступна гибкая схема итерации по ключам. Можно итерироваться в прямом и обратном направлении. В процессе можно дополнительно фильтровать значения. Можно сместиться на определённое значение ключа, затем проходить по следующим ключам в сторону возрастания или убывания. Направление прохода на лету менять нельзя.
Например:
results = {}
for _, tuple in box.space.pairs('key', 'GE') do
if tuple['value'] > 10 then
table.insert(results, tuple)
end
end
return results
Вторичные индексы
Redis
У Redis нет вторичных индексов. Есть некоторые трюки, чтобы их имитировать:
- В упорядоченных множествах можно использовать порядковый номер элемента как вторичный ключ.
- Использовать хешмапы, ключ которых является, в некотором смысле, индексом данных.
Tarantool
В Tarantool можно строить произвольное количество вторичных индексов для данных:
- Вторичные ключи могут состоять из нескольких полей.
- Для вторичных индексов можно использовать типы HASH, TREE, RTREE, BITSET.
- Вторичные индексы могут содержать уникальные и не уникальные ключи.
- У любых индексов можно использовать настройки локали, например, для регистронезависимых строковых значений.
- Вторичные индексы могут строиться по полям с массивом значений (иногда их называют мультииндексы).
Вывод
Вторичные ключи и удобные итераторы позволяют строить в Tarantool реляционные модели хранения данных. В Redis такую модель построить невозможно.
Транзакции
Механизм транзакций позволяет выполнить несколько операций атомарно. И Redis, и Tarantool поддерживают транзакции. Пример транзакции в Redis:
> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
Пример транзакции в Tarantool:
do
box.begin()
box.space.kv:update('foo', {{'+', 'value', 1}})
box.space.kv:update('bar', {{'+', 'value', 1}})
box.commit()
end
Персистентность
Персистентность данных обеспечивается двумя механизмами:
- периодическим сбросом in-memory данных на диск — snapshoting;
- последовательной упреждающей записью всех приходящих операций в файл — transaction journal.
И Redis, и Tarantool содержат оба механизма персистентности.
Redis
Redis периодически сбрасывает все данные из памяти на диск. Происходит это по-умолчанию каждые 60 секунд (настраивается). Redis использует механизм ОС fork для «копирования» текущих данных в памяти, затем информация сохраняется на диск. Если происходит аварийное завершение, то Redis восстановит состояние из последнего сохранения. Если последний снапшот был сделан давно, то данные, пришедшие после снапшота, будут утеряны.
Журнал операций используется для сохранения всей приходящей в базу информации. Каждая операция сохраняется в журнал на диске. Так, при запуске Redis восстанавливает своё состояние из снапшота и затем донакатывает оставшиеся транзакции из журнала.
- Снапшот в Redis называется RDB (redis database).
- Журнал операций в Redis называется AOF (append only file).
Tarantool
- Механизм персистентности взят из архитектур баз данных.
- Он является целостным — снапшоты и журналирование.
- Этот же механизм позволяет существовать надежной WAL-based репликации.
Tarantool периодически сохраняет текущие in-memory данные на диск и записывает каждую операцию в журнал.
- Снапшот в Tarantool называется snap (snapshot). Можно делать с произвольной частотой.
- Журнал транзакций в Tarantool называется WAL (write ahead log).
И в Redis. и в Tarantool каждый из механизмов может быть выключен. Для надёжного хранения данных оба механизма надо включить. Для максимального быстродействия можно отключить снапшотинг и журналирование, заплатив персистентностью. Слабоумие и отвага!
Различия
Для снапшотинга в Redis используется механизм ОС fork. Tarantool использует внутренний readview всех данных, это работает быстрее чем fork.
В Redis по умолчанию включён только снапшотинг. В Tarantool включён снапшотинг и журнал.
Redis хранит и использует только по одному файлу для снапшотов и журнала операций. Tarantool по-умолчанию хранит два файла снапшотов (можно настроить и больше) и консистентно дополняющее неограниченное количество журналов операций. При повреждении снапшот-файла Tarantool сможет загрузиться из предыдущего. Для Redis необходимо наладить механизм бекапов.
В Tarantool, в отличие от Redis, снапшоты и журналы образуют единый механизм отображения данных в файловой системе. Это значит, что в Tarantool и в файлах снапшотов и в журналах хранится полная метаинформация о транзакции, кто её сделал и когда. Она одного формата и взаимодополняющая.
Troubleshooting
Если повреждён файл журнала в Redis:
redis-check-aof --fix
Если повреждён файл журнала в Tarantool:
tarantool> box.cfg{force_recovery=true}
Язык программирования для хранимых процедур
Хранимые процедуры — это код, выполняющийся рядом с данными. И Redis, и Tarantool предлагают Lua для создания хранимок. С точки зрения пользователя это очень простой язык. Он создавался для людей, для которых программирование будет инструментом решения задач в предметной области.
C точки зрения разработчика базы данных:
- Lua — это язык, который легко встраивается в существующее приложение.
- Он просто интегрируется с объектами и процессами приложения.
- Lua имеет динамическую типизацию и автоматическое управление памятью.
- Язык имеет сборщик мусора incremental Mark&Sweep.
Различия
Реализация
- В Redis используется ванильная реализация PUC-Rio.
- В Tarantool используется LuaJIT.
Таймаут задач
- В Redis можно задать таймаут, после которого выполнение хранимой процедуры прервётся.
- В Tarantool хранимые процедуры компилируются и выполняются быстрее, но в этом механизме нет возможности выставить таймаут. Для прерывания хранимой процедуры пользователь должен предусмотреть механизм проверки флага прерывания.
Runtime
- В Redis используется однозадачность: задачи выполняются по одной и целиком.
- В Tarantool используется кооперативная многозадачность. Задачи выполняются по одной, но при этом задача отдаёт управление на операциях ввода-вывода или явно с помощью yield.
Вывод
- В Redis Lua — это просто хранимые процедуры.
- В Tarantool — это кооперативный runtime, в котором можно взаимодействовать со внешними системами.
Репликация
Репликация — это механизм копирования объектов с одного узла на другой. Бывает асинхронная и синхронная.
- Асинхронная репликация: при вставке объекта на один узел мы не дожидаемся, когда этот же объект будет отреплицирован на второй узел.
- Синхронная репликация: при вставке объекта мы дожидаемся, когда он будет сохранён на первом и втором узлах.
И Redis, и Tarantool поддерживают асинхронную репликацию. Только Tarantool умеет в синхронную репликацию.
На практике бывают ситуации, когда мы хотим дождаться репликации объекта. И в Redis, и в Tarantool есть способы для этого:
- В Redis это команда wait. Она принимает два параметра:
- сколько реплик должны получить объект;
- сколько ждать, пока это произойдёт.
- В Tarantool это можно сделать фрагментом кода:
псевдокод:
local netbox = require('net.box')
local replica = netbox.connect(...)
local replica_vclock, err = replica.eval([[
return box.info().vclock
]])
while not vclock_compare(box.info().vclock, replica_vclock) do
fiber.sleep(0.1)
end
Синхронная репликация
В Redis нет синхронной репликации. Начиная с Tarantool 2.6 синхронная репликация доступна [2].
Коннекторы из других языков программирования
И Redis, и Tarantool поддерживают коннекторы для популярных языков программирования:
- Go;
- Python;
- NodeJS;
- Java.
Полные списки:
Под какие задачи плохо подходят
И Redis, и Tarantool плохо подходят для решения OLAP-задач. Online analytical processing имеет дело с историческими или архивными данными. OLAP характеризуется относительно низким объёмом транзакций. Запросы часто очень сложны и включают агрегацию.
В обоих случаях данные хранятся построчно, и это снижает эффективность алгоритмов агрегации в сравнении с базами с колоночным хранением.
Redis и Tarantool — однопоточные базы данных, что не позволяет распараллелить аналитические запросы.
Экосистема
Redis
Модули Redis представлены в трёх категориях:
- Enterprise;
- проверенные и сертифицированные для Enterprise и Open source;
- непроверенные.
Enterprise-модули:
- полнотекстовый поиск;
- хранение и поиск по bloom-фильтрам;
- хранение временных рядов.
Сертифицированные:
- хранение графов и запросы к ним;
- хранение JSON и запросы к нему;
- хранение и работа с моделями машинного обучения.
Все модули, отсортированные по количеству звёзд на Github:https://redis.io/modules
Tarantool
Модули представлены в двух категориях:
- Встроенные: https://www.tarantool.io/en/doc/latest/reference/
- Enterprise: https://www.tarantool.io/en/enterprise_doc/rocksref/#closed-source-modules
Чем Redis лучше
- Проще.
- В интернете представлено больше информации, 20 тыс. вопросов на Stackoverflow (из них 7 тыс. без ответов).
- Ниже порог входа.
- Как следствие, проще найти людей, которые умеют работать с Redis.
Чем Tarantool лучше
- Русскоязычная бесплатная поддержка в Telegram от разработчиков.
- Есть вторичные индексы.
- Есть итерация по индексу.
- Есть UI для администрирования кластера.
- Предлагает механику сервера приложений с кооперативной многозадачностью. Эта механика похожа на однопоточный Go.
4. Вывод
Redis — это классный продвинутый кеш, но его нельзя брать как основное хранилище. Tarantool — это мультипарадигменная база данных, можно брать как основное хранилище. Tarantool поддерживает:
- Реляционную модель хранения с SQL.
- Распределённое NoSQL-хранилище.
- Создание продвинутых кешей.
- Создание брокера очередей.
У Redis ниже порог входа. У Tarantool выше потолок в production.
Сравнение одной таблицей:
Redis
Tarantool
Описание
Продвинутый кэш в памяти.
Мультипарадигменная СУБД с сервером приложений.
Модель данных
Key-value
Key-value, документы, реляционная
Сайт
redis.io
www.tarantool.io
Документация
redis.io/%C2%ADdocumentation
www.tarantool.io/ru/doc/latest
Разработчик
Salvatore Sanfilippo, Redis Labs
mail.ru Group
Текущий релиз
6.2
2.6
Лицензия
The 3-Clause BSD License
The 2-Clause BSD License
Язык реализации
C
C, C++
Поддерживаемые ОС
BSD, Linux, MacOS, Win
BSD, Linux, MacOS
Схема данных
Key-value
Гибкая
Вторичные индексы
Нет
Есть
Поддержка SQL
Нет
Для одного инстанса, ANSI SQL
Foreign keys
Нет
Есть, с помощью SQL
Триггеры
Нет
Есть
Транзакции
Оптимистичные блокировки, атомарное выполнение.
ACID, read commited
Масштабирование
Шардинг по фиксированному диапазону.
Шардинг по настраиваемому количеству виртуальных бакетов.
Многозадачность
Да, сериализация сервером.
Да, кооперативная многозадачность.
Персистентность
Снапшоты и журналирование.
Снапшоты и журналирование.
Концепция консистентности
Eventual ConsistencyStrong eventual consistency with CRDTs
Immediate Consistency
API
Проприетарный протокол.
Свой открытый бинарный протокол.
Язык скриптов
Lua
Lua
Поддерживаемые языки
C
C#, C++, Clojure, Crystal, D, Dart, Elixir, Erlang, Fancy, Go, Haskell, Haxe, Java, JavaScript (Node.js), Lisp, Lua, MatLab, Objective-C, OCaml, Pascal, Perl, PHP, Prolog, Pure Data, Python, R, Rebol, Ruby, Rust, Scala, Scheme, Smalltalk, Swift, Tcl, Visual Basic
C, C#, C++, Erlang, Go, Java, JavaScript, Lua, Perl, PHP, Python, Rust
5. Ссылки
- Архитектура S3: три года эволюции Mail.ru Cloud Storage
- Синхронная репликация в Tarantool
- Скачать Tarantool можно на официальном сайте, а получить помощь — в Telegram-чате.
===========
Источник:
habr.com
===========
Похожие новости:
- [Интерфейсы, Конференции, Дизайн игр] 7 апреля состоится онлайн-саммит TBD PRO про продуктовый дизайн в геймдеве
- [Разработка веб-сайтов, Тестирование IT-систем, PHP, Тестирование веб-сервисов] Юнит-тестирование на PHP в примерах (перевод)
- [Администрирование баз данных, Карьера в IT-индустрии, DevOps] Неотправленное письмо боссу в кровавом Enterprise
- [Разработка под iOS, Разработка мобильных приложений, Интерфейсы] Compositional Layout: стоит ли игра свеч?
- [Облачные вычисления, Разработка под e-commerce, Управление e-commerce, Облачные сервисы] Вебинар «Технологии, которые позволяют E-commerce опередить конкурентов» 6 апреля
- [] ИТ-амбассадор — на шаг ближе к профессии
- [Ненормальное программирование, SQL, PowerShell, Microsoft SQL Server, Администрирование баз данных] Email Chart — это вам не ASCII Art
- [Oracle, PostgreSQL, Администрирование баз данных, ERP-системы] Хватит это терпеть: как мы обновили архитектуру системы мониторинга автотранспорта на 15 000 машин и 17 000 магазинов
- [Java, Администрирование баз данных, DevOps] Версионирование структуры БД при помощи Liquibase
- [Высокая производительность, PostgreSQL, SQL, Администрирование баз данных] DBA: Когда почти закончился serial
Теги для поиска: #_nosql, #_administrirovanie_baz_dannyh (Администрирование баз данных), #_tarantool, #_redis, #_tarantool, #_nosql, #_blog_kompanii_mail.ru_group (
Блог компании Mail.ru Group
), #_nosql, #_administrirovanie_baz_dannyh (
Администрирование баз данных
), #_tarantool
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:15
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В этой статье я хочу сравнить Redis и Tarantool. У меня нет цели сделать громогласный вывод «Tarantool лучше!» или «Redis круче!». Я хочу понять их сходства и отличия, разобраться, для каких задач какую технологию выбрать. Потому что это очень близкие на первый взгляд вещи, и вопросы про их отличия я вижу часто. Для этого мы посмотрим на технологии в трёх частях:
Смело переходите сразу к наиболее интересной вам части. Или даже сразу к итоговой табличке сравнения, которую я прикладываю в заключении. Поехали! Содержание
1. Вводная часть Что такое БД в памяти Redis и Tarantool — это in-memory технологии. Их ещё называют «резидентными БД», но я буду писать короче — «в памяти» или in-memory. Так что такое БД в памяти? Это база, которая весь объём данных хранит целиком в оперативной памяти. Размер такой базы лимитирован ёмкостью оперативной памяти узла, что может ограничивать нас в количестве данных, но увеличивает скорость на порядок. Если данных слишком много, БД в памяти способны сохранять данные на диск. Можно перезагрузить узел и не потерять информацию. Стереотип про ненадёжность БД в памяти сильно устарел, их можно использовать как основное хранилище в production. Например, Mail.ru Cloud Solutions использует Tarantool как основную БД для хранения метаинформации в своём объектном хранилище [1]. БД в памяти нужны для высокой скорости доступа к данным, условно от 10 000 запросов в секунду. Например, запросы к ленте новостей Кинопоиска в день релиза Снайдерката «Лиги Справедливости», Яндекс.Маркет перед Новым Годом или Delivery Club вечером в пятницу. Зачем нужны решения в памяти Кеш. БД в памяти традиционно используют как кеш для более медленных баз данных. Это логично, память быстрее диска (даже SSD). Но в жизненном цикле любого кеша случаются перезагрузки, падения, сетевая недоступность, нехватка памяти и прочие инфраструктурные беды. С течением времени кеши стали уметь в персистентность, резервирование и шардирование.
Шардирование — это большая система. Резервирование — это надёжная система. Вместе с персистентностью получается кластерное хранилище данных. Можно положить туда терабайты информации и крутить их на скорости 1 000 000 RPS. OLTP. Расшифровывается как Online Transaction Processing, обработка транзакций в реальном времени. In-memory решения подходят для такого типа задач благодаря своей архитектуре. OLTP — это большое количество коротких on-line транзакций (INSERT, UPDATE, DELETE). Главное в OLTP-системах — быстро обработать запросы и обеспечить целостность данных. Эффективность чаще всего определяется количеством RPS. Что такое Redis
Что такое Tarantool
Разобрались с основами, давайте переходить на следующий уровень. 2. Архитектурная часть Производительность Это самый любимый запрос про БД в памяти — а насколько вы быстрые? «Сколько миллионов РПС можно снять с одного ядра?» Проведём простой синтетический тест, в нём максимально приблизим настройки баз данных. Скрипт на Go наполняет хранилище случайными ключами со случайными значениями. MacBook Pro 2,9 GHz Quad-Core Intel Core i7
Redis version=6.0.9, bits=64 Tarantool 2.6.2 Redis redis_test.go
package main import ( "context" "fmt" "log" "math/rand" "testing" "github.com/go-redis/redis" ) func BenchmarkSetRandomRedisParallel(b *testing.B) { client2 := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379", Password: "", DB: 0}) if _, err := client2.Ping(context.Background()).Result(); err != nil { log.Fatal(err) } b.RunParallel(func(pb *testing.PB) { for pb.Next() { key := fmt.Sprintf("bench-%d", rand.Int31()) _, err := client2.Set(context.Background(), key, rand.Int31(), 0).Result() if err != nil { b.Fatal(err) } } }) } Tarantool tarantool>
box.cfg{listen='127.0.0.1:3301', wal_mode='none', memtx_memory=2*1024*1024*1024} box.schema.user.grant('guest', 'super', nil, nil, {if_not_exists=true,}) box.schema.space.create('kv', {if_not_exists=true,}) box.space.kv:create_index('pkey', {type='TREE', parts={{field=1, type='str'}}, if_not_exists=true,}) tarantool_test.go
package main import ( "fmt" "math/rand" "testing" "github.com/tarantool/go-tarantool" ) type Tuple struct { _msgpack struct{} `msgpack:",asArray"` Key string Value int32 } func BenchmarkSetRandomTntParallel(b *testing.B) { opts := tarantool.Opts{ User: "guest", } pconn2, err := tarantool.Connect("127.0.0.1:3301", opts) if err != nil { b.Fatal(err) } b.RunParallel(func(pb *testing.PB) { var tuple Tuple for pb.Next() { tuple.Key = fmt.Sprintf("bench-%d", rand.Int31()) tuple.Value = rand.Int31() _, err := pconn2.Replace("kv", tuple) if err != nil { b.Fatal(err) } } }) } Запуск/ Чтобы полностью прогрузить базы данных, используем больше потоков. go test -cpu 12 -test.bench . -test.benchtime 10s
goos: darwin goarch: amd64 BenchmarkSetRandomRedisParallel-12 929368 15839 ns/op BenchmarkSetRandomTntParallel-12 972978 12749 ns/op Результаты. Среднее время запроса к Redis составило 15 микросекунд, к Tarantool — 12 микросекунд. Это даёт Redis 63 135 RPS, Tarantool — 78 437 RPS. Тест нужен, чтобы показать уровень производительности БД в памяти, а не для замера, кто быстрее. Каждый из вас может измерить так, что быстрее окажется нужный вариант, я это тоже понимаю. Надёжность Для надёжности хранения данных используют две основные техники:
И Redis, и Tarantool содержат эти функции. Технические подробности мы рассмотрим далее. Масштабируемость Масштабирование может рассматриваться для двух задач:
Redis Узлы Redis можно соединить друг с другом асинхронной репликацией. Такие узлы будем называть репликационной группой, или replica set. Управлением такой репликационной группой занимается Redis Sentinel. Redis Sentinel — это один или несколько объединенных в кластер специальных процессов, которые следят за узлами Redis. Они выполняют четыре основные задачи:
В случае, когда данные необходимо расшардировать на несколько узлов, Redis предлагает open source-версию Redis Cluster. Она позволяет построить кластер, состоящий из нескольких репликационных групп. Данные в кластере шардируются по 16 384 слотам. Диапазоны слотов распределяются между узлами Redis. Узлы в кластере общаются по отдельному открытому порту, чтобы понимать состояния соседей. Приложение при работе с Redis Cluster должно использовать специальный коннектор. Tarantool Tarantool также содержит в себе оба механизма масштабирования: персистентность и репликацию. Основной инструмент управления масштабированием — Tarantool Cartridge. Он объединяет узлы в репликационные группы. В этой ситуации вы можете построить одну такую репликационную группу и использовать её аналогично Redis Sentinel. Tarantool Cartridge может управлять несколькими репликационными группами и шардировать данные между ними. Шардирование выполняется с помощью библиотеки vshard. Различия Администрирование
Корзины шардирования
Ребалансировка корзин (решардинг)
Маршрутизация запросов
Инфраструктура
Валидация схемы данных В Redis основная схема данных — ключ-значение. Но в значениях могут быть разные структуры. На стороне сервера нет механизма для задания правил. Мы не можем указать, в каком ключе какой тип данных должен использоваться и какая именно структура должна быть у значения. Валидацией схемы должен заниматься или коннектор, или клиентское приложение. В Tarantool на стороне сервера можно использовать валидацию по схеме данных:
3. Технические особенности Какие типы данных можно хранить В Redis ключом может быть только строка. В Redis можно хранить и манипулировать следующими типами данных:
В Tarantool можно хранить и манипулировать следующими типами данных:
Типы данных Redis лучше подходят для счётчиков событий, в том числе уникальных, для хранения небольших готовых витрин данных. А типы данных Tarantool лучше подходят для хранения объектов и/или документов, как в SQL и NoSQL СУБД. Вытеснение данных Redis и Tarantool содержат в себе механизм ограничения занимаемой памяти. Когда клиент попытается добавить ещё, базы ответят ошибкой. Перейдём к другому механизму, когда мы можем настроить алгоритм удаления «больше ненужных» данных. Redis содержит в себе несколько механизмов вытеснения:
Все механизмы могут быть настроены либо на весь объем данных, либо только на те объекты, которые помечены как вытесняемые. В Tarantool для вытеснения данных можно использовать расширения expirationd или indexpiration, или создать собственную фоновую процедуру, которая будет проходить по вторичному индексу (с таймштампом) и удалять ненужные данные. Итерация по ключам В Redis можно это сделать с помощью операторов:
Операции возвращают страницы с результатами. Для получения каждой новой страницы, необходимо передать «идентификатор» предыдущей. Операции поддерживают фильтрацию по шаблону. Для этого используется параметр MATCH. Фильтрация происходит на момент выдачи страницы, поэтому некоторые страницы могут оказаться пустыми. Это не будет означать, что страниц больше не осталось. В Tarantool доступна гибкая схема итерации по ключам. Можно итерироваться в прямом и обратном направлении. В процессе можно дополнительно фильтровать значения. Можно сместиться на определённое значение ключа, затем проходить по следующим ключам в сторону возрастания или убывания. Направление прохода на лету менять нельзя. Например: results = {}
for _, tuple in box.space.pairs('key', 'GE') do if tuple['value'] > 10 then table.insert(results, tuple) end end return results Вторичные индексы Redis У Redis нет вторичных индексов. Есть некоторые трюки, чтобы их имитировать:
Tarantool В Tarantool можно строить произвольное количество вторичных индексов для данных:
Вывод Вторичные ключи и удобные итераторы позволяют строить в Tarantool реляционные модели хранения данных. В Redis такую модель построить невозможно. Транзакции Механизм транзакций позволяет выполнить несколько операций атомарно. И Redis, и Tarantool поддерживают транзакции. Пример транзакции в Redis: > MULTI
OK > INCR foo QUEUED > INCR bar QUEUED > EXEC 1) (integer) 1 2) (integer) 1 Пример транзакции в Tarantool: do
box.begin() box.space.kv:update('foo', {{'+', 'value', 1}}) box.space.kv:update('bar', {{'+', 'value', 1}}) box.commit() end Персистентность Персистентность данных обеспечивается двумя механизмами:
И Redis, и Tarantool содержат оба механизма персистентности. Redis Redis периодически сбрасывает все данные из памяти на диск. Происходит это по-умолчанию каждые 60 секунд (настраивается). Redis использует механизм ОС fork для «копирования» текущих данных в памяти, затем информация сохраняется на диск. Если происходит аварийное завершение, то Redis восстановит состояние из последнего сохранения. Если последний снапшот был сделан давно, то данные, пришедшие после снапшота, будут утеряны. Журнал операций используется для сохранения всей приходящей в базу информации. Каждая операция сохраняется в журнал на диске. Так, при запуске Redis восстанавливает своё состояние из снапшота и затем донакатывает оставшиеся транзакции из журнала.
Tarantool
Tarantool периодически сохраняет текущие in-memory данные на диск и записывает каждую операцию в журнал.
И в Redis. и в Tarantool каждый из механизмов может быть выключен. Для надёжного хранения данных оба механизма надо включить. Для максимального быстродействия можно отключить снапшотинг и журналирование, заплатив персистентностью. Слабоумие и отвага! Различия Для снапшотинга в Redis используется механизм ОС fork. Tarantool использует внутренний readview всех данных, это работает быстрее чем fork. В Redis по умолчанию включён только снапшотинг. В Tarantool включён снапшотинг и журнал. Redis хранит и использует только по одному файлу для снапшотов и журнала операций. Tarantool по-умолчанию хранит два файла снапшотов (можно настроить и больше) и консистентно дополняющее неограниченное количество журналов операций. При повреждении снапшот-файла Tarantool сможет загрузиться из предыдущего. Для Redis необходимо наладить механизм бекапов. В Tarantool, в отличие от Redis, снапшоты и журналы образуют единый механизм отображения данных в файловой системе. Это значит, что в Tarantool и в файлах снапшотов и в журналах хранится полная метаинформация о транзакции, кто её сделал и когда. Она одного формата и взаимодополняющая. Troubleshooting Если повреждён файл журнала в Redis: redis-check-aof --fix
Если повреждён файл журнала в Tarantool: tarantool> box.cfg{force_recovery=true}
Язык программирования для хранимых процедур Хранимые процедуры — это код, выполняющийся рядом с данными. И Redis, и Tarantool предлагают Lua для создания хранимок. С точки зрения пользователя это очень простой язык. Он создавался для людей, для которых программирование будет инструментом решения задач в предметной области. C точки зрения разработчика базы данных:
Различия Реализация
Таймаут задач
Runtime
Вывод
Репликация Репликация — это механизм копирования объектов с одного узла на другой. Бывает асинхронная и синхронная.
И Redis, и Tarantool поддерживают асинхронную репликацию. Только Tarantool умеет в синхронную репликацию. На практике бывают ситуации, когда мы хотим дождаться репликации объекта. И в Redis, и в Tarantool есть способы для этого:
псевдокод: local netbox = require('net.box')
local replica = netbox.connect(...) local replica_vclock, err = replica.eval([[ return box.info().vclock ]]) while not vclock_compare(box.info().vclock, replica_vclock) do fiber.sleep(0.1) end Синхронная репликация В Redis нет синхронной репликации. Начиная с Tarantool 2.6 синхронная репликация доступна [2]. Коннекторы из других языков программирования И Redis, и Tarantool поддерживают коннекторы для популярных языков программирования:
Полные списки: Под какие задачи плохо подходят И Redis, и Tarantool плохо подходят для решения OLAP-задач. Online analytical processing имеет дело с историческими или архивными данными. OLAP характеризуется относительно низким объёмом транзакций. Запросы часто очень сложны и включают агрегацию. В обоих случаях данные хранятся построчно, и это снижает эффективность алгоритмов агрегации в сравнении с базами с колоночным хранением. Redis и Tarantool — однопоточные базы данных, что не позволяет распараллелить аналитические запросы. Экосистема Redis Модули Redis представлены в трёх категориях:
Enterprise-модули:
Сертифицированные:
Все модули, отсортированные по количеству звёзд на Github:https://redis.io/modules Tarantool Модули представлены в двух категориях:
Чем Redis лучше
Чем Tarantool лучше
4. Вывод Redis — это классный продвинутый кеш, но его нельзя брать как основное хранилище. Tarantool — это мультипарадигменная база данных, можно брать как основное хранилище. Tarantool поддерживает:
У Redis ниже порог входа. У Tarantool выше потолок в production. Сравнение одной таблицей: Redis Tarantool Описание Продвинутый кэш в памяти. Мультипарадигменная СУБД с сервером приложений. Модель данных Key-value Key-value, документы, реляционная Сайт redis.io www.tarantool.io Документация redis.io/%C2%ADdocumentation www.tarantool.io/ru/doc/latest Разработчик Salvatore Sanfilippo, Redis Labs mail.ru Group Текущий релиз 6.2 2.6 Лицензия The 3-Clause BSD License The 2-Clause BSD License Язык реализации C C, C++ Поддерживаемые ОС BSD, Linux, MacOS, Win BSD, Linux, MacOS Схема данных Key-value Гибкая Вторичные индексы Нет Есть Поддержка SQL Нет Для одного инстанса, ANSI SQL Foreign keys Нет Есть, с помощью SQL Триггеры Нет Есть Транзакции Оптимистичные блокировки, атомарное выполнение. ACID, read commited Масштабирование Шардинг по фиксированному диапазону. Шардинг по настраиваемому количеству виртуальных бакетов. Многозадачность Да, сериализация сервером. Да, кооперативная многозадачность. Персистентность Снапшоты и журналирование. Снапшоты и журналирование. Концепция консистентности Eventual ConsistencyStrong eventual consistency with CRDTs Immediate Consistency API Проприетарный протокол. Свой открытый бинарный протокол. Язык скриптов Lua Lua Поддерживаемые языки C C#, C++, Clojure, Crystal, D, Dart, Elixir, Erlang, Fancy, Go, Haskell, Haxe, Java, JavaScript (Node.js), Lisp, Lua, MatLab, Objective-C, OCaml, Pascal, Perl, PHP, Prolog, Pure Data, Python, R, Rebol, Ruby, Rust, Scala, Scheme, Smalltalk, Swift, Tcl, Visual Basic C, C#, C++, Erlang, Go, Java, JavaScript, Lua, Perl, PHP, Python, Rust 5. Ссылки
=========== Источник: habr.com =========== Похожие новости:
Блог компании Mail.ru Group ), #_nosql, #_administrirovanie_baz_dannyh ( Администрирование баз данных ), #_tarantool |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:15
Часовой пояс: UTC + 5