SlideShare a Scribd company logo
Расширяем возможности
Tarantool с помощью
модулей на Lua / C / C++
Цисык Роман <roman@tarantool.org>
http://tarantool.org, Mail.Ru Group
https://github.com/tarantool/modulekit
https://tarantool.org/download.html
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
#!/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
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool — СУБД + Application Server
● Язык программирования общего назначения
● Выполнение кода рядом с данными
● Fibers, channels, sockets, JSON в СУБД!
● Динамическая загрузка кода и отладка
● Модули и приложения
● Как Go + node.js + Redis в одном флаконе
Tarantool Modules, Tarantool Meetup 2016-08-25
Дотарантульная эра: до 2010 года
● Framework для написания высокопроизводительных
серверов для Почты@Mail.ru и Мой Мир@Mail.Ru
● Файберы и кооперативная многозадачность на C
● Семейство специализированных аллокаторов памяти
● Восстановление из write ahead log
● Бинарный сетевой протокол (IPROTO)
● Текстовая админская консоль
● Статически компилируемые модули на С/ObjC
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
Tarantool Modules, Tarantool Meetup 2016-08-25
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
Tarantool Modules, Tarantool Meetup 2016-08-25
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
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool 1.6.x: 2014 - …
● Фреймворк для написания high-load сервисов
● Эффективная СУБД общего назначения на борту
● Файберы и кооперативная многозадачность
● Текстовая админка, бинарный сетевой протокол
● Семейство специализированных аллокаторов
● Динамические Lua, Lua/C, C модули и запас батареек
Batteries Included
● box — база данных
● fiber — кооперативная многозадачность
● socket, fio — асинхронное I/O
● net.box — клиент к Tarantool из Tarantool
● json/yaml/msgpack — сериализаторы
● console — интроспектирование сервера
● log — логгирование событий
json = require(„json“)
Tarantool Modules, Tarantool Meetup 2016-08-25
Модули в репозитории
●
shard — server-side шардинг
● mysql/pg — клиенты к mysql и pg
●
queue — персистентные очереди
●
http — http сервер и клиент
●
memcached — эмуляция memcached
● gis — работа с геоданными в Tarantool
● try — сервис try.tarantool.org
http://tarantool.org/download.html
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()
Примеры: memcached
memcached = require('memcached')
local instance = memcached.create('mycache', '0.0.0.0:11211')
$ printf "set key 0 60 5rnvaluern" | nc localhost 11211
STORED
$ printf "get keyrn" | nc localhost 11211
VALUE key 0 5
value
https://github.com/tarantool/memcached
Примеры: tarantool-queue
● Copy-cat of beanstalkd API:
– tube:put(), tube:take(), tube:ack()
– tube:peek(), tube:bury(), tube:kick()
● FIFO, FIFOTTL, uTUBE, uTUBETTL
local queue = require('queue')
queue.create_tube(name, type, { ... })
queue.tube.tube_name:put(task_data[, opts])
queue.tube.tube_name:take([timeout])
https://github.com/tarantool/queue
Tarantool Modules, Tarantool Meetup 2016-08-25
http://tarantool.org/download.html
http://github.com/tarantool/modulekit
$ sudo apt-get install tarantool tarantool-dev
$ tarantool
tarantool: version 1.6.8-671-gdd1beee
type 'help' for interactive help
Tarantool> 2 + 2
---
- 4
...
Модули к 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
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
Вызов функций из клиента
tarantool> box.cfg { listen = 3313 }
tarantool> mymodule = require('mymodule')
tarantool> box.schema.user.grant('guest', 'execute', 'universe')
Python >>> import tarantool
Python >>> conn = tarantool.connect('localhost', 3313)
Python >>> conn.call('mymodule.add', 1, 2)
- [3]
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 }
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
Lua FFI модуль
$ tarantool
tarantool: version 1.6.8-671-gdd1beee
type 'help' for interactive help
tarantool> require('ffimodule').rand_bytes(10)
---
- !!binary l6cKok+uoRwXEg==
...
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
Lua Stack
lua_tointeger(L, 1) => 10
lua_tointeger(L, -1) => 10
lua_tostring(L, 2) => "Hello"
lua_type(L,3) => LUA_TTABLE
10
"Hello"
table
tarantool> myfun(10, "Hello", {1, 2, 3})
1
2
3
1
2
3
-3
-2
-1
lua_gettop(L) == 3
Lua/C модуль: инициализация и сборка
extern "C" int luaopen_luacmodule(lua_State *L) {
lua_newtable(L);
lua_pushcfunction(L, luacmodule_add);
lua_setfield(L, -2, "add");
return 1; }
$ cc luacmodule.c -o luacmodule.so -shared -fPIC
-I/usr/include/tarantool
http://github.com/tarantool/modulekit
apt-get install tarantool-dev
Lua: return { add = add }
Lua/C модуль: загрузка
$ nm -a luacmodule.so |grep luaopen
0000000000000855 T luaopen_luacmodule
tarantool> require('luacmodule').add(1, 2)
---
- 3
...
http://github.com/tarantool/modulekit
С API: возможности
● insert/replace/delete/update/upsert/etc.
● Итераторы (курсоры), работа с tuples
● Полный доступ к файберам, запуск своих тредов
● Аллокаторы, неблокирующий I/O, обработка ошибок
● Доступ к любым системным библиотекам
● Прозрачно для клиента (CALL в бинарном протоколе)
https://tarantool.org/doc/reference_capi/index.html
Runtime and Box
C API
Lua
C API: файберы
struct fiber *f = fiber_new("background", background_f);
If (f == NULL) return -1;
fiber_start(f, some, args);
fiber_join(f);
int background_f(va_list ap) {
uint32_t space_id = va_arg(ap, uint32_t);
uint32_t index_id = va_arg(ap, uint32_t);
fiber_sleep(5); }
Запуск файбера
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 пока на сокете не появятся события
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
C API: быстро
replace 4 007 026 rps
select 7 114 054 rps
update 2 337 879 rps
delete 3 989 257 rps
7M запросов на одном ядре!
Tarantool Modules, Tarantool Meetup 2016-08-25
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
Pure C: запуск
box.schema.func.create('mylibrary.args', {language = "C"})
box.schema.user.grant('guest', 'execute', 'function', 'mylibrary.args')
conn:call('mylibrary.args', 15)
> ---
- [15, 'hello']
...
Отладка
● 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
Tarantool Modules, Tarantool Meetup 2016-08-25
Best Practices
● Отдавайте CPU другим файберам — fiber_sleep()
● Используйте файберы и каналы
● Не используйте блокирующие сокеты
● Запускайте числодробилки в отдельных тредах
●
Проверяйте fiber_testcancel() в фоновых файберах
● Создавайте как можно меньше мусора в Lua
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
Порядок загрузки модулей
tarantool> package.path
tarantool> package.сpath
● Текущая директория
● $HOME/.luarocks/… – luarocks install --local
● /usr/share/tarantool/?.lua; /usr/lib/x86_64-linux-gnu/?.so
● /usr/share/lua/5.1/?.lua; /usr/lib/x86_64-linux-gnu/lua/5.1/?.so
Запуск демонов
● /etc/tarantool/instances.enabled/myapp.lua - конфиг
box.cfg({ slab_alloc_arena = 0.5; })
instance = require("mymodule");
instance.start()
● /usr/share/tarantool/mymodule/init.lua — код
● systemctl start tarantool@myapp
● systemctl status tarantool@myapp
● tail -f /var/log/tarantool/myapp.log
Tarantool Modules, Tarantool Meetup 2016-08-25
LuaRocks
● Пакетный менеджер для Lua
● Как RubyGems, Python Eggs, CPAN, но для Lua
● Разрешает зависимости
● Работает без root прав
● Работает на любой ОС
http://rocks.tarantool.org/
Tarantool Modules, Tarantool Meetup 2016-08-25
Пакеты
.travis.yml:
env:
matrix:
- OS=el DIST=6 PACK=rpm
- OS=fedora DIST=23 PACK=rpm
- OS=ubuntu DIST=trusty PACK=deb
- OS=debian DIST=stretch PACK=deb
script:
- git clone https://github.com/tarantool/build.git
- ./build/pack/travis.sh
https://github.com/tarantool/build
Сборка пакетов на Travis CI
https://github.com/tarantool/build
Docker
$ docker run -t -i tarantool/tarantool:1.7
FROM tarantool/tarantool:1.7
ADD myapp.lua /
RUN luarocks install http pg mysql
CMD ["tarantool", "/myapp.lua"]
Упаковка
Спасибо!
https://github.com/tarantool/modulekit
https://github.com/tarantool/build
http://tarantool.org/download.html
http://telegram.me/tarantool
roman@tarantool.org
Tarantool Modules, Tarantool Meetup 2016-08-25
Почему Lua?
● Низкий порог вхождения
● Компактный и легко встраиватся
● Нативная поддержка coroutines
● Быстрее V8 для server-side
● Tracing JIT Сompiler
Почему Lua?
Почему Lua?
x = fun.tabulate(math.sin)
:take(n)
:map(function(x)
return x^2 end)
:sum()
-- sum(sin(x)^2 for x in 0..n-1)
print(x)
50.011981355266
-- skip some initilization code --
->LOOP:
0bcaffd0 movsd [rsp+0x8], xmm7
0bcaffd6 addsd xmm4, xmm5
0bcaffda ucomisd xmm6, xmm1
0bcaffde jnb 0x0bca0028 ->6
0bcaffe4 addsd xmm6, xmm0
0bcaffe8 addsd xmm7, xmm0
0bcaffec fld qword [rsp+0x8]
0bcafff0 fsin
0bcafff2 fstp qword [rsp]
0bcafff5 movsd xmm5, [rsp]
0bcafffa mulsd xmm5, xmm5
0bcafffe jmp 0x0bcaffd0 ->LOOP
---- TRACE 1 stop -> loop

More Related Content

ODP
Константин Осипов (Mail.Ru)
PDF
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
PPTX
Сервер-агрегатор на python (аля Xscript FEST), Сумин Андрей, Сабуренков Михаи...
PDF
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
PDF
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)
PDF
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
PDF
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
PDF
Движок LMDB - особенный чемпион
Константин Осипов (Mail.Ru)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
Сервер-агрегатор на python (аля Xscript FEST), Сумин Андрей, Сабуренков Михаи...
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Использование Tarantool для хранения чатов и лент друзей (Константин Осипов)
2013-01-05 01 Леонид Евдокимов. Web scale. Взорвется все
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Движок LMDB - особенный чемпион

What's hot (20)

PDF
Reform: путь к лучшему ORM
PDF
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
PDF
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
PDF
Хранение данных на виниле / Константин Осипов (tarantool.org)
PPTX
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
PDF
Семинар 12. Параллельное программирование на MPI (часть 5)
PDF
Tarantool_qs
PPTX
Apache Storm: от простого приложения до подробностей реализации
PPTX
Раскручиваем стек. Иван Пономарев. CoreHard Spring 2019
PDF
7 встреча — Программирование компьютерных сетей (А. Свириденков)
PPTX
FreeRTOS
PDF
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...
PDF
iOS-07_2 Multithreading
PDF
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
PPT
Conflux: GPGPU .NET
PDF
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
PDF
Пространственно-распределенная мультикластерная вычислительная система: архит...
PDF
GIT Slides (25.03.2015)
PDF
Лекция 7. Язык параллельного программирования Intel Cilk Plus
PDF
Механика DDoS (Александр Крижановский)
Reform: путь к лучшему ORM
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Последние новости постгреса с PGCon / О.Бартунов, А.Коротков, Ф.Сигаев (Postg...
Хранение данных на виниле / Константин Осипов (tarantool.org)
Движок LMDB — особенный чемпион / Юрьев Леонид (Петер-Сервис R&D)
Семинар 12. Параллельное программирование на MPI (часть 5)
Tarantool_qs
Apache Storm: от простого приложения до подробностей реализации
Раскручиваем стек. Иван Пономарев. CoreHard Spring 2019
7 встреча — Программирование компьютерных сетей (А. Свириденков)
FreeRTOS
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...
iOS-07_2 Multithreading
Строим сервисы на базе Nginx и Tarantool / Василий Сошников, Андрей Дроздов (...
Conflux: GPGPU .NET
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Пространственно-распределенная мультикластерная вычислительная система: архит...
GIT Slides (25.03.2015)
Лекция 7. Язык параллельного программирования Intel Cilk Plus
Механика DDoS (Александр Крижановский)
Ad

Similar to Tarantool Modules, Tarantool Meetup 2016-08-25 (20)

PPTX
Основные кейсы использования in-memory СУБД на примере Тарантула и проектов M...
PPTX
Tarantool, .net, newsql
PDF
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
PDF
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
PDF
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
PDF
Tarantool/Silverbox (Юрий Востриков)
PDF
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
PPTX
Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)
PDF
Введение в Python и Django
PDF
Vladimir V Perepelitsa Ae Highload
PPTX
dotnext version of "Tarantool, .net, newsql"
PDF
как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков...
PPTX
Tarantool
PDF
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
PDF
Дмитрий Грошев, Фёдор Гоголев. Erlang и Haskell в production: проблемы и решения
PDF
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
PDF
Рефакторинг монолита в микросервисы на Go
PDF
Рефакторинг монолита в микросервисы на Go / Refactoring of Monolithe to Micro...
PDF
Максим Пугачев
PDF
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
Основные кейсы использования in-memory СУБД на примере Тарантула и проектов M...
Tarantool, .net, newsql
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
Tarantool/Silverbox (Юрий Востриков)
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)
Введение в Python и Django
Vladimir V Perepelitsa Ae Highload
dotnext version of "Tarantool, .net, newsql"
как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков...
Tarantool
Сетевой инженер 2.0. Что нужно знать о программируемости в корпоративной сети?
Дмитрий Грошев, Фёдор Гоголев. Erlang и Haskell в production: проблемы и решения
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Рефакторинг монолита в микросервисы на Go
Рефакторинг монолита в микросервисы на Go / Refactoring of Monolithe to Micro...
Максим Пугачев
CodeFest 2013. Лузин А. — Бэкенд-винегрет: как подружить разные ЯП на ваших с...
Ad

Tarantool Modules, Tarantool Meetup 2016-08-25

  • 1. Расширяем возможности Tarantool с помощью модулей на Lua / C / C++ Цисык Роман <roman@tarantool.org> http://tarantool.org, Mail.Ru Group
  • 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
  • 6. Tarantool — СУБД + Application Server ● Язык программирования общего назначения ● Выполнение кода рядом с данными ● Fibers, channels, sockets, JSON в СУБД! ● Динамическая загрузка кода и отладка ● Модули и приложения ● Как Go + node.js + Redis в одном флаконе
  • 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
  • 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
  • 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
  • 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“)
  • 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()
  • 20. Примеры: memcached memcached = require('memcached') local instance = memcached.create('mycache', '0.0.0.0:11211') $ printf "set key 0 60 5rnvaluern" | nc localhost 11211 STORED $ printf "get keyrn" | nc localhost 11211 VALUE key 0 5 value https://github.com/tarantool/memcached
  • 21. Примеры: tarantool-queue ● Copy-cat of beanstalkd API: – tube:put(), tube:take(), tube:ack() – tube:peek(), tube:bury(), tube:kick() ● FIFO, FIFOTTL, uTUBE, uTUBETTL local queue = require('queue') queue.create_tube(name, type, { ... }) queue.tube.tube_name:put(task_data[, opts]) queue.tube.tube_name:take([timeout]) https://github.com/tarantool/queue
  • 23. http://tarantool.org/download.html http://github.com/tarantool/modulekit $ sudo apt-get install tarantool tarantool-dev $ tarantool tarantool: version 1.6.8-671-gdd1beee type 'help' for interactive help Tarantool> 2 + 2 --- - 4 ...
  • 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
  • 26. Вызов функций из клиента tarantool> box.cfg { listen = 3313 } tarantool> mymodule = require('mymodule') tarantool> box.schema.user.grant('guest', 'execute', 'universe') Python >>> import tarantool Python >>> conn = tarantool.connect('localhost', 3313) Python >>> conn.call('mymodule.add', 1, 2) - [3]
  • 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
  • 31. Lua Stack lua_tointeger(L, 1) => 10 lua_tointeger(L, -1) => 10 lua_tostring(L, 2) => "Hello" lua_type(L,3) => LUA_TTABLE 10 "Hello" table tarantool> myfun(10, "Hello", {1, 2, 3}) 1 2 3 1 2 3 -3 -2 -1 lua_gettop(L) == 3
  • 32. Lua/C модуль: инициализация и сборка extern "C" int luaopen_luacmodule(lua_State *L) { lua_newtable(L); lua_pushcfunction(L, luacmodule_add); lua_setfield(L, -2, "add"); return 1; } $ cc luacmodule.c -o luacmodule.so -shared -fPIC -I/usr/include/tarantool http://github.com/tarantool/modulekit apt-get install tarantool-dev Lua: return { add = add }
  • 33. Lua/C модуль: загрузка $ nm -a luacmodule.so |grep luaopen 0000000000000855 T luaopen_luacmodule tarantool> require('luacmodule').add(1, 2) --- - 3 ... 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
  • 35. Runtime and Box C API Lua
  • 36. C API: файберы struct fiber *f = fiber_new("background", background_f); If (f == NULL) return -1; fiber_start(f, some, args); fiber_join(f); int background_f(va_list ap) { uint32_t space_id = va_arg(ap, uint32_t); uint32_t index_id = va_arg(ap, uint32_t); fiber_sleep(5); } Запуск файбера
  • 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 запросов на одном ядре!
  • 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
  • 42. Pure C: запуск box.schema.func.create('mylibrary.args', {language = "C"}) box.schema.user.grant('guest', 'execute', 'function', 'mylibrary.args') conn:call('mylibrary.args', 15) > --- - [15, 'hello'] ...
  • 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
  • 45. Best Practices ● Отдавайте CPU другим файберам — fiber_sleep() ● Используйте файберы и каналы ● Не используйте блокирующие сокеты ● Запускайте числодробилки в отдельных тредах ● Проверяйте fiber_testcancel() в фоновых файберах ● Создавайте как можно меньше мусора в Lua
  • 48. Порядок загрузки модулей tarantool> package.path tarantool> package.сpath ● Текущая директория ● $HOME/.luarocks/… – luarocks install --local ● /usr/share/tarantool/?.lua; /usr/lib/x86_64-linux-gnu/?.so ● /usr/share/lua/5.1/?.lua; /usr/lib/x86_64-linux-gnu/lua/5.1/?.so
  • 49. Запуск демонов ● /etc/tarantool/instances.enabled/myapp.lua - конфиг box.cfg({ slab_alloc_arena = 0.5; }) instance = require("mymodule"); instance.start() ● /usr/share/tarantool/mymodule/init.lua — код ● systemctl start tarantool@myapp ● systemctl status tarantool@myapp ● tail -f /var/log/tarantool/myapp.log
  • 51. LuaRocks ● Пакетный менеджер для Lua ● Как RubyGems, Python Eggs, CPAN, но для Lua ● Разрешает зависимости ● Работает без root прав ● Работает на любой ОС http://rocks.tarantool.org/
  • 53. Пакеты .travis.yml: env: matrix: - OS=el DIST=6 PACK=rpm - OS=fedora DIST=23 PACK=rpm - OS=ubuntu DIST=trusty PACK=deb - OS=debian DIST=stretch PACK=deb script: - git clone https://github.com/tarantool/build.git - ./build/pack/travis.sh https://github.com/tarantool/build
  • 54. Сборка пакетов на Travis CI https://github.com/tarantool/build
  • 55. Docker $ docker run -t -i tarantool/tarantool:1.7 FROM tarantool/tarantool:1.7 ADD myapp.lua / RUN luarocks install http pg mysql CMD ["tarantool", "/myapp.lua"]
  • 59. Почему Lua? ● Низкий порог вхождения ● Компактный и легко встраиватся ● Нативная поддержка coroutines ● Быстрее V8 для server-side ● Tracing JIT Сompiler
  • 61. Почему Lua? x = fun.tabulate(math.sin) :take(n) :map(function(x) return x^2 end) :sum() -- sum(sin(x)^2 for x in 0..n-1) print(x) 50.011981355266 -- skip some initilization code -- ->LOOP: 0bcaffd0 movsd [rsp+0x8], xmm7 0bcaffd6 addsd xmm4, xmm5 0bcaffda ucomisd xmm6, xmm1 0bcaffde jnb 0x0bca0028 ->6 0bcaffe4 addsd xmm6, xmm0 0bcaffe8 addsd xmm7, xmm0 0bcaffec fld qword [rsp+0x8] 0bcafff0 fsin 0bcafff2 fstp qword [rsp] 0bcafff5 movsd xmm5, [rsp] 0bcafffa mulsd xmm5, xmm5 0bcafffe jmp 0x0bcaffd0 ->LOOP ---- TRACE 1 stop -> loop