SlideShare a Scribd company logo
1 of 48
Хранимые
процедуры в NoSQL
СУБД на примере
Tarantool
Денис Линник
О чем я расскажу?
1. Хранимые процедуры как прием оптимизации
2. Tarantool: разные роли СУБД
3. Обзор основных возможностей написания хранимых процедур
4. Оптимизация и профилирование хранимых процедур
Хранимые процедуры
Преимущества:
1. Скорость
2. Переиспользование кода/сервиса
3. Сокрытие структуры данных
Недостатки:
1. Сложно поддерживать
2. «Размытие» бизнес-логики
Почему Tarantool?
Tarantool: основные потоки
1. Main transaction thread
2. WAL (write-ahead log) thread
3. Networking
Tarantool: подсистемы хранения
Memtx Vinyl
Tarantool: индексы
HASH:
1. Поиск и вставка за O(1)
2. Только для memtx
TREE:
1. Поиск и вставка за O(log(N))
2. Возможность поиска по диапозону
3. Данные отсортированы
Разные роли Tarantool
1. Persistent key-value storage
2. Transaction Cache
3. Application Server
Разные роли Tarantool
1. Persistent key-value storage
2. Transaction Cache
3. Application Server
Tarantool как application server
Преимущества:
1. Действительно быстрый
2. Встроенный Lua JIT
3. Экосистема приложений
Недостатки:
1. Сложности репликации
2. Масштабирование
Tarantool: сервис авторизации
local db = {}
function db.create()
local user_space =
box.schema.space.create(‘auth_user’, {
engine = ‘memtx’,
if_not_exists = true,
})
...
end
return db
local db = {}
function db.create()
local user_space =
box.schema.space.create(‘auth_user’, {
engine = ‘memtx’,
if_not_exists = true,
})
...
end
return db
local db = {}
function db.create()
...
user_space:create_index(‘primary’, {
type = ‘hash’,
parts = {1, ‘string’},
if_not_exists = true,
})
...
end
return db
local db = {}
function db.create()
...
user_space:create_index(‘email’, {
type = ‘tree’,
parts = {2, ‘string’, 3, ‘unsigned’},
if_not_exists = true,
unique = false,
})
end
return db
local auth = {}
function auth.api(config)
api = {}
db.create()
function api.registration(email)
...
end
return api
end
return auth
local auth = {}
function auth.api(config)
api = {}
db.create()
function api.registration(email)
...
end
return api
end
return auth
function api.registration(email)
local user_tuple
user_tuple = box.space.auth_user.index
.email:select({email, COMMON_USER})
if user_tuple == nil then
return false, ‘user_already_exists’
end
...
end
function api.registration(email)
...
user_tuple = box.space.auth_user:insert({
uuid.str(), email, COMMON_USER
})
return true, user_tuple
end
box.cfg({
listen = 3301
})
...
local config = {...}
auth = require(‘auth’).api(config)
Запуск Tarantool
$ tarantoolctl start auth
$ tarantoolctl enter auth
tarantool> ok, user =
auth.registration(‘example@mail.ru’)
-- Как обратиться к auth из кода, например, Python?
async def run():
conn = asynctnt.Connection(
host=‘...’, port=‘...’, username=‘...’
)
values = await conn.call(
‘auth.registrtion’, [‘exaples@mail.ru’]
)
await conn.disconnect()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
Tarantool: сервис авторизации
local http_client = require(‘http.client’)
function api.social_registration(code, provider)
...
local ok, msg, response
ok, msg = pcall(
response = http_client.post(url, body, {
headers = {...},
timeout = timeout,
})
)
...
end
Tarantool queue
-- Установка: tarantoolctl rocks install queue
local queue = require('queue')
local registration_queue =
queue.create_tube('registration_queue', 'fifo')
registration_queue:put({‘example@mail.ru'})
local task = registration_queue:take()
Tarantool: миграция данных
uuid email type
550e8400-e29b... example@mail.ru 1
uuid email type gender
550e8400-e29b... example@mail.ru 1 0
local function migrations()
if box.cfg.read_only == false then
box.once('20171101_add_gender', function ()
...
end)
end
end
migrations()
local counter = 0
for _, tuple in box.space.auth_user:pairs(
nil, {iterator=box.index.ALL}
) do
local user_tuple = tuple:totable()
user_tuple[4] = get_user_gender(...)
box.space.auth_user:replace(user_tuple)
counter = counter + 1
if counter % 10000 == 0 then
fiber.sleep(0)
end
end
local counter = 0
for _, tuple in box.space.auth_user:pairs(
nil, {iterator=box.index.ALL}
) do
local user_tuple = tuple:totable()
user_tuple[4] = get_user_gender(...)
box.space.auth_user:replace(user_tuple)
counter = counter + 1
if counter % 10000 == 0 then
fiber.sleep(0)
end
end
Tarantool: оптимизация хранимых
процедур
Задача:
Посчитать количество мужчин и женщин,
зарегистрированных в системе. Подобрать наиболее
эффективный способ.
local result = {male = 0, female = 0}
for _, tuple in box.space.auth_user:pairs(
nil, {iterator=box.index.ALL}
) do
if tuple[4] == 0 then
result['female'] = result['female'] + 1
else
result['male'] = result['male'] + 1
end
end
local result = {male = 0, female = 0}
for _, tuple in box.space.auth_user:pairs(
nil, {iterator=box.index.ALL}
) do
if tuple[4] == 0 then
result['female'] = result['female'] + 1
else
result['male'] = result['male'] + 1
end
end
for _, tuple in box.space.auth_user:pairs(
nil, {iterator=box.index.ALL}) do
if tuple[4] == 0 then
female = female + 1
else
male = male + 1
end
end
local result = {
male = male,
female = female,
}
LUA_API int
luaopen_count_genders(lua_State *L) {
lua_newtable(L);
static const struct luaL_Reg meta [] = {
{"count", count},
{NULL, NULL}
};
luaL_register(L, NULL, meta);
return 1;
}
static int count(lua_State *L) {
uint32_t space_id = lua_tonumber(L, 1);
uint32_t index_id = box_index_id_by_name(
space_id, "primary", strlen("primary")
);
...
}
static int count(lua_State *L) {
uint32_t space_id = lua_tonumber(L, 1);
uint32_t index_id = box_index_id_by_name(
space_id, "primary", strlen("primary")
);
...
}
static int count(lua_State *L) {
...
char key[1024];
char *key_p = key;
key_p = mp_encode_array(key_p, 0);
box_iterator_t *iterator = box_index_iterator(
space_id, index_id, ITER_ALL, key, key_p
);
...
box_iterator_free(iterator);
}
static int count(lua_State *L) {
...
while (box_iterator_next(iterator, &tuple) != -1) {
if(!tuple) {
break;
}
box_tuple_iterator_t *tuple_iterator;
tuple_iterator = box_tuple_iterator(tuple);
...
box_tuple_iterator_free(tuple_iterator);
}
...
}
static int count(lua_State *L) {
...
while (box_iterator_next(iterator, &tuple) != -1) {
...
field = box_tuple_seek(tuple_iterator, 3);
int gender = (int)mp_decode_uint(&field);
if(gender == 1) { ... }
...
}
...
}
Tarantool: результаты оптимизации
Lua (JIT отключен): 8,99с
Lua (JIT включен): 2,33с
C: 0,40 с
Tarantool: профилирование
local cpuprof = require('gperftools.cpu')
cpuprof.start('/tmp/profile')
for i = 1, ITERATIONS do
count_genders.count()
end
cpuprof.stop()
cpuprof.flush()
Tarantool: профилирование C
4635 53.9% tuple_bless (inline)
327 3.8% mslab_free
300 3.5% count
260 3.0% mp_next (inline)
252 2.9% box_iterator_next
250 2.9% mempool_alloc
233 2.7% mp_load_u8 (inline)
201 2.3% box_tuple_iterator_free
...
Tarantool: профилирование C
4635 53.9% tuple_bless (inline)
327 3.8% mslab_free
300 3.5% count
260 3.0% mp_next (inline)
252 2.9% box_iterator_next
250 2.9% mempool_alloc
233 2.7% mp_load_u8 (inline)
201 2.3% box_tuple_iterator_free
...
Tarantool: профилирование Lua
597 11.0% lj_obj_equal
542 10.0% tuple_unref (inline)
517 9.5% tuple_bless (inline)
414 7.6% lj_tab_newkey
282 5.2% clearhpart (inline)
215 4.0% lj_tab_set
135 2.5% gc_traverse_tab (inline)
124 2.3% hashkey.isra.0
...
Tarantool: профилирование Lua
597 11.0% lj_obj_equal
542 10.0% tuple_unref (inline)
517 9.5% tuple_bless (inline)
414 7.6% lj_tab_newkey
282 5.2% clearhpart (inline)
215 4.0% lj_tab_set
135 2.5% gc_traverse_tab (inline)
124 2.3% hashkey.isra.0
...
Tarantool: хранимые процедуры
1. Хранимые процедуры позволяют избежать передачи лишних
данных и сэкономить на сетевых задержках.
2. Tarantool развивает экосистему приложений и обладает
богатым набором готовых инструментов для реализации
многих задач.
3. Профилирование кода хранимых процедур – еще один способ
понять, как оптимизировать работу сервиса.
Tarantool: что дальше?
1. fiber
2. sharding
3. replication
4. SQL
5. transactions
6. rocks
7. tap.test
8. ...
Полезные ссылки
1. https://github.com/mailru/tarantool-authman
2. https://github.com/igorcoding/asynctnt
3. https://t.me/tarantoolru

More Related Content

What's hot

Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILRoman Brovko
 
Python. Объектно-ориентированное программирование
Python. Объектно-ориентированное программирование Python. Объектно-ориентированное программирование
Python. Объектно-ориентированное программирование Theoretical mechanics department
 
CPU Performance in Java.
CPU Performance in Java.CPU Performance in Java.
CPU Performance in Java.Dzmitry Hil
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.Roman Brovko
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Roman Brovko
 
Лекция 10. Классы 2.
Лекция 10. Классы 2.Лекция 10. Классы 2.
Лекция 10. Классы 2.Roman Brovko
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателейDEVTYPE
 
C++ и базы данных
C++ и базы данныхC++ и базы данных
C++ и базы данныхmcroitor
 
Python dict: прошлое, настоящее, будущее
Python dict: прошлое, настоящее, будущееPython dict: прошлое, настоящее, будущее
Python dict: прошлое, настоящее, будущееdelimitry
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Roman Brovko
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиMikhail Kurnosov
 
Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 

What's hot (20)

Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
лек9 10
лек9 10лек9 10
лек9 10
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
Лекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GILЛекция 13. Многопоточность и GIL
Лекция 13. Многопоточность и GIL
 
Основы Python. Функции
Основы Python. ФункцииОсновы Python. Функции
Основы Python. Функции
 
Основы NumPy
Основы NumPyОсновы NumPy
Основы NumPy
 
Python. Объектно-ориентированное программирование
Python. Объектно-ориентированное программирование Python. Объектно-ориентированное программирование
Python. Объектно-ориентированное программирование
 
CPU Performance in Java.
CPU Performance in Java.CPU Performance in Java.
CPU Performance in Java.
 
Лекция 1. Начало.
Лекция 1. Начало.Лекция 1. Начало.
Лекция 1. Начало.
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.Лекция 2. Всё, что вы хотели знать о функциях в Python.
Лекция 2. Всё, что вы хотели знать о функциях в Python.
 
Основы SciPy
Основы SciPyОсновы SciPy
Основы SciPy
 
Python: ввод и вывод
Python: ввод и выводPython: ввод и вывод
Python: ввод и вывод
 
Лекция 10. Классы 2.
Лекция 10. Классы 2.Лекция 10. Классы 2.
Лекция 10. Классы 2.
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателей
 
C++ и базы данных
C++ и базы данныхC++ и базы данных
C++ и базы данных
 
Python dict: прошлое, настоящее, будущее
Python dict: прошлое, настоящее, будущееPython dict: прошлое, настоящее, будущее
Python dict: прошлое, настоящее, будущее
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 12. Быстрее, Python, ещё быстрее.
 
Лекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные спискиЛекция 3: Бинарный поиск. Связные списки
Лекция 3: Бинарный поиск. Связные списки
 
Something about Golang
Something about GolangSomething about Golang
Something about Golang
 

Similar to Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)

Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?tfmailru
 
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...Ontico
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)Smolensk Computer Science Club
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Ontico
 
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Roman Tsisyk
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?tfmailru
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в TarantoolTimur Safin
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#Dmitri Soshnikov
 
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Yandex
 

Similar to Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru) (20)

Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
 
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
 
Sphinx search
Sphinx searchSphinx search
Sphinx search
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)8 встреча — Язык программирования Python (В. Ананьев)
8 встреча — Язык программирования Python (В. Ананьев)
 
Charming python sc2-8
Charming python sc2-8Charming python sc2-8
Charming python sc2-8
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
 
C language. Introduction
C language. IntroductionC language. Introduction
C language. Introduction
 
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Rgsu04
Rgsu04Rgsu04
Rgsu04
 
Algo 00
Algo 00Algo 00
Algo 00
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кодаSECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
 
Язык программирования C#
Язык программирования C#Язык программирования C#
Язык программирования C#
 
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
 

More from Ontico

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...Ontico
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Ontico
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Ontico
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Ontico
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Ontico
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)Ontico
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Ontico
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Ontico
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)Ontico
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)Ontico
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Ontico
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Ontico
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Ontico
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Ontico
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)Ontico
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Ontico
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...Ontico
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Ontico
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Ontico
 

More from Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 

Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)

  • 1. Хранимые процедуры в NoSQL СУБД на примере Tarantool Денис Линник
  • 2. О чем я расскажу? 1. Хранимые процедуры как прием оптимизации 2. Tarantool: разные роли СУБД 3. Обзор основных возможностей написания хранимых процедур 4. Оптимизация и профилирование хранимых процедур
  • 3. Хранимые процедуры Преимущества: 1. Скорость 2. Переиспользование кода/сервиса 3. Сокрытие структуры данных Недостатки: 1. Сложно поддерживать 2. «Размытие» бизнес-логики
  • 5. Tarantool: основные потоки 1. Main transaction thread 2. WAL (write-ahead log) thread 3. Networking
  • 7. Tarantool: индексы HASH: 1. Поиск и вставка за O(1) 2. Только для memtx TREE: 1. Поиск и вставка за O(log(N)) 2. Возможность поиска по диапозону 3. Данные отсортированы
  • 8. Разные роли Tarantool 1. Persistent key-value storage 2. Transaction Cache 3. Application Server
  • 9. Разные роли Tarantool 1. Persistent key-value storage 2. Transaction Cache 3. Application Server
  • 10. Tarantool как application server Преимущества: 1. Действительно быстрый 2. Встроенный Lua JIT 3. Экосистема приложений Недостатки: 1. Сложности репликации 2. Масштабирование
  • 12. local db = {} function db.create() local user_space = box.schema.space.create(‘auth_user’, { engine = ‘memtx’, if_not_exists = true, }) ... end return db
  • 13. local db = {} function db.create() local user_space = box.schema.space.create(‘auth_user’, { engine = ‘memtx’, if_not_exists = true, }) ... end return db
  • 14. local db = {} function db.create() ... user_space:create_index(‘primary’, { type = ‘hash’, parts = {1, ‘string’}, if_not_exists = true, }) ... end return db
  • 15. local db = {} function db.create() ... user_space:create_index(‘email’, { type = ‘tree’, parts = {2, ‘string’, 3, ‘unsigned’}, if_not_exists = true, unique = false, }) end return db
  • 16. local auth = {} function auth.api(config) api = {} db.create() function api.registration(email) ... end return api end return auth
  • 17. local auth = {} function auth.api(config) api = {} db.create() function api.registration(email) ... end return api end return auth
  • 18. function api.registration(email) local user_tuple user_tuple = box.space.auth_user.index .email:select({email, COMMON_USER}) if user_tuple == nil then return false, ‘user_already_exists’ end ... end
  • 19. function api.registration(email) ... user_tuple = box.space.auth_user:insert({ uuid.str(), email, COMMON_USER }) return true, user_tuple end
  • 20. box.cfg({ listen = 3301 }) ... local config = {...} auth = require(‘auth’).api(config)
  • 21. Запуск Tarantool $ tarantoolctl start auth $ tarantoolctl enter auth tarantool> ok, user = auth.registration(‘example@mail.ru’) -- Как обратиться к auth из кода, например, Python?
  • 22. async def run(): conn = asynctnt.Connection( host=‘...’, port=‘...’, username=‘...’ ) values = await conn.call( ‘auth.registrtion’, [‘exaples@mail.ru’] ) await conn.disconnect() loop = asyncio.get_event_loop() loop.run_until_complete(run())
  • 24. local http_client = require(‘http.client’) function api.social_registration(code, provider) ... local ok, msg, response ok, msg = pcall( response = http_client.post(url, body, { headers = {...}, timeout = timeout, }) ) ... end
  • 25. Tarantool queue -- Установка: tarantoolctl rocks install queue local queue = require('queue') local registration_queue = queue.create_tube('registration_queue', 'fifo') registration_queue:put({‘example@mail.ru'}) local task = registration_queue:take()
  • 26. Tarantool: миграция данных uuid email type 550e8400-e29b... example@mail.ru 1 uuid email type gender 550e8400-e29b... example@mail.ru 1 0
  • 27. local function migrations() if box.cfg.read_only == false then box.once('20171101_add_gender', function () ... end) end end migrations()
  • 28. local counter = 0 for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL} ) do local user_tuple = tuple:totable() user_tuple[4] = get_user_gender(...) box.space.auth_user:replace(user_tuple) counter = counter + 1 if counter % 10000 == 0 then fiber.sleep(0) end end
  • 29. local counter = 0 for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL} ) do local user_tuple = tuple:totable() user_tuple[4] = get_user_gender(...) box.space.auth_user:replace(user_tuple) counter = counter + 1 if counter % 10000 == 0 then fiber.sleep(0) end end
  • 30. Tarantool: оптимизация хранимых процедур Задача: Посчитать количество мужчин и женщин, зарегистрированных в системе. Подобрать наиболее эффективный способ.
  • 31. local result = {male = 0, female = 0} for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL} ) do if tuple[4] == 0 then result['female'] = result['female'] + 1 else result['male'] = result['male'] + 1 end end
  • 32. local result = {male = 0, female = 0} for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL} ) do if tuple[4] == 0 then result['female'] = result['female'] + 1 else result['male'] = result['male'] + 1 end end
  • 33. for _, tuple in box.space.auth_user:pairs( nil, {iterator=box.index.ALL}) do if tuple[4] == 0 then female = female + 1 else male = male + 1 end end local result = { male = male, female = female, }
  • 34. LUA_API int luaopen_count_genders(lua_State *L) { lua_newtable(L); static const struct luaL_Reg meta [] = { {"count", count}, {NULL, NULL} }; luaL_register(L, NULL, meta); return 1; }
  • 35. static int count(lua_State *L) { uint32_t space_id = lua_tonumber(L, 1); uint32_t index_id = box_index_id_by_name( space_id, "primary", strlen("primary") ); ... }
  • 36. static int count(lua_State *L) { uint32_t space_id = lua_tonumber(L, 1); uint32_t index_id = box_index_id_by_name( space_id, "primary", strlen("primary") ); ... }
  • 37. static int count(lua_State *L) { ... char key[1024]; char *key_p = key; key_p = mp_encode_array(key_p, 0); box_iterator_t *iterator = box_index_iterator( space_id, index_id, ITER_ALL, key, key_p ); ... box_iterator_free(iterator); }
  • 38. static int count(lua_State *L) { ... while (box_iterator_next(iterator, &tuple) != -1) { if(!tuple) { break; } box_tuple_iterator_t *tuple_iterator; tuple_iterator = box_tuple_iterator(tuple); ... box_tuple_iterator_free(tuple_iterator); } ... }
  • 39. static int count(lua_State *L) { ... while (box_iterator_next(iterator, &tuple) != -1) { ... field = box_tuple_seek(tuple_iterator, 3); int gender = (int)mp_decode_uint(&field); if(gender == 1) { ... } ... } ... }
  • 40. Tarantool: результаты оптимизации Lua (JIT отключен): 8,99с Lua (JIT включен): 2,33с C: 0,40 с
  • 41. Tarantool: профилирование local cpuprof = require('gperftools.cpu') cpuprof.start('/tmp/profile') for i = 1, ITERATIONS do count_genders.count() end cpuprof.stop() cpuprof.flush()
  • 42. Tarantool: профилирование C 4635 53.9% tuple_bless (inline) 327 3.8% mslab_free 300 3.5% count 260 3.0% mp_next (inline) 252 2.9% box_iterator_next 250 2.9% mempool_alloc 233 2.7% mp_load_u8 (inline) 201 2.3% box_tuple_iterator_free ...
  • 43. Tarantool: профилирование C 4635 53.9% tuple_bless (inline) 327 3.8% mslab_free 300 3.5% count 260 3.0% mp_next (inline) 252 2.9% box_iterator_next 250 2.9% mempool_alloc 233 2.7% mp_load_u8 (inline) 201 2.3% box_tuple_iterator_free ...
  • 44. Tarantool: профилирование Lua 597 11.0% lj_obj_equal 542 10.0% tuple_unref (inline) 517 9.5% tuple_bless (inline) 414 7.6% lj_tab_newkey 282 5.2% clearhpart (inline) 215 4.0% lj_tab_set 135 2.5% gc_traverse_tab (inline) 124 2.3% hashkey.isra.0 ...
  • 45. Tarantool: профилирование Lua 597 11.0% lj_obj_equal 542 10.0% tuple_unref (inline) 517 9.5% tuple_bless (inline) 414 7.6% lj_tab_newkey 282 5.2% clearhpart (inline) 215 4.0% lj_tab_set 135 2.5% gc_traverse_tab (inline) 124 2.3% hashkey.isra.0 ...
  • 46. Tarantool: хранимые процедуры 1. Хранимые процедуры позволяют избежать передачи лишних данных и сэкономить на сетевых задержках. 2. Tarantool развивает экосистему приложений и обладает богатым набором готовых инструментов для реализации многих задач. 3. Профилирование кода хранимых процедур – еще один способ понять, как оптимизировать работу сервиса.
  • 47. Tarantool: что дальше? 1. fiber 2. sharding 3. replication 4. SQL 5. transactions 6. rocks 7. tap.test 8. ...
  • 48. Полезные ссылки 1. https://github.com/mailru/tarantool-authman 2. https://github.com/igorcoding/asynctnt 3. https://t.me/tarantoolru