3. Tarantool — эффективная СУБД
● Multi-engine: persistent in-memory + disk only
● Secondary indexes and range queries
● Real ACID transactions
● Master-Master replication and hot standby
● Authentication, authorization and access control
● 1M+ transactions per second per CORE
● Server-side scripting and stored procedures
4. #!/usr/bin/env tarantool
function handler(self)
return self:render({
json = { box.space.data:select() }
})
end
server = require('http.server').new(nil, 8080)
server:route({ path = '/' }, handler)
server:start()
-- connect to localhost:8080 to get json
5.
6. Tarantool — СУБД + Application Server
● Язык программирования общего назначения
● Выполнение кода рядом с данными
● Fibers, channels, sockets, JSON в СУБД!
● Динамическая загрузка кода и отладка
● Модули и приложения
● Как Go + node.js + Redis в одном флаконе
7.
8. Дотарантульная эра: до 2010 года
● Framework для написания высокопроизводительных
серверов для Почты@Mail.ru и Мой Мир@Mail.Ru
● Файберы и кооперативная многозадачность на C
● Семейство специализированных аллокаторов памяти
● Восстановление из write ahead log
● Бинарный сетевой протокол (IPROTO)
● Текстовая админская консоль
● Статически компилируемые модули на С/ObjC
9. Tarantool 1.3: август 2010
● Tarantool/Box (mod_box) — in-memory key/value storage на
основе фреймворка
● Opensourced on GitHub, BSD-2 «Simplified» license
● Сотни тысяч запросов в секунду на одном ядре
● Поддержка memcached протокола из коробки
● А почему «Tarantool»?
● localhost> exec command
Unimplemented
10.
11. Tarantool 1.4.1- 1.4.5: 2011 - 2012
● 1.4.1: rudimentary Lua support using LuaJIT:
localhost> lua 2 + 2
- 4
● 1.4.2: CALL команда в бинарном протоколе
● 1.4.2: box.select(), box.update(), box.replace(), box.delete()
● 1.4.3: биндинги к файберам из Lua
12.
13. Tarantool 1.4.6 - 1.5.x: 2012 - 2014
● box.socket() - файберные сокеты для Lua
● box.ipc — inter procedure communication (channels)
● box.net.box, box.net.pg, box.net.mysql
● box.httpd, box.http, box.json, box.digest
● tarantool/queue, tarantool/shard
● Заработала поддержка внешних Lua modules
14.
15. Tarantool 1.6.x: 2014 - …
● Фреймворк для написания high-load сервисов
● Эффективная СУБД общего назначения на борту
● Файберы и кооперативная многозадачность
● Текстовая админка, бинарный сетевой протокол
● Семейство специализированных аллокаторов
● Динамические Lua, Lua/C, C модули и запас батареек
16. Batteries Included
● box — база данных
● fiber — кооперативная многозадачность
● socket, fio — асинхронное I/O
● net.box — клиент к Tarantool из Tarantool
● json/yaml/msgpack — сериализаторы
● console — интроспектирование сервера
● log — логгирование событий
json = require(„json“)
17.
18. Модули в репозитории
●
shard — server-side шардинг
● mysql/pg — клиенты к mysql и pg
●
queue — персистентные очереди
●
http — http сервер и клиент
●
memcached — эмуляция memcached
● gis — работа с геоданными в Tarantool
● try — сервис try.tarantool.org
http://tarantool.org/download.html
19. https://github.com/tarantool/pg
https://github.com/tarantool/mysql
Примеры: pg и mysql
local pg = require('pg')
local conn = pg.connect({host = localhost, user = 'user',
pass = 'pass', db = 'db'})
local tuples = conn:execute("SELECT ? AS a, 'xx' AS b", 42))
conn:begin()
conn:execute("INSERT INTO test VALUES(1, 2, 3)")
conn:commit()
24. Модули к Tarantool. Вам какой?
● Pure Lua shard, queue, http, ...
● Lua + FFI digest, memcached, gis, ...
● Lua/C pg, mysql, json, yaml, ...
● Pure C (без Lua) test/box/function1.c
http://github.com/tarantool/modulekit
25. Pure Lua модуль
$ mkdir mymodule && editor mymodule/init.lua
local function add(a, b)
return a+b
end
return { add = add } -- export public API
tarantool> mymodule = require('mymodule').add(2, 5)
http://github.com/tarantool/modulekit
27. Pure Lua: возможности
local http_client = require('http.client')
local json = require('json')
local r = http_client.get('http://api.example.org/data/2.5/weather')
if r.status ~= 200 then error('OMG') end
local data = json.decode(r.body)
return { wind = data.wind.speed }
28. FFI - Foreign Function Interface
local ffi = require('ffi')
local crypto = ffi.load('crypto')
ffi.cdef("int RAND_bytes(unsigned char *buf, int num);")
function exports.rand_bytes(size)
local buf = ffi.new('char[?]', size)
crypto.RAND_bytes(buf, size)
return ffi.string(buf, size);
end
http://luajit.org/ext_ffi.html
29. Lua FFI модуль
$ tarantool
tarantool: version 1.6.8-671-gdd1beee
type 'help' for interactive help
tarantool> require('ffimodule').rand_bytes(10)
---
- !!binary l6cKok+uoRwXEg==
...
30. Lua/C модуль
#include <lua.h>
Int luacmodule_add(lua_State *L) {
int a = lua_tointeger(L, 1); -- get #1 argument
int b = lua_tointeger(L, 2); -- get #2 argument
lua_pushinteger(L, a + b); -- push result
return 1; -- one result
}
http://github.com/tarantool/modulekit
34. С API: возможности
● insert/replace/delete/update/upsert/etc.
● Итераторы (курсоры), работа с tuples
● Полный доступ к файберам, запуск своих тредов
● Аллокаторы, неблокирующий I/O, обработка ошибок
● Доступ к любым системным библиотекам
● Прозрачно для клиента (CALL в бинарном протоколе)
https://tarantool.org/doc/reference_capi/index.html
37. C API: сокеты
man 2 socket
/**
* Wait until READ or WRITE event on socket (a fd). Yields.
* param fd - non-blocking socket fd
*/
API_EXPORT int
coio_wait(int fd, int event, double timeout);
yield пока на сокете не появятся события
38. C API: работа с СУБД
int box_replace(uint32_t space_id, const char *tuple,
const char *tuple_end, box_tuple_t **result);
box_iterator_t * box_index_iterator(uint32_t space_id,
uint32_t index_id, int type, const char *key, char *key_end)
https://tarantool.org/doc/reference_capi/index.html
39. C API: быстро
replace 4 007 026 rps
select 7 114 054 rps
update 2 337 879 rps
delete 3 989 257 rps
7M запросов на одном ядре!
40.
41. Pure C: пример
int args(box_function_ctx_t *ctx,
const char *args, const char *args_end) {
uint32_t arg_count = mp_decode_array(&args);
say_info("argument count is %u", arg_count);
…
box_tuple_new(fmt, tuple_buf, d);
return box_return_tuple(ctx, tuple);
MsgPack
43. Отладка
● Tarantool Debugger https://github.com/Sulverus/tdb
(TDB) 7: local i = 0
(TDB) 8: while true do
(TDB) 9: i = i + 1
(TDB) 10: fiber.sleep(0.5)
● gdb
● Шлите корки, пишите в чатик, обновляйте тарантул (c)
http://telegram.me/tarantool
44.
45. Best Practices
● Отдавайте CPU другим файберам — fiber_sleep()
● Используйте файберы и каналы
● Не используйте блокирующие сокеты
● Запускайте числодробилки в отдельных тредах
●
Проверяйте fiber_testcancel() в фоновых файберах
● Создавайте как можно меньше мусора в Lua
51. LuaRocks
● Пакетный менеджер для Lua
● Как RubyGems, Python Eggs, CPAN, но для Lua
● Разрешает зависимости
● Работает без root прав
● Работает на любой ОС
http://rocks.tarantool.org/
59. Почему Lua?
● Низкий порог вхождения
● Компактный и легко встраиватся
● Нативная поддержка coroutines
● Быстрее V8 для server-side
● Tracing JIT Сompiler