43

Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Embed Size (px)

Citation preview

Page 1: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Page 2: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Agenda

Что представляет из себя Tarantool в 2016 году

Как подружить Nginx и Tarantool

Как сделать REST API на чистой СУБД

Как это используется в production

Бенчмарки и цифры

Page 3: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Tarantool

Tuple storage

ACID Transactions

Write ahead log

Lua application server

Ecosystem

Page 4: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Ecosystem

Page 5: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Building blocks

Page 6: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

How to build?

Shard

Avro Schema

Nginx upstream module

Page 7: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Shard function

Page 8: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Shard gossip

Page 9: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Shardlocal cfg = {

servers = {

{ uri = 'host1:3301', zone = 'z1' };

{ uri = 'host2:3301', zone = 'z2' };

};

login = 'my_user';

password = 'i_love_bananas';

redundancy = 2;

binary = 3301;

}

Page 10: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Nginxupstream tnt { server host.com:4301 max_fails=1; server host.com:4302 max_fails=1; server host.com:4303 max_fails=1; }

location /api { tnt_http_rest_methods get delete; tnt_http_methods all; tnt_multireturn_skip_count 2; tnt_pure_result on; tnt_pass_http_request on parse_args; tnt_pass tnt; } }

Page 11: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Nginx

function square(request, a) return {result=a*a}end

Page 12: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

NginxPOST http://host.com/apiBODY:{ "id": 0, "method": "squire" "params": [5]}

RESPONSE:{ "result": 25}

Page 13: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

JSON RPC

Page 14: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Схемы Avro{ "First": "John", "Last": "Doe" }

{ "name": "Person", "type": "record", "fields": [

{ "name": "First", "type": "string" },

{ "name": "Last", "type": "string" } ] }

Хранится как: ["John", "Doe"]

Page 15: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

[ "John", "Doe", "Was here!" ]

{ "First": "John", "Last": "Doe" "Notes": "Was here!" }

V2 V2

Versions

Page 16: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

[ "John", "Doe", "Was here!" ]

{ "First": "Jane", "Last": "Doe" }

V2 V1

Versions

Page 17: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

[ "Jane", "Doe" ]

{ "First": "Jane", "Last": "Doe" "Notes": "" }

V1 V2

Versions

Page 18: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Compiler

• Apache implementation (too slow)

• Code generation?

• LuaJIT

• LLVM

Page 19: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

RPS (×1000)

500

1000

1500

2000

Baseline (C) Codegen (LuaJIT)

Interpretor

JIT

Page 20: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

RPS (×1000)

500

1000

1500

2000

2500

3000

3500

Baseline (C) Codegen (LuaJIT) Codegen (LLVM)

Page 21: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

REST API

Page 22: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Примеры архитектур

• Одноуровневая система с репликацией

• Отдельно приложение, отдельно хранение (shard)

• Хранение по ttl (expirationd)

• Совместное хранение в памяти и на диске(vinyl)

Page 23: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Use cases• Виртуализация данных

• Роутинг запросов в биллинге

• Обогащение данных от источника

• Интеграция с legacy проектами

• Объединение данных от нескольких источников

Page 24: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

BenchЖелезо

4 ядра 2,6 GHz

64 GB оперативной памяти

Данные

100 ГБ данных, размер запроса 2 КБ(JSON)

избыточность(2 датацентра)

Кластер

4 storage сервера(16 инстансов tarantool)

4 application сервера(16 инстансов tarantool)

Клиентские машины для создания нагрузки

Page 25: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Read

Page 26: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Write

Page 27: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Node

Page 28: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Подводные камни• Нужно описать логику преобразования версий

• Нужно написать хранимые процедуры под каждый тип запроса

• Нужно связывать авро схему и индексы в tuple

• Удобно иметь связи между схемами

• Удобно создавать простые API автоматически (не программируя на lua)

Page 29: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Tarantino

Page 30: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Что это дает?• Автоматическая настройка tarantool

• Вся конфигурация - один json файл

• Версионирование запросов на лету

• Хранится только актуальная версия

• Иерархические связи между схемами

• Не нужно программировать на lua

Page 31: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Пример конфигурации{ "memory": 30, "port": 3301, "index": [ "user":["uid"], "device":["uid", "sno"] ], "relations": { "user": ["device"] } "api": { "v1": { "user":{}, "device":{} ] } }

Page 32: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Что произойдет внутри?box.cfg{ slab_alloc_arena=30, listen=3301 wal_mode=«write» } box.schema.create_space(«user») box.space.user:create_index(…) box.schema.create_space(«device») box.space.device:create_index(…)

Page 33: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Что произойдет снаружи?• /api/v1/user/1

• /api/v1/user?limit=100&offset=0

• /api/v1/device/1/1

• /api/v1/device?limit=100&offset=0

• /api/v1/user/1/?related=prefetch

Page 34: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Join{ "uid": 1, "First": «John", "Last": «Doe" "device": [ { "uid": 1, "sno": 1, "name":"myD", } ] }

Page 35: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Популярные фреймворки

Page 36: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Производительность

• 4 ядра 2,6 GHz

• 2кб данных на один запрос

• Преобразование версии во время запроса

Page 37: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Запись

Page 38: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Запись

Page 39: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Чтение

Page 40: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Чтение

Page 41: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Производительность 4 ядра

Чтение: 120000 rps Запись: 80000 rps

Page 42: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Use cases• Легковесные restful сервисы

• Бекенды для мобильных приложений

• Выкатывание нескольких версий приложения одновременно

• Scientific приложения (анализ данных) - хранение грязных и чистых данных в разных версиях

Page 43: Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"

Спасибо за внимание

• http://tarantool.org

• https://github.com/tarantool/avro-schema

• http://avro.apache.org/docs/1.8.0/spec.html