HighLoad++ 2017
Зал «Найроби + Касабланка», 8 ноября, 11:00
Тезисы:
http://www.highload.ru/2017/abstracts/2950.html
Одним из приемов, позволяющих увеличить скорость обработки и получения данных, является написание хранимых процедур. В этом докладе будут рассмотрены преимущества и недостатки такого подхода на примере Tarantool.
Tarantool можно рассматривать как полноценный application server. При таком подходе к разработке приложения, запущенные на Tarantool, можно рассматривать как микросервисы.
...
2. О чем я расскажу?
1. Хранимые процедуры как прием оптимизации
2. Tarantool: разные роли СУБД
3. Обзор основных возможностей написания хранимых процедур
4. Оптимизация и профилирование хранимых процедур
7. Tarantool: индексы
HASH:
1. Поиск и вставка за O(1)
2. Только для memtx
TREE:
1. Поиск и вставка за O(log(N))
2. Возможность поиска по диапозону
3. Данные отсортированы
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
21. Запуск Tarantool
$ tarantoolctl start auth
$ tarantoolctl enter auth
tarantool> ok, user =
auth.registration(‘example@mail.ru’)
-- Как обратиться к auth из кода, например, Python?
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
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,
}
41. Tarantool: профилирование
local cpuprof = require('gperftools.cpu')
cpuprof.start('/tmp/profile')
for i = 1, ITERATIONS do
count_genders.count()
end
cpuprof.stop()
cpuprof.flush()
46. Tarantool: хранимые процедуры
1. Хранимые процедуры позволяют избежать передачи лишних
данных и сэкономить на сетевых задержках.
2. Tarantool развивает экосистему приложений и обладает
богатым набором готовых инструментов для реализации
многих задач.
3. Профилирование кода хранимых процедур – еще один способ
понять, как оптимизировать работу сервиса.