Привет, %хабраюзер%. Команда Тарантула продолжает делиться инсайтами и экспертизой для эффективной работы с данными в высоконагруженных проектах. Сегодня мы попытаемся разобраться, почему же Tarantool — это «два в одном»: не только база данных, но и сервер приложений. Наверное, некоторые слышали о Тарантуле как о сверхбыстром персистентном in-memory хранилище с поддержкой репликации и хранимок на Lua. Представьте, что мы берём кусочки Redis, добавляем замороженный Node.js, сверху заправляем Go, после чего варим, медленно перемешивая, в течение пяти минут после закипания. Казалось бы, при чём здесь Application Server?



Многие, наверное, будут удивлены, но такие отличные продукты, как nginx, Go, Node.js, Redis, MongoDB, Tarantool и др., имеют много общего в архитектурном плане. Для создания любого высокопроизводительного сетевого сервера так или иначе требуется набор библиотек, обеспечивающий неблокирующий ввод-вывод, асинхронную обработку событий, работу с памятью, обработку ошибок, логирование, демонизацию и т. п. и т. д. Данный движок (runtime) обычно представляет собой достаточно сложную штуку, требующую глубокого понимания основ работы различных систем и навыков низкоуровневого программирования.

Мы в команде Tarantool прошли очень длинный путь, создав свой runtime с асинхронной обработкой событий, неблокирующими I/O, зелёными тредами в user-space (файберами), кооперативной многозадачностью, семейством специализированных аллокаторов памяти и пр., и пр. Получилось что-то архитектурно больше всего похожее на Go (у глупцов мысли совпадают), но только в виде библиотек для чистого C. Благодаря данной основе «под капотом» удалось создать СУБД, которая сегодня способна обрабатывать до 6M запросов в секунду на одном ядре рядового ноутбука и имеет лучший memory footprint на рынке. В какой-то момент мы решили дать неограниченную свободу разработчикам приложений, разрешив в хранимых процедурах делать не только запросы к базе, но и использовать весь наш инструментарий по полной программе. Получить и распарсить JSON’чик по HTTP с облачного сервиса прямо из базы данных — легко. Запустить свой REST-сервис прямо в СУБД — пожалуйста. Сходить за данными на десяток серверов, параллельно обрабатывая запросы, — без проблем! Все возможности и инструменты в руки разработчиков! Developers, developers, developers!

Как же в Tarantool сделать X, Y, Z?




Наc очень часто спрашивают, есть ли в Tarantool очереди, expiration данных, pub/sub, multiget или ещё что-нибудь из сотен команд Redis’а. Нет, в Tarantool ничего этого нет, не было и не будет (сорян, котаны). Мы отказались от подобного пути и предлагаем немного другой подход. Как известно, дай человеку рыбу, и он будет сыт один день, научи его ловить рыбу, и он будет сыт всегда. Tarantool предоставляет инструменты («удочку»), с помощью которых можно решать различные задачи, в том числе и выходящие из разряда шаблонов и паттернов. Автоматическое удаление старых данных — фоновый файбер на Lua. Multiget из нескольких таблиц по определённому условию — две строчки Lua. Отдача данных в формате JSON — загрузить модуль веб-сервера прямо в базу данных. Think out of the box!

Посмотрим, что же за инструменты предоставляет Tarantool:

  • fiber — кооперативная многозадачность и каналы (как в Go);
  • socket, fio — асинхронный неблокирующий сокетный и файловый ввод-вывод;
  • json/msgpack/yaml — упаковщики-распаковщики данных;
  • mysql/pg/whatever — клиенты к MySQL, PostgreSQL из самого Тарантула;
  • net.box — клиент к Тарантулу из самого Тарантула;
  • http — примитивный HTTP сервер и клиент;
  • tap — тестирование для приложений и модулей;
  • console — инспектирование состояния сервера, горячая загрузка кода, изменение настроек на лету;
  • log — логирование событий, logrotate;
  • init-скрипты, RPM/DEB-пакеты, средства развертывания и др.

В роли вишенки на торте выступает boxсупербыстрая multi-engine база данных с поддержкой транзакций и multi-master репликации, работающая прямо в том же адресном пространстве, что и приложения.

Занимательно, но у нас же трёхуровневая архитектура?




«Неужели опять предлагается переносить всю бизнес-логику в базу данных, вместо отдельного application server (Node.js, PHP, Python, whatever) и СУБД (Redis, MongoDB и т. п.)?» — резонно возразите вы. Нет, мы не покушаемся на основы мироздания. Давайте лишь посмотрим чуть более прагматично. Во времена, когда космиче приложения можно писать уже прямо в браузере, серверная часть остаётся по большей мере для хранения и обработки данных, тогда как браузер может запрашивать и обновлять всю необходимую информацию динамически через AJAX. Что же в таком раскладе делает ваш application server (PHP/Node/Go/Python)? Простаивает в ожидании ответа от базы, чтобы потом сразу отдать всё это в виде JSON в nginx? А ведь надо открыть транзакцию, после этого по сети выкачать данные из базы, поменять в них какие-то поля в application server, послать обновления обратно в базу данных, закрыть транзакцию и вернуть результат в nginx. Сколько лишних сетевых round trip и переключений userspace <-> kernel <-> userspace мы при этом потратим? А ещё ведь база данных должна на каждую открытую транзакцию поддерживать для вас целостный read-view данных, например ценой использования локов или других, не менее тяжеловесных механизмов. И всё это ради того, чтобы выбрать пять записей из одной таблички, обновить две записи в другой и вернуть результат в наш REST-сервис?

Для подобного рода микросервисов Тарантул предлагает удоч написать хранимку прямо рядом с самими данными, внутри СУБД. Модуль tarantool-http и nginx_tarantool_upstream легко организуют REST-сервис из Тарантула, упрощая архитектуру сервиса и убирая лишнее звено в виде выделенного application server. При этом никто не предлагает таким образом переписывать всё приложение, ведь можно выделить в микросервис лишь самые нагруженные части проекта, где запаса производительности традиционных решений уже не хватает. Для остального можно использовать тот же Tarantool как СУБД общего назначения через коннекторы из различных языков программирования.

Прекрасно, но там же Lua?!




«Мы не умеем писать на Lua! Да и где же взять таких программистов?» — спросите вы. Don’t panic! Lua (португ. луна) — простой как три копейки язык, не требующий для работы изучать собрание сочинений авторов в десяти томах. Посмотрели на примеры вместо просмотра рекламы в метро — и уже можно начинать грабить коро кодить. В Mail.Ru Group процедурки на Lua одинаково успешно пишут как программисты на C/C++, так и Python-, Perl-, Ruby- и JS-девелоперы. Но почему же Lua? Tarantool даёт разработчику настоящий Тьюринг-полный язык программирования высокого уровня, позволяющий решать любые задачи. Скажем своё твёрдое железное нет программированию на PL/SQL, XML, YAML и ini-файлах (прости господи). Кроме того, Lua крайне простой и очень быстро работает. С Lua нет споров о том, какие же 10% функциональности языка разрешить использовать в проекте.

Кстати, Tarantool также имеет сишный API, что позволяет достигать невиданной ранее производительности и, в теории, возможности использовать любые другие языки. Мы расскажем об этом подробнее в следующих сериях, не отключайтесь.

А давайте-ка попробуем!




Устанавливаем Tarantool со страницы tarantool.org/download.html. В репозиториях на сайте есть бинарные пакеты под основные Linux-дистрибутивы, а также порты для FreeBSD и brew для OS X. После установки вводим в консольке команду tarantool, которая по умолчанию запускает интерактивную консоль (как Python, Node, irb и др.):

roman@book:~$ tarantool
tarantool: version 1.6.8-123-gbe2ce21
type 'help' for interactive help
tarantool> 

В интерпретаторе можно вводить произвольный Lua-код, а результат выполнения будет выведен в читабельном формате (YAML) в консольку:

tarantool> 2 + 2
---
- 4
...
tarantool> { name = "Roman", gender = "male" }
---
- name: Roman
  gender: male
...
tarantool> print('Hello')
Hello
---
...

Всё то же самое можно написать в виде скриптика в отдельном файле:

#!/usr/bin/env tarantool

print(‘Hello world!’)

Запускаем скрипт аналогично Bash, Python или Ruby:

roman@desktop:~$ edit ololo.lua
roman@desktop:~$ chmod a+x ololo.lua
roman@desktop:~$ ./ololo.lua
Hello world!

Tarantool полностью совместим с Lua 5.1 и LuaJIT на уровне скриптов и может использоваться как drop-in replacement. Все модули от Lua работают в Tarantool.

Функция box.cfg{} конфигурирует и запускает встроенную базу данных (box), после чего можно создавать таблицы (space) и выполнять запросы:

tarantool> box.cfg {}
[cut]
tarantool> space = box.schema.space.create('test')
[cut]
tarantool> box.space.test:create_index('primary', { type = 'tree', parts = { 1, 'num' }})
[cut]
tarantool> box.space.test:insert({48, 'some data', { key = 'value', key2 = 'value2' }})
---
- [48, 'some data', {'key': 'value', 'key2': 'value2'}]
...
tarantool> box.space.test:select()
---
- - [48, 'some data', {'key': 'value', 'key2': 'value2'}]
...

Если же теперь остановить интерактивную консоль (через CTRL+D или os.exit(0)), то в каталоге можно увидеть новые файлы *.snap, *.xlog. Данные файлы используются для обеспечения persistence нашей базы данных в оперативной памяти. Повторный же запуск tarantool восстановит все данные:

tarantool> box.cfg{}
---
...

tarantool> box.space.test:select()
---
- - [48, 'some data', {'key': 'value', 'key2': 'value2'}]
...

А теперь попробуем что-нибудь более сложное (пример с главной страницы):

#!/usr/bin/env tarantool

box.cfg{}
-- Создаёт таблички при первом запуске
box.once('schema', function()
	box.schema.create_space('hosts')
	box.space.hosts:create_index('primary', { type = 'hash',
    	parts = {1, 'str'} })
end)

-- Обработчик GET-запросов к /
local function handler(self)
	-- Получаем IP-адрес клиента
	local ipaddr = self.peer.host
	-- Вставляем новую запись для адреса или инкрементируем существующую
	box.space.hosts:upsert({ ipaddr, 1 }, {{'+', 2, 1}})
	-- Возвращаем все записи в виде JSON клиенту
	return self:render{ json = box.space.hosts:select() }
end

local httpd = require('http.server')
local server = httpd.new('127.0.0.1', 8080)
server:route({ path = '/'  }, handler)
server:start()

Для запуска необходим модуль tarantool-http, который можно поставить из пакетов или из GitHub. Скрипт при первом запуске создаст таблицу hosts, после чего будет запущен HTTP-сервер, который на `/` будет инкрементировать counter для каждого IP-адреса и возвращать клиенту все адреса в формате JSON. Так же легко можно поставить перед сервисом nginx. Кстати, try.tarantool.org написан на самом Tarantool. Мы сами кушаем свои кактусы и стараемся делать жизнь разработчиков лучше.

Выкатываем на production




Как же лучше разместить наше простенькое приложение на рабочем сервере? Ведь одно дело в консольках поиграться, и совсем другое — запустить всё это в бой. Всё просто. Переносим скриптец в /etc/tarantool/instances.enabled/myapp.lua и запускаем уже через готовые утилиты для init (tarantoolctl start myapp или даже service tarantool restart). Работает! Просто?

Приложений можно сделать сколько угодно много, init-система сама будет запускать нужное количество демонов Tarantool и следить за ними. Мы рекомендуем запускать чуть меньше тарантулов, чем вы имеете физических ядер. Данный подход позволит обеспечить наилучшие показатели производительности на один сервер и сэкономить миллионы долларов. В списке процессов легко можно найти демон с именем вашего приложения. Log-файлы по умолчанию пишутся в /var/log/tarantool/myapp.log, данные хранятся в /var/lib/tarantool/myapp/, а pid-файл пишется в /run/tarantool. Иными словами, всё именно так, как задумано в вашем любимом дистрибутиве. Для сборки RPM- и DEB-пакетов можно воспользоваться нашим шаблоном.

Из полезного стоит отдельно отметить команду tarantoolctl enter myapp, которая позволяет подключаться консолькой к работающему демону для интроспекции состояния и изменения кода на лету. Также через box.cfg({listen = 3313 }) можно открыть сетевой порт для подключения коннекторами из других языков программирования и фреймворков (мы же вам обещали, что не будем ломать всё мироустройство!).

Что далее?


В следующих сериях мы расскажем более подробно, как обеспечить модульную архитектуру вашего приложения, организовать тестирование и непрерывную интеграцию кода. Также будет раскрыто секретное know-how по приготовлению Тарантула для обработки до 6М запросов в секунду на одном физическом ядре (seriously).

Ждём вопросов и комментариев.

З. Ы. 28 января мы проводим второй Tarantool Meetup в суперсовременном офисе Mail.Ru Group на м. Аэропорт. На встрече будут новые инсайты как от нашей команды, так и от внешних пользователей Тарантула. Вход бесплатный после регистрации, все ништяки включены. С вас хорошее настроение и желание попробовать Tarantool в своих проектах.

Комментарии (58)


  1. evnuh
    09.12.2015 14:22
    +2

    Что-то вас понесло конечно) Я когда-то рассматривал тарантул в качестве бд, но ещё на этапе бд она уже была разнобокая — хранение на диске и в памяти было реализовано по-разному, в итоге прихоодилось выбирать либо только то, либо только это. А теперь, когда ваш тарантул превратился и в веб-сервер-клиент-api-parser и т.д. уже совсем непонятно, в какой реальной задаче требуется это всё?


    1. dedokOne
      09.12.2015 14:29
      +4

      Это все инструменты, не обязательно их все использовать, к примеру, можно использовать только in-memory или только storage.
      Кстати, многие проекты которые начинались как БД обросли не меньше.


    1. zloidemon
      09.12.2015 14:31
      +7

      У меня вообще обрабатывает звонки из телефонии. Можно делать что хочешь, и как хочешь.


    1. rtsisyk
      09.12.2015 15:32

      box.schema.space.create('in_memory', { engine = 'memtx' }) — храним в памяти
      box.schema.space.create('on_disk', { engine = 'sophia' }) — храним на диске
      При том что мы используем общий binlog для всех движков, репликация и прочие фишки будут работать одинаково.


      1. youROCK
        09.12.2015 16:35

        Я кстати всё забываю спросить, репликация логическая? Или здесь это неприменимо :)?


        1. rtsisyk
          09.12.2015 17:14
          +2

          row-based на запросы к самой базе.
          Кстати вызовы хранимок на слейвы тоже не проигрываем, как некоторые, передаем лишь сделанные изменения в базе.


  1. DLag
    09.12.2015 14:53
    -2

    Что-то я на Highload поспрашивал используется ли оно хоть где-то в production, и не получил положительных ответов.
    Как я понял, Mail.ru это делает чисто для поиграться, и ищет желающих подопытных все-таки попробовать это в работе…
    Т.е. по сути очистка кармы перед OSS сообществом и информационный повод.


    1. rtsisyk
      09.12.2015 14:56
      +7

      Всё Mail.Ru на Tarantool. Серьезно.


    1. bigbes
      09.12.2015 14:58
      +7

      Это странное утверждение. На стенде рассказывали что оно используется в Badoo, Avito, Wallarm, да и во всём Мейл.Ру.
      Не особо понятно о каком «Mail.ru это делает чисто для поиграться» идёт речь.


      1. DLag
        09.12.2015 16:42

        На стенде говорили что его пробуют много где.
        Пробовать — не значит использовать в проде.
        На прямой вопрос о том в каких кейсах Mail.Ru использует Tarantool мне фактически не ответили, съехали с разговора.
        На всех докладах говорилось что они ждут фидбек от тех кто использует в проде.
        Как я понял своего фидбека нет…


        1. rtsisyk
          09.12.2015 17:16

          На Хайлоаде был знатный доклад тех. дира почты (почты Mail.Ru, Карл) про сэкономленный миллион долларов на Тарантуле.
          Как раздобуду презентацию — постараюсь выложить.
          Фидбек всегда ждем, поскольку на его основе мы планируем новые фичи.


          1. RubaXa
            09.12.2015 17:27
            +3

            Так вот же он it.mail.ru/video/253


        1. RubaXa
          10.12.2015 11:29

          Вот ещё про использование Tarantool в «Облаке@Mail.Ru»


    1. ooprizrakoo
      09.12.2015 14:58
      +2

      + Badoo, Avito, Wallarm, чуток в Сбербанке, и др.


      1. HDDimon
        09.12.2015 17:47

        а в Сбербанке как его используют?


        1. ooprizrakoo
          09.12.2015 17:55
          +1

          не знаю подробностей, там у них какое-то небольшое инфраструктурное решение.
          возможно, просто смотрят пока как оно в «бою» себя ведет.


    1. ilnarb
      09.12.2015 15:07
      +10

      Я использую в продакшене: 4 сервера в кластере с 96Gb, суммарно 320Gb памяти под тарантулы.
      Хранятся порядка 5 млрд записей, в среднем по 40 байт. Uptime 2 года без без каких либо вмешательств и обновлений.
      Никакая база так эффективно не может хранить столько мелких данных так эффективно в оперативке.
      Бизнес логика зашита в lua процедурах, и запросы идут в batch режиме.
      Если бы не было lua процедур, batch режим был бы не доступен, т.к. изменение данных зависят от других данных в базе: пара селектов и один апдейт. Это было бы 3 раунд-трипа на одну операцию изменения, а тут удается упаковать 50 операций в один раунд-трип.


      1. DLag
        09.12.2015 16:47
        +2

        2 года без обновлений? Смело.
        4 сервера в кластере, у вас Master->3xSlave?
        Просто Master-Master появился в Tarantool чуть больше месяца назад и использовать подобное решение для боевых данных без проверки временем рисковано.
        Раудтрипы убираются в любой БД встроенными процедурами.
        Почему взяли Tarantool?


        1. ilnarb
          09.12.2015 17:20
          +1

          Шардинг на клиенте.


        1. bigbes
          09.12.2015 18:14
          +1

          > Просто Master-Master появился в Tarantool чуть больше месяца назад.
          Вы это скажите инсталляциям в Авито, которым уже больше года


      1. DLag
        09.12.2015 16:53
        -1

        Не ясно откуда утверждение про эффективность хранения.
        В Tarantool не шардинга, только поделка на коленке от инженеров Mail.Ru без понимания принципа ACID.
        Очевидно что либо Tarantool не хранит все данные в ОЗУ, либо у вас свой наколеночный шардинг.
        И опять таки, почему не использовать взрослые решения и с чем вы сравнивали?
        И сравнивали ли вы вообще…


        1. rtsisyk
          09.12.2015 17:11
          +1

          В плане базы данных у нас все честно. ACID самый что ни на есть настоящий.
          Мастер-Мастер есть уже более года, с каждым релизом делаем всё проще и удобнее.


          1. DLag
            09.12.2015 18:15

            Я про ACID в шардинге, который предлагали ваши коллеги.
            Там его просто нет.


            1. rtsisyk
              09.12.2015 18:46

              возможно, он там и не нужен был.
              Расскажите как use-case у Вас…


        1. ilnarb
          09.12.2015 17:21

          Сравнивал (мемкеш, монго, мускуль, редис, токио кабинет), но расписывать все не хочу, могу ответить по конкретным конкурентам, про которые вы хотели бы знать.


        1. BHYCHIK
          09.12.2015 19:11

          На HighLoad был доклад от Дмитрия Калугина-Балашова о выборе базы данных.


          1. rtsisyk
            09.12.2015 19:51

            articles.rvncerr.org/how-to-chose-an-in-memory-nosql-solution-performance-measuring вот здесь есть статья по мотивам доклада.


    1. rtsisyk
      10.12.2015 11:30
      +1

      Вы просили — мы сделали. habrahabr.ru/company/mailru/blog/272769


  1. zloidemon
    09.12.2015 15:01
    +6

    У нас в плюсофоне используется.


    1. DLag
      09.12.2015 16:57
      +2

      Отлично, кто-то живой с опытом production use.
      Ответьте пожалуйста на вопросы, думаю всем будет интересно:
      Под какие структуры данных?
      Какой стор используете?
      Масштабируете?
      Почему именно Tarantool?


      1. zloidemon
        10.12.2015 12:10

        1. Разные данные, есть где пары звонков с индексами по несколько ключам, есть просто куча данных которые по кругу через очередь ротируются.
        2. У меня memtx и почти все режиме temporary=true.
        3. Стоит http встроенный, и nginx балансирует нагрузку. На сокетах протоколы (AGI & AMI) из АТС (Asterisk).
        4. Очень удобно программировать на Lua (нет лишних знаков препинания), и сразу есть куча ништяков. У меня не только Tarantool есть. Есть redis/riak которые пойдут под нож в будущем.


  1. Nick0N
    09.12.2015 15:02

    Переносим скриптец в /etc/tarantool/instances.enabled/myapp.lua и запускаем уже через готовые утилиты для init (tarantoolctl start myapp или даже service tarantool restart). Работает! Просто?


    Все хорошо, но тогда приложение БД и http сервер нужно описывать в одном файле, иначе при рестарте http приложение заворачивается в event loop и на этом все! Я подозреваю, что server:start() должен вызываться вконце всего и вся.

    И отсюда проблемы с перезапуском, service tarantool restart на большой БД (около 180кк туплов ) занимает порядка 15минут!!! А тебе всего лишь нужно было добавить новый route и handler.


    1. bigbes
      09.12.2015 15:06
      +2

      Использовать «tarantoolctl eval \<app\>» , по хорошему. Никакого перезапуска, только перезагрузка файла конфигурации.


      1. Nick0N
        09.12.2015 15:14

        Спасибо! Но я так понимаю надо и сервер и бд описывать в одном файле конфигурации?


        1. rtsisyk
          09.12.2015 15:17

          Само приложение лучше делать отдельно в виде модуля и помещать в /usr/share/tarantool/myapp.
          В etc лучше оставить только конфигурацию. Изменение настроек на лету можно делать через админку, правда не все опции пока меняются.
          Я думаю мы еще напишем об этом.


  1. GubkaBob
    09.12.2015 15:19

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

    Всё Mail.Ru на Tarantool. Серьезно.

    какие шишки успели набить? где стелить солому?


    1. rtsisyk
      09.12.2015 15:29

      Сравнение разумно проводить в разрезе с какими-то другими конкретными решениями, но в целом это тема для отдельной докторской диссертации статьи :) Расскажите о своей задаче и мы скажем насколько Tarantool для неё подходит.


      1. GubkaBob
        09.12.2015 15:41
        +1

        Я и надеялся, что такие сравнения проводились.

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

        Задача наглядная, и частично покрыта Асинхронная работа с Tarantool на Python. Но если взять вместо tarantool что-то из набора: tomcat, play2, mina, go, mysql, postgresql, berkleydb — где станет хуже/лучше?

        ps. то что будет солянка их технологий — меня не пугает. от неё все равно не уйти. интересует только какие проблемы добавит tarantool.


        1. rtsisyk
          09.12.2015 16:50

          Смешались в кучу кони, люди :) Я не очень понимаю как можно сравнивать play framework и bdb, ведь это совершенно разные инструменты для разных задач.

          Для телеметрии от датчиков и прочего IoT сервис можно поднять сервис напрямую на тарантуле, хоть по HTTP, хоть MQTT какой-нибудь на луа. В таком раскладе tomcat c play может оказаться вам просто не нужен. Собственно в этом и есть соль статьи.

          Кстати, с графиками у нас есть няшный пример — bench.farm.tarantool.org


          1. GubkaBob
            09.12.2015 18:56

            Смешались в кучу кони, люди :) Я не очень понимаю как можно сравнивать play framework и bdb


            не надо сравнивать одно с другим. вопрос был про Tarantool vs others. Потому что статья называется «Tarantool как сервер приложений», да и сам тарантул вроде как база чуть-чуть. поэтому и сравнивать можно/надо со стеком, в котором компонентами может быть как play, так и bdb.

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


            1. rtsisyk
              09.12.2015 19:24

              Если задача состоит в том, что надо получить данные с устройства, немного их обработать и сразу же сохранить в БД, то какой смысл здесь городить целый стек tomcat + play + postgresql, если один тарантул с http на борту сделает тоже самое?
              Про модуль для nginx писали тоже не так давно: habrahabr.ru/company/mailru/blog/272141


              1. GubkaBob
                09.12.2015 22:18

                вот и я думаю — зачем?


  1. zuborg
    09.12.2015 16:24

    Технический вопрос.
    Стоит задача эффективно хранить сотню (или больше) миллионов записей вида (idA, idB) — т.е. отношение many-to-many. Например, что такой-то файл есть на таком-то сервере (файлов много и серверов много, один и тот же файл на разных серверах и соотв на одном сервере разные файлы). Как с этим справится тарантул? Сколько байт будет в среднем потребляться на одну запись (положим, айдишники по 32 бита)? Нужны persistency, fault tolerance, master-master replication, индексированный доступ по обоим полям (т.е. эффективно получить список серверов для файла и список файлов на сервере).


  1. kostja
    09.12.2015 16:41

    32-40 байт на запись, с учётом памяти под данные и индексы.


    1. rtsisyk
      09.12.2015 17:06

      Немного поправлю, 32-40 с одним индексом (сервер->файлы) и примерно 48-56 с двумя (файл->сервер + сервер->файлы).
      Над утилизацией памяти мы активно работаем, есть чем похвастаться. Остальные перечисленные фишки (persistency, fault tolerance, master-master replication) также есть из коробки.


  1. zuborg
    09.12.2015 17:16

    Есть ли у тарантула проблема с index bloating? Если индексы ещё можно пересоздать на ходу (можно ж на ходу создать индекс?) то как обстоит с фрагментацией в файлах данных? Сколько будет занимать пустое место (от удаленных записей) в файлах базы под активной нагрузкой?


    1. rtsisyk
      09.12.2015 17:20

      У нас же не монгаWebScale, нет никакого пустого места ни в каких файлах в принципе.
      В случае in-memory мы пишем append only write-ahead-log (binary log) и периодически делаем снапшоты на диск. Индексы вообще хранятся полностью в памяти.


      1. zuborg
        09.12.2015 17:35

        Индексы вообще хранятся полностью в памяти.
        То что они хранятся в памяти ещё не означает что нет проблемы с раздуванием. Например, тарантул запустился, загрузил 100М записей, проиндексировал их и это заняло 5ГБ памяти. Потом пошла работа — какие-то данные удалились, какие-то добавились, в итоге их осталось те же 100М, но уже других. В ходе работы потребление памяти будет расти. Например, при записях нефиксированной длины будут оставаться дырки, когда на место большой записи будет добавлена маленькая, а оставшееся место уже не сможет уместить ни одну запись. Обновление индексов тоже влечет за собой постоянное перемещение указателей для сохранения балансировки дерева — в итоге часть нод будет заполнена совсем не так плотно, как могла бы.
        Если в процессе работы будет заменено в случайном порядке 200% записей (т.е. 200М обновлений для 100М записей) — во сколько раз вырастет потребление памяти? Для постгреса, например, размер индекса легко вырастает в несколько раз при активной нагрузке.


        1. rtsisyk
          09.12.2015 17:48
          +1

          Вы говорите сейчас о так называемой «фрагментации памяти». Естественно, что решить NP-полную задачу выделения памяти идеально для всех случаев невозможно, но можно свести фрагментацию к минимуму для ваших конкретных данных. Именно поэтому Tarantool использует аж целое семейство специализированных аллокаторов под разные задачи, а также дает различные ручки для их настройки. На HighLoad++ в этом году аж целый доклад был про особенности в СУБД для данных в оперативной памяти (видео пока организаторы не дают).


        1. dedokOne
          09.12.2015 18:00

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


  1. uglock
    10.12.2015 07:34

    Lua это хорошо, это вам не q/kdb.


  1. B7W
    10.12.2015 10:13
    +3

    Ребята. Вы странно пиарите продукт. Будь он сто раз крут, я не возьму его пока не увижу use cases. Потом связка lua application server является диковиной, никто не представляет как это готовить.

    Предлагаю вам написать приложение. Идеально если это будет не веб чатик, а что то полезное у вас в компании. Выложите все это в open source. Расскажите с нуля что как делали. Как код структурировали, базу проектировали, управляли зависимостями, CI, deploy, мониторинг и тд.


    1. rtsisyk
      10.12.2015 10:32
      +1

      В какой-то мере согласен с Вами. Пока что статей от early adopters Tarantool 1.6, прошедших семь кругов ада с управлением зависимостями, CI, deploy, тестированием, мониторингом и прочим, не так много, как хотелось бы. На конференциях были хорошие доклады, но надо постараться донести свой опыт и в виде статей. Также на митапе постараемся рассмотреть больше реальных use cases.


      1. B7W
        11.12.2015 00:05
        +1

        Мне кажется вы немного не туда смотрите. Не надо доносить что-то в статьях и встречах. Надо на сайте написать пачку железобетонных use cases в которых tarantool максимально подходит. Можно сравнить с какой нить базой, например Redis.

        Гляньте для примера kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis

        А популяризация Tarantool происходит только в русской часте сети?


        1. dedokOne
          11.12.2015 10:54

          Статьи и сравнения (например, на tarantool.org) есть. Use cases не хватает, тоже пришли к такому мнению, будет исправляться, но не все сразу.
          А популяризация Tarantool происходит только в русской часте сети?
          Не только в русской части сети.


        1. rtsisyk
          11.12.2015 10:56

          Мы подобную статью тоже написали articles.rvncerr.org/how-to-chose-an-in-memory-nosql-solution-performance-measuring
          Продвигать будем в том числе и на западный рынок, но наши ресурсы не безграничны.


  1. Deepwalker
    15.12.2015 17:04

    А нет никакого инструментария для управления зависимостями там и тп? Ранние адаптеры не выкладывают своих решений?


    1. rtsisyk
      15.12.2015 18:18

      luarocks [1], если поиграться на коленках (типа как pip, gem, npm и прочее).
      Если в боевую, то deb/rpm пакеты. Можно использовать нашу инфраструктуру [2][3] для сборки своих аппликух под нужные платформы.

      [1]: rocks.tarantool.org
      [2]: github.com/tarantool/modulekit
      [3]: github.com/tarantool/http/blob/master/.travis.yml