И снова Эрланг...
Плана не будет! 
Причины: 
- невозможно впитать язык за два часа, надо 
начать на нем писать 
- невозможно хорошо рассказать о языке за 
два часа и при этом так, чтобы ни у кого не 
болела голова 
- язык — это просто средство выражения 
управления чем-либо, без предметной области 
его обсуждать скучно и бесполезно 
Скажите «Спасибо, кэп!»
Что будет 
Поговорим за задачи 
Посмотрим, каким боком тут поможет Э 
Накачаемся кучей фактов 
...в надежде, что потом это пригодится в 
реальной жизни 
OMG!!! Это же план!
Поговорим за «тяжелые приложения» 
• термина highload не существует, его придумал 
Бунин 
• буржуины оперируют другими терминами 
• High Avaibility Systems (HA) — это любые системы 
с 24/7 и кучей девяток в конце (сюда же и вэбня); 
• High Performance Computing (HPC) — это уже 
про вычисления, съедающие ресурсы без остатка; 
• наверное, есть что-то еще... но нам пока хватит
Поговорим за HPC 
- много потолков (CPU bound, memory bound, 
IO bound); 
- предметная область — непростая; 
- область решений — еще более непростая; 
- цель: максимальная производительность, 
минимальная задержка; 
- 24/7 — как обычно; 
- выжать из железа все возможное (цена +1U 
может быть больше стоимости времени разработчика на 
оптимизацию). 
Примеры: HFT, OLAP, video encoding, DPI.
Своя особая атмосфера 
● ядро (kernel), брысь с моего ядра (core) — cpu 
affinity... но нам нужны таймеры и системные вызовы; 
● память (преаллокация и локальность, huge 
pages, NUMA, пулы структур (слябы), zero 
copy, DMA, дружественность кешу); 
● выполнение (считаем такты, особенности 
компилятора и прыжки в ассемблер, 
неблокирующие алгоритмы, минимум 
системных вызовов, контролируем 
вымывание кеша, помогаем предсказателю 
ветвления); 
...
Своя особая атмосфера - 2 
... 
● контр-интуитивные знания и опыт (будет ли аппаратно 
подпружиненная функция быстрее самописной, 
HyperThreading — плохо, и т.д.); 
● NIH — это нормально (переписанное и написанное 
самостоятельно будет наверняка быстрее и лучше 
вписываться в экосистему проекта); 
● ЗБЧ. Когда операция повторяется миллиард раз, 
выигрыш в миллисекунду приносит неиллюзорный 
бенефит; 
● языки: С/C++ с подпорками и asm {} (без вариантов); 
● спецоборудование (CUDA/OpenCL видео-карты, Xeon 
Phi, TileGX, FPGA).
А что вы будете делать, если дойдете до конца? 
Упираемся головой в одну из границ? 
- рост вглубь (смотрим что еще подкрутить); 
- рост вширь (добавляем ресурсов). 
2 CPU x 8 core + 348GB RAM + 6 x 4Tb— и пока все, что 
можно упихать в 1U. 
Можно — больше, но это уже свое железо, свои патчи к 
ядру, свое производство, свой саппорт, в общем — ну его 
нафик... 
Остается только одно — ставить еще одну железку. И еще 
одну... И еще...
Мухи от котлет 
- этим безобразием надо как-то управлять 
(сообщать конфигурацию) 
- за этим безобразием надо как-то следить 
(собирать статистику) 
Application 
Control plane 
Data plane
А теперь немного уличной магии... 
Если с Data plane все ясно, то с Control plane мы можем 
развлекаться: 
● можно использовать язык высокого уровня; 
● легкий FFI с языком data plane; 
● сетевая прозрачность/простота; 
● легкость интеграции. 
● можно использовать сторонние 
библиотеки/GC/кеды/смузи; 
● можно (но не нужно) падать и терять данные (главное 
— не уронить data plane при этом) 
● при этом не мешало бы горячая смена кода, если вдруг 
понадобятся бантики (а они понадобятся).
И где тут Эрланг? 
Легкие процессы, нет классической смены 
контекста и ее тяжести; 
Непростой, но вполне понятный FFI с Си (порты, 
NIF, C node); 
Сетевая прозрачность и распределенный 
характер; 
Иммутабельность и GC; 
Интроспекция и легкое чтение кода; 
24/7: let it fall, hot code reload; 
Интегрируемость (ASN.1, куча сетевых сервисов и binary 
pattern matching).
Берем Э, ставим в продакшен … PROFIT!! 
* 
* - на самом деле нет. 
Нужно еще понимание, что там под капотом: 
- OTP (Open Telecom Platform) 
- не OTP (bad idea but embeed!) 
.erl + .hrl 
erlc 
.app 
.beam 
.b.ebaemam 
ERTS EPMD 
node@localhost 
EPMD 
EPMD 
EPMD
Декларативность и pattern matching 
- программа не последовательность действий, 
а набор правил 
- какое правило сработало — то и выполняем 
- т.е. такой большой неявный switch/case 
(clause, слоз, набор правил) 
Соответствие образцу (pattern matching) + 
присвоение (про иммутабельность позже): 
- полное 
{ok, Result} = {ok, [1,2,3]} | {ok, undefined} 
- частичное 
{error, _} = {error, notfound} | {error, <<123, 255>>} 
- с допусловиями (guards) 
{ok, IP} where IP =/= {127, 0, 0, 1}
Иммутабельность и GC 
1> P = 1. 
1 
2> P = 2. 
** exception error: no match of right hand side value 2 
vs. 
irb(main):001:0> a = 1 
=> 1 
irb(main):002:0> a = 2 
=> 2 
irb(main):003:0> print a 
2=> nil 
+ все версии значения переменной; 
+ чужой код не подменит значения; 
+ warnings рулят! (возникают 
зачастую из-за ошибки); 
+ простота GC (собираем по выходу 
за границы видимости). 
- работа с большими списками и 
кортежами — ад копирования и 
фрагментация памяти; 
- разработчику трудно 
адаптироваться; 
- имена кончаются, а нумерация 
усложняет понимание и написание; 
- можно наступить в утечку.
Легкие процессы? Wut? 
- process vs. threads vs. green threads vs. erlang processes 
- не процесс, но объект, инкапсулирующий состояние 
(ObjC) 
- OTP — инфраструктура над процессами (супервизоры, 
серверы, конечные автоматы, события, мониторы) 
ppaarreenntt инициализация receive 
State 
spawn(Fun) 
Pid = <0.0 10> 
{...} 
State 
{...} 
{...} 
State 
Fun 
309 w (heap: 233) 
Pid ! Message 
mailbox
Let if fall, hot code reload.. 
- let it fall =/= можно писать с ошибками 
- let it fall =:= «ошибки неизбежны, подстрахуемся на их счет» 
Страховка: OTP-инфраструктура, супервизоры, мониторы 
- немного о релизах 
- горячее обновление: останавливаем мир, трансформируем 
состояние, меняем код, запускаем мир 
- система даже не заметит 
- и можно делать по сети 
- минусы: надо делать аккуратно, надо следить за версиями 
структур и писать трансформеры 
- практика: все предпочитают перезагрузится, для вэба это 
некритично
Интроспекция 
observer:start().
Интегрируемость 
Что уже есть и прям можно брать: 
- SNMP, SSH, SSL, telnet, ASN.1 — в комплекте; 
- LDAP, HTTP (classic + WS), XMPP, AMQP — стороннее; 
- адаптерты к БД (epgsql, eredis, sqlite) — полно; 
- ZMQ, GTK, OpenGL — и это тоже, да. 
Через ports и NIF можно подпихнуть что угодно: 
- библиотеки; 
- unix pipes; 
- shared memory.
Фу-фу-фу 
- корявый синтаксис (надо привыкнуть); 
- особенности GC и масштабирования; 
- небыстрая математика; 
- проблема первого пня.
Пссс... Хочешь немного кода? 
connect(_Con) -> undefine. 
msg(Con, <<"I">>, undefine) -> add(Con); 
msg(Con, <<"L:", Nick/binary>>, undefine) -> 
case enter(Con, Nick) of 
{ok, UState} -> UState; 
error -> undefine 
end; 
msg(Con, <<"P">>, S) when S =/= undefine -> pub(Con, S); 
msg(Con, <<"S">>, S) when S =/= undefine -> stop(Con, S); 
msg(Con, <<"C:", Msg/binary>>, S) when S =/= undefine -> chat(Con, S, Msg); 
msg(_, _, S) -> S. 
close(Con, S) -> rm(Con, S).
Нафик код, архитектура лучше. 
Что нужно сделать, чтобы передать статистику работы data plane в 
control plane? 
Варианты: 
1. data plane сам формирует статистику и передает ее в control plane 
по шине сообщений; 
DP CP 
2. control plane сам забирает статистику из разделяемой памяти data 
plane; 
DP CP 
3. data plane готовит статистику по запросу из control plane. 
DP CP DP CP
Книги 
http://dmkpress.com/ 
http://www.oreilly.com/ 
https://pragprog.com/
Пообщаться 
Google-группы: 
https://groups.google.com/forum/#!forum/erlang-russian 
Jabber-конференции: 
erlang@conference.jabber.ru 
erlang-talks@conference.jabber.ru
Спасибо за внимание! 
Максим Крентовский 
http://devimpress.com 
max@relabs.ru 
mkrentovskiy 
mkrentovskiy

GetDev.NET: Снова Эрланг

  • 1.
  • 2.
    Плана не будет! Причины: - невозможно впитать язык за два часа, надо начать на нем писать - невозможно хорошо рассказать о языке за два часа и при этом так, чтобы ни у кого не болела голова - язык — это просто средство выражения управления чем-либо, без предметной области его обсуждать скучно и бесполезно Скажите «Спасибо, кэп!»
  • 3.
    Что будет Поговоримза задачи Посмотрим, каким боком тут поможет Э Накачаемся кучей фактов ...в надежде, что потом это пригодится в реальной жизни OMG!!! Это же план!
  • 4.
    Поговорим за «тяжелыеприложения» • термина highload не существует, его придумал Бунин • буржуины оперируют другими терминами • High Avaibility Systems (HA) — это любые системы с 24/7 и кучей девяток в конце (сюда же и вэбня); • High Performance Computing (HPC) — это уже про вычисления, съедающие ресурсы без остатка; • наверное, есть что-то еще... но нам пока хватит
  • 5.
    Поговорим за HPC - много потолков (CPU bound, memory bound, IO bound); - предметная область — непростая; - область решений — еще более непростая; - цель: максимальная производительность, минимальная задержка; - 24/7 — как обычно; - выжать из железа все возможное (цена +1U может быть больше стоимости времени разработчика на оптимизацию). Примеры: HFT, OLAP, video encoding, DPI.
  • 6.
    Своя особая атмосфера ● ядро (kernel), брысь с моего ядра (core) — cpu affinity... но нам нужны таймеры и системные вызовы; ● память (преаллокация и локальность, huge pages, NUMA, пулы структур (слябы), zero copy, DMA, дружественность кешу); ● выполнение (считаем такты, особенности компилятора и прыжки в ассемблер, неблокирующие алгоритмы, минимум системных вызовов, контролируем вымывание кеша, помогаем предсказателю ветвления); ...
  • 7.
    Своя особая атмосфера- 2 ... ● контр-интуитивные знания и опыт (будет ли аппаратно подпружиненная функция быстрее самописной, HyperThreading — плохо, и т.д.); ● NIH — это нормально (переписанное и написанное самостоятельно будет наверняка быстрее и лучше вписываться в экосистему проекта); ● ЗБЧ. Когда операция повторяется миллиард раз, выигрыш в миллисекунду приносит неиллюзорный бенефит; ● языки: С/C++ с подпорками и asm {} (без вариантов); ● спецоборудование (CUDA/OpenCL видео-карты, Xeon Phi, TileGX, FPGA).
  • 8.
    А что выбудете делать, если дойдете до конца? Упираемся головой в одну из границ? - рост вглубь (смотрим что еще подкрутить); - рост вширь (добавляем ресурсов). 2 CPU x 8 core + 348GB RAM + 6 x 4Tb— и пока все, что можно упихать в 1U. Можно — больше, но это уже свое железо, свои патчи к ядру, свое производство, свой саппорт, в общем — ну его нафик... Остается только одно — ставить еще одну железку. И еще одну... И еще...
  • 9.
    Мухи от котлет - этим безобразием надо как-то управлять (сообщать конфигурацию) - за этим безобразием надо как-то следить (собирать статистику) Application Control plane Data plane
  • 10.
    А теперь немногоуличной магии... Если с Data plane все ясно, то с Control plane мы можем развлекаться: ● можно использовать язык высокого уровня; ● легкий FFI с языком data plane; ● сетевая прозрачность/простота; ● легкость интеграции. ● можно использовать сторонние библиотеки/GC/кеды/смузи; ● можно (но не нужно) падать и терять данные (главное — не уронить data plane при этом) ● при этом не мешало бы горячая смена кода, если вдруг понадобятся бантики (а они понадобятся).
  • 11.
    И где тутЭрланг? Легкие процессы, нет классической смены контекста и ее тяжести; Непростой, но вполне понятный FFI с Си (порты, NIF, C node); Сетевая прозрачность и распределенный характер; Иммутабельность и GC; Интроспекция и легкое чтение кода; 24/7: let it fall, hot code reload; Интегрируемость (ASN.1, куча сетевых сервисов и binary pattern matching).
  • 12.
    Берем Э, ставимв продакшен … PROFIT!! * * - на самом деле нет. Нужно еще понимание, что там под капотом: - OTP (Open Telecom Platform) - не OTP (bad idea but embeed!) .erl + .hrl erlc .app .beam .b.ebaemam ERTS EPMD node@localhost EPMD EPMD EPMD
  • 13.
    Декларативность и patternmatching - программа не последовательность действий, а набор правил - какое правило сработало — то и выполняем - т.е. такой большой неявный switch/case (clause, слоз, набор правил) Соответствие образцу (pattern matching) + присвоение (про иммутабельность позже): - полное {ok, Result} = {ok, [1,2,3]} | {ok, undefined} - частичное {error, _} = {error, notfound} | {error, <<123, 255>>} - с допусловиями (guards) {ok, IP} where IP =/= {127, 0, 0, 1}
  • 14.
    Иммутабельность и GC 1> P = 1. 1 2> P = 2. ** exception error: no match of right hand side value 2 vs. irb(main):001:0> a = 1 => 1 irb(main):002:0> a = 2 => 2 irb(main):003:0> print a 2=> nil + все версии значения переменной; + чужой код не подменит значения; + warnings рулят! (возникают зачастую из-за ошибки); + простота GC (собираем по выходу за границы видимости). - работа с большими списками и кортежами — ад копирования и фрагментация памяти; - разработчику трудно адаптироваться; - имена кончаются, а нумерация усложняет понимание и написание; - можно наступить в утечку.
  • 15.
    Легкие процессы? Wut? - process vs. threads vs. green threads vs. erlang processes - не процесс, но объект, инкапсулирующий состояние (ObjC) - OTP — инфраструктура над процессами (супервизоры, серверы, конечные автоматы, события, мониторы) ppaarreenntt инициализация receive State spawn(Fun) Pid = <0.0 10> {...} State {...} {...} State Fun 309 w (heap: 233) Pid ! Message mailbox
  • 16.
    Let if fall,hot code reload.. - let it fall =/= можно писать с ошибками - let it fall =:= «ошибки неизбежны, подстрахуемся на их счет» Страховка: OTP-инфраструктура, супервизоры, мониторы - немного о релизах - горячее обновление: останавливаем мир, трансформируем состояние, меняем код, запускаем мир - система даже не заметит - и можно делать по сети - минусы: надо делать аккуратно, надо следить за версиями структур и писать трансформеры - практика: все предпочитают перезагрузится, для вэба это некритично
  • 17.
  • 18.
    Интегрируемость Что ужеесть и прям можно брать: - SNMP, SSH, SSL, telnet, ASN.1 — в комплекте; - LDAP, HTTP (classic + WS), XMPP, AMQP — стороннее; - адаптерты к БД (epgsql, eredis, sqlite) — полно; - ZMQ, GTK, OpenGL — и это тоже, да. Через ports и NIF можно подпихнуть что угодно: - библиотеки; - unix pipes; - shared memory.
  • 19.
    Фу-фу-фу - корявыйсинтаксис (надо привыкнуть); - особенности GC и масштабирования; - небыстрая математика; - проблема первого пня.
  • 20.
    Пссс... Хочешь немногокода? connect(_Con) -> undefine. msg(Con, <<"I">>, undefine) -> add(Con); msg(Con, <<"L:", Nick/binary>>, undefine) -> case enter(Con, Nick) of {ok, UState} -> UState; error -> undefine end; msg(Con, <<"P">>, S) when S =/= undefine -> pub(Con, S); msg(Con, <<"S">>, S) when S =/= undefine -> stop(Con, S); msg(Con, <<"C:", Msg/binary>>, S) when S =/= undefine -> chat(Con, S, Msg); msg(_, _, S) -> S. close(Con, S) -> rm(Con, S).
  • 21.
    Нафик код, архитектуралучше. Что нужно сделать, чтобы передать статистику работы data plane в control plane? Варианты: 1. data plane сам формирует статистику и передает ее в control plane по шине сообщений; DP CP 2. control plane сам забирает статистику из разделяемой памяти data plane; DP CP 3. data plane готовит статистику по запросу из control plane. DP CP DP CP
  • 22.
  • 23.
    Пообщаться Google-группы: https://groups.google.com/forum/#!forum/erlang-russian Jabber-конференции: erlang@conference.jabber.ru erlang-talks@conference.jabber.ru
  • 24.
    Спасибо за внимание! Максим Крентовский http://devimpress.com max@relabs.ru mkrentovskiy mkrentovskiy