tempesta fw: challenges, internals, use cases / Александр Крижановский...
TRANSCRIPT
Tempesta FW: challenges, internals,use cases
Александр Крижановский
Привет :)• Tempesta Technologies — с 2014, подразделение
NatSys Lab
• NatSys Lab — с 2008, разработка высокопроизводительных систем
– хранения
– обработки сетевого трафика
• Сделали cамую быструю реализацию lock-free очереди задач (Linux Journal, Jun 12, 2013)
• Исследовали производительность Intel TSX
Challenges (Зачем?)• Современный Internet бывает зол
• Но есть Web-рыцари добра и света
Challenges (Зачем?)• Современный Internet бывает зол
• Но есть Web-рыцари добра и света
• .., которые фильтруют плохие запросы
Рыцарь WAF• Оружие: XHTML, WSDL, Machine learning, Regexps
• Платформа: Nginx, Apache Traffic Server etc.
Пример: Nginx + regexps
0 5000 10000 15000 20000 25000 30000 350000
5000
10000
15000
20000
25000
30000
4168 4133
6855
HyperScanVanilla NginxPCRE-JIT
Target RPS
Act
ua
l RP
S
Результат: WAF 15K HTTP RPS на 24 ядрах (а хочется >100KRPS)
Снова об акселерации
Рыцарь Anti-DDoS CDN• Оружие: DPI или Firewall + Machine Learning
• Платформа: Nginx
Application layer DDoSService from Cache Rate limit
Nginx 22us 23us
Application layer DDoSService from Cache Rate limit
Nginx 22us 23us
• Fail2Ban: пишем файл, парсим файл, пишем файл, парсим файл…
Application layer DDoSService from Cache Rate limit
Nginx 22us 23us
• Fail2Ban: пишем файл, парсим файл, пишем файл, парсим файл… - 21й век?!
Что не может Web-сервер?• Фильтровать DDoS трафик
– мелкие запросы
– флуды
Что не может Web-сервер?• Фильтровать DDoS трафик
– мелкие запросы
– флуды
• Быстро работать (c10k => c100k) ??!!
Профиль Web-сервера % symbol name
1.5719 ngx_http_parse_header_line
1.0303 ngx_vslprintf
0.6401 memcpy
0.5807 recv
0.5156 ngx_linux_sendfile_chain
0.4990 ngx_http_limit_req_handler
+ довольно длинный хвост
Вызовы Web-сервераepoll_wait(.., {{EPOLLIN, ....}},...)
recvfrom(3, "GET / HTTP/1.1\r\nHost:...", ...)
// parse HTTP
write(1, “...limiting requests, excess...", ...)
writev(3, "HTTP/1.1 503 Service...", ...)
sendfile(3,..., 383)
recvfrom(3, ...) = -1 EAGAIN
epoll_wait(.., {{EPOLLIN, ....}}, ...)
recvfrom(3, "", 1024, 0, NULL, NULL) = 0
close(3)
HTTP парсерStart: state = 1, *str_ptr = 'b'
while (++str_ptr) { switch (state) { <= check state case 1: switch (*str_ptr) { case 'a': ... state = 1 case 'b': ... state = 2 } case 2: ... } ... }
HTTP парсерStart: state = 1, *str_ptr = 'b'
while (++str_ptr) { switch (state) { case 1: switch (*str_ptr) { case 'a': ... state = 1 case 'b': ... state = 2 <= set state } case 2: ... } ... }
HTTP парсерStart: state = 1, *str_ptr = 'b'
while (++str_ptr) { switch (state) { case 1: switch (*str_ptr) { case 'a': ... state = 1 case 'b': ... state = 2 } case 2: ... } ... <= jump to while }
HTTP парсерStart: state = 1, *str_ptr = 'b'
while (++str_ptr) { switch (state) { <= check state case 1: switch (*str_ptr) { case 'a': ... state = 1 case 'b': ... state = 2 } case 2: ... } ... }
HTTP парсерStart: state = 1, *str_ptr = 'b'
while (++str_ptr) { switch (state) { case 1: switch (*str_ptr) { case 'a': ... state = 1 case 'b': ... state = 2 } case 2: ... <= do something } ... }
HTTP парсер
Асинхронный I/O
Асинхронный I/O
Асинхронный I/O
Асинхронный I/O
Итого: Web-сервер• Медленный HTTP парсинг
• Контекст свитчи
• Копирование
• Асинхронная модель I/O
• Файлы и файловые дескрипторы
• Web-cache не имеет представления о NUMA
Linux?
Linux zero-copy I/O - мифtcp_transmit_skb(sock *sk, sk_buff *skb, int clone_it, ...){ ... if (likely(clone_it)) skb = pskb_copy(skb, gfp_mask); else skb = skb_clone(skb, gfp_mask);
...
}
Что делают современники?“...standard servers running an in-house OS. The key to achieve that performance was to disable IRQs, no syscalls, no context switching, no kernel, no memcopy, new stack etc. Basically in few hundreds ticks a packet hits the nginx or whatever application runs on it.”
User-space TCP/IP (~Exokernel ОС)
• Sandstorm
– Netmap
– Специализированный TCP/IP стек:● Web-сервер «знает» о пакетах● преаллокация пакетов
– syscall batching (latency)
• mTCP (http://shader.kaist.edu/mtcp/)
– PSIO, DPDK
– TCP/IP stack from scratch (~15KoL, linux >130KoL)
Итого: User- vs Kernel-space• Проблемы Web-сервера не уходят
(прикладной уровень не «знает» о сетевом)
• Все равно есть syscall'ы (немного)
• Фиксированный размер буферов
• Неконтролируемое вытеснение(lock-free, RCU, spinlock)
• Большой дублирующий пласт кода
И снова синхронизация...
И снова синхронизация...
...приходим к тем же локам и копированиям
Не только TCP/IP, но и СУБД• Web-cache
• Сессии
• Правила фильтрации
• Web Application Server: вообще что угодно
• WAF & DDoS mitigation: модели обучения и пр.
Что делают разработчики СУБД?
• Buffer pool (page cache в ОС)
• Планирование I/O ( --''-- в ОС)
• Префетчинг блоков ( --''-- в ОС)
• Транзакционный лог ( --''-- в ФС)
• open(O_DIRECT) (OS bypass)...
Что думают об этом разработчики ядра
«In short, the whole "let's bypass the OS" notion is just fundamentally broken. It sounds simple, but it sounds simple only to an idiot who writes databases and doesn't even UNDERSTAND what an OS is meant to do.»
Linus Torvalds «Re: O_DIRECT question»
https://lkml.org/lkml/2007/1/11/129
Tempesta FW• Минималистичная и очень быстрая реализация в
ядре
– Web-прокси и Web-сервер
– Key-value in-memory база данных (Tempesta DB)
Tempesta FW• Минималистичная и очень быстрая реализация в
ядре
– Web-прокси и Web-сервер
– Key-value in-memory база данных (Tempesta DB)
• Фаервол на сетевых уровнях IP, TCP, HTTP
Tempesta FW• Минималистичная и очень быстрая реализация в
ядре
– Web-прокси и Web-сервер
– Key-value in-memory база данных (Tempesta DB)
• Фаервол на сетевых уровнях IP, TCP, HTTP
• Оптимизация и доработка вместо специализации
Tempesta FW: macrokernel?• Прикладная логика в user-space
– Tempesta DB: tdbq → libtdb → kernel engine
– Tempesta FW: CGI-like zero-copy интерфейс (TODO)
Cинхронный I/O• Вся работа в softirq
Cинхронный I/O• Вся работа в softirq
• Нет очередей (на чтение)
Cинхронный I/O• Вся работа в softirq
• Нет очередей (на чтение)
• Нет файловых дескрипторов
Cинхронный I/O• Вся работа в softirq
• Нет очередей (на чтение)
• Нет файловых дескрипторов
• Меньше блокировок
Cинхронный I/O• Вся работа в softirq
• Нет очередей (на чтение)
• Нет файловых дескрипторов
• Меньше блокировок
=> Быстрее чтение (и парсинг HTTP!)
Synchronous Sockets
http://natsys-lab.blogspot.ru/2013/03/whats-wrong-with-sockets-performance.html
Быстрый HTTP парсер
237ms 470ms http://natsys-lab.blogspot.ru/2014/11/the-fast-finite-state-machine-for-http.htmlc
Tempesta DBIn-memory Key-Value
Tempesta DBIn-memory Key-Value
• Cache conscious Burst Hash Trie
Tempesta DBIn-memory Key-Value
• Cache conscious Burst Hash Trie
• Lock-free (почти)
Tempesta DBIn-memory Key-Value
• Cache conscious Burst Hash Trie
• Lock-free (почти)
• Huge pages
Tempesta DBIn-memory Key-Value
• Cache conscious Burst Hash Trie
• Lock-free (почти)
• Huge pages
• Быстрый транспорт в/из user-space
Tempesta DB:zero-copy транспорт
http://natsys-lab.blogspot.ru/2015/03/linux-netlink-mmap-bulk-data-transfer.html
Web-кэш• На основе Tempesta DB
• NUMA-aware
Web-кэш: NUMA sharding
Web-кэш: NUMA replication
Frang: HTTP DoS• Rate limits
– request_rate, request_burst
– connection_rate, connection_burst
– concurrent_connections
Frang: HTTP DoS• Rate limits
– request_rate, request_burst
– connection_rate, connection_burst
– concurrent_connections
• Slow HTTP
– client_header_timeout, client_body_timeout
– http_header_cnt
– http_header_chunk_cnt, http_body_chunk_cnt
Frang: WAF• Ограничения размеров
– http_uri_len, http_field_len, http_body_len
Frang: WAF• Ограничения размеров
– http_uri_len, http_field_len, http_body_len
• Допустимые значения
– http_ct_required, http_ct_vals
– http_methods
Frang: фильтрация
Frang: фильтрация
Frang: фильтрация
Frang: фильтрация
Балансировка нагрузки• Динамический реконнект
Балансировка нагрузки• Динамический реконнект
• Конфигурируемое число соединений к бакендам
Балансировка нагрузки• Динамический реконнект
• Конфигурируемое число соединений к бакендам
• Планировщики
– HTTP (по группам серверов)● Wildcards, full match, prefix● Метод, URI, Host● Любые заголовоки
Балансировка нагрузки• Динамический реконнект
• Конфигурируемое число соединений к бакендам
• Планировщики
– HTTP (по группам серверов)● Wildcards, full match, prefix● Метод, URI, Host● Любые заголовоки
– Round-robin (внутри групп серверов)
Балансировка нагрузки• Динамический реконнект
• Конфигурируемое число соединений к бакендам
• Планировщики
– HTTP (по группам серверов)● Wildcards, full match, prefix● Метод, URI, Host● Любые заголовоки
– Round-robin (внутри групп серверов)
– Rendezvous hashing
Примерsrv_group static { # sched=round-robin server 10.10.0.1:8080; server [fc00::2]:8081;}
srv_group dynamic sched=hash { server 10.10.0.3:8080; # conns_n = 4 server [fc00::4]:8081 conns_n=8;}
srv_group black_hole { }
sched_http_rules { match black_hole hdr_raw prefix "X-Bad:"; match static uri prefix "/static/"; match dynamic * * *;}
Sticky cookie• Идентификация пользователей
• enforce: HTTP 302 redirect
sticky name=__tfw_user_id__ enforce;
А не страшно ли в ядре? #include <linux/module.h> static int oops_init(void) { BUG(); } module_init(oops_init);
# insmod oops.ko || echo "$?, but I'm alive"Segmentation fault139, but I'm alive
# dmesg|grep oops\.ckernel BUG at /root/oops_failover/oops.c:4!
Бенчмарки… :(
https://github.com/natsys/tempesta/issues/30
Спасибо!
Source Code (GPLv2):https://github.com/natsys/tempesta
Blog:http://natsys-lab.blogspot.com
E-mail:[email protected]