30
load balancing и оптимальная загрузка кластера Андрей Свелов [email protected]

Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Embed Size (px)

Citation preview

Page 1: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

load balancing и оптимальная загрузка кластера

Андрей Свелов[email protected]

Page 2: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

● Пишу на Python с 1999 года● Python Code Developer● Соавтор asyncio, aiohttp и ещё дюжины

библиотек● Работаю в DataRobot

Page 3: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Простейшая схема развертывания

Browser Server

Page 4: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Проблемы:

1. Статика

Page 5: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Проблемы:

1. Статика2. Безопасность

Page 6: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Reverse proxy

Browser Application Server

Reverse proxyaka NGINX, HAProxy etc

Page 7: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Конфигурация NGINX:http {

server {

location /static {

root /www/static;

}

location / {

proxy_pass http://127.0.0.7:8080;

}

}

}

Page 8: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Балансировка на несколько app servers:

Browser Reverse proxy

Page 9: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Конфигурация NGINX:server {

upstream backend {

server http://127.0.0.7:8080;

server http://127.0.0.7:8081;

}

location / {

proxy_pass http://backend;

}

}

Page 10: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Round Robin:

Reverse proxy

1

2

3

Page 11: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Ситуация:

1. В DataRobot делаем предсказания на обученых моделях2. Предсказание занимает в 20-600 милисекунд в среднем.3. Модель может "весить" гигабайт(ы).4. Загрузка модели в память требует в 10-30 раз больше времени.Хочу чтобы запрос шел на сервер с уже загруженной моделью.

Page 12: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Каждому узлу -- по своей модели:

Node 1

Reverse proxy Node 2

Model 1

Model 2

Model 3

Model 4

Page 13: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Особенность:

url = "/v1/<project_id>/<model_id>/predict"

Удобный hash key

Page 14: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

URL Hash как решение:

upstream = servers[hash(url) % len(servers)]

Page 15: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Конфигурация NGINX:server {

upstream backend {

hash $request_uri; server http://127.0.0.7:8080;

server http://127.0.0.7:8081;

}

location / {

proxy_pass http://backend;

}

}

Page 16: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

URL Hash как плохое решение:

upstream = servers[hash(url) % len(servers)]

Если один сервер умирает -- вся система требует перебалансировки.

Page 17: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Пропадание узла:4 сервера, 12 объектов 3 сервера, 12 объектов

Page 18: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Consistent hash:

Page 19: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Consistent hash 2:

Page 20: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Конфигурация NGINX:server {

upstream backend {

consistent_hash $request_uri; server http://127.0.0.7:8080;

server http://127.0.0.7:8081;

}

location / {

proxy_pass http://backend;

}

}

Page 21: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Sticky sessions:

HTTP cookie based upstream selection

Page 22: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Всё это классно, но нам не годится:

● Нужен лучший контроль над выбором upstream

● Велосипедим сами

Page 23: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Самодельный контроллер

NGINX

Controller

Node 1

Node 2

Page 24: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Конфигурация NGINX:server {

location / {

set $upstream "<placeholder>";

rewrite_by_lua '

ctrl = require("controller")

ngx.var.upstream = ctrl.get(ngx.var.uri,

"unix://tmp/ctrl.sock")

';

proxy_pass http://$upstream;

}

}

Page 25: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

LUA:function get(uri, sock_path)

local sock = ngx.socket.connect(sock_path)

local buf = pack("<HB", string.len(uri)+1, 1)

sock:send({buf, uri})

local resp_len_buf = sock:receive(3)

local resp_len, resp_code = unpack("<HB", resp_len_buf)

local upstream = sock:receive(resp_len - 1)

sock:setkeepalive()

return upstream

end

Page 26: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Контроллер:

● asyncio UNIX/TCP сервер● данные -- в REDIS slave

Page 27: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Управление:

● REST сервер -- конфигурирование● Sentinel -- наблюдение

Page 28: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Результат:

● Емкость кластера х4● Утилизация серверов х3 (75%)

Page 29: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Ищем сотрудников в Минский офис

http://datarobot.com● Python backend● JavaScript frontend● DevOps● Data Science

Page 30: Андрей Светлов-«Делаем своё решение для оптимальной загрузки кластера»

Вопросы?

Андрей Светлов[email protected]