SlideShare a Scribd company logo
Erlang data operation
caveats
FunBox
Илья Аверьянов
1. Deadlocks
Обращение к самому себе
%%% blacklist.erl
handle_call(get_all_blacklisted, _From, #st{all_blacklisted = AllBlacklisted} =
St) ->
{reply, AllBlacklisted, St};
...
handle_call({is_blacklisted, Word}, _From, St) ->
AllBlacklisted = gen_server:call(blacklist, get_all_blacklisted),
IsBlacklisted = lists:any(fun(W) -> W =:= Word end, AllBlacklisted),
{reply, IsBlacklisted, St};
Взаимное обращение
%%% processor.erl
...
handle_call({process_job, Job}, _From, St) ->
do_job(Job),
gen_server:call(generator, {register_completion, Job}),
{reply, true, St};
%%% generator.erl
...
handle_call(generate_job, _From, St) ->
Job = generate_job(),
gen_server:call(generator, {process_job, Job}),
{reply, true, St};
Бесконечный timeout
gen_server:call(Pid, Message, infinity)
gen_server:call(Pid, Message, 10000)
gen_server:call(Pid, Message)
Как найти?
erlang:system_info(procs)
2. Bottlenecks
2.1. Явные bottleneck-и
Медленные операции в gen_server
handle_call({calculate_pi, Digits}, _From, St) ->
Pi = calculate_pi(Digits),
{reply, Pi, St};
handle_call({get_new_files_from_bbs, Boss}, _From, St) ->
Files = get_new_files_from_bbs(Boss),
{reply, Files, St};
Лишнее копирование данных
Плохо
is_blacklisted(Word) ->
AllBlacklisted = gen_server:call(BlackListPid, get_all_blacklisted),
sets:is_element(Word, AllBlacklisted).
handle_call(get_all_blacklisted, _From, #st{all_blacklisted = AllBlacklisted} =
St) ->
{reply, AllBlacklisted, St};
Хорошо
is_blacklisted(Word) ->
AllBlacklisted = gen_server:call({is_blacklisted, Word}).
handle_call({is_blacklisted, Word}, _From, #st{all_blacklisted = AllBlacklisted}
= St)
Result = sets:is_element(Word, AllBlacklisted).
{reply, Result, St};
Документация!
● http://www.erlang.org/doc/efficiency_guide/processes.html
● Refc binaries (не копируются между процессами в рамках одной
виртуальной машины)
● Heap binaries (<= 64 bytes)
● ets и dets
2.2 Неявные bottleneck-и
Плохо
handle_cast(incr, St = #st{redis = Redis}) ->
spawn_link(fun() -> redis:qp(Redis, "INCR key") end).
St.
3. Лишнее копирование
См. 2.1.
Более хитрый пример
handle_deliver_sm(Pdu, {Pid, _}, #st{smsc_monitor_pid = SmscMonitorPid} = St) ->
smsc_monitor:event(deliver_sm, SmscMonitorPid),
event_counter:event(esme_client_deliver_sm),
do_handle_deliver_sm(Pid, Pdu, St),
{reply, noreply, St}.
handle_deliver_sm(Pdu, {Pid, _}, #st{smsc_monitor_pid = SmscMonitorPid} = St) ->
smsc_monitor:event(deliver_sm, SmscMonitorPid),
event_counter:event(esme_client_deliver_sm),
spawn_link(fun() -> do_handle_deliver_sm(Pid, Pdu, St) end),
{reply, noreply, St}.
handle_deliver_sm(Pdu, {Pid, _}, #st{smsc_monitor_pid = SmscMonitorPid} = St) ->
smsc_monitor:event(deliver_sm, SmscMonitorPid),
event_counter:event(esme_client_deliver_sm),
spawn_link(fun() -> do_handle_deliver_sm(Pid, Pdu, St) end),
{reply, noreply, St}.
handle_deliver_sm(Pdu, {Pid, _}, #st{smsc_monitor_pid = SmscMonitorPid} = St) ->
smsc_monitor:event(deliver_sm, SmscMonitorPid),
event_counter:event(esme_client_deliver_sm),
LightSt = St#st{reqs = undefined},
spawn_link(fun() -> do_handle_deliver_sm(Pid, Pdu, LightSt) end),
{reply, noreply, St}.
Как бороться
● Передавать в процесс только необходимые ему данные (в рамках
функционального стиля)
● Не делать по возможности спаун линк, а использовать другой
gen_server с пулом воркеров к нему
3. Memory leaks
Локально
gen_server:cast(LocalPiCalcPid, {calculate_pi, Digits}).
На удаленной машине
gen_server:cast({PiCalcPid, remote@node}, {calculate_pi, Digits}).
Как найти и побороть
process_info(Pid),
process_info(Pid, memory)
4. IO
Плохо
case process_job(Job) of
{ok, Res} ->
send_job_result(Res);
{error, some_noncritical_frequent_error} ->
lager:error(“Error: some_noncritical_frequent_error”)
end.
Хорошо
file:open(Path, [append, raw, {delayed_write, ?WRITE_BUFFER_SIZE,
?WRITE_BUFFER_MAX_DELAY}])
5. Недостаток ресурсов
● erl +P 1048576
● ulimit -n
● no swap!

More Related Content

What's hot

Kramer
KramerKramer
Krameranisol
 
PHP basic
PHP basicPHP basic
PHP basicNoveo
 
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019QADay
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonPython Meetup
 
Meet Magento Belarus debug Pavel Novitsky (rus)
Meet Magento Belarus debug Pavel Novitsky (rus)Meet Magento Belarus debug Pavel Novitsky (rus)
Meet Magento Belarus debug Pavel Novitsky (rus)Pavel Novitsky
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателейDEVTYPE
 
Реализация шаблонов корпоративных приложений в Magento
Реализация шаблонов корпоративных приложений в MagentoРеализация шаблонов корпоративных приложений в Magento
Реализация шаблонов корпоративных приложений в MagentoMagecom Ukraine
 
MySQL replication from setup to advanced features. Hidden MySQL replication o...
MySQL replication from setup to advanced features. Hidden MySQL replication o...MySQL replication from setup to advanced features. Hidden MySQL replication o...
MySQL replication from setup to advanced features. Hidden MySQL replication o...Pivorak MeetUp
 

What's hot (10)

Kramer
KramerKramer
Kramer
 
PHP basic
PHP basicPHP basic
PHP basic
 
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019
ЄВГЕН КЛИМЕНКО «Think like a tester, act like an engineer» Lviv QA Day 2019
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки Python
 
Meet Magento Belarus debug Pavel Novitsky (rus)
Meet Magento Belarus debug Pavel Novitsky (rus)Meet Magento Belarus debug Pavel Novitsky (rus)
Meet Magento Belarus debug Pavel Novitsky (rus)
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
2.4 Использование указателей
2.4 Использование указателей2.4 Использование указателей
2.4 Использование указателей
 
Perl 5.10 и 5.12
Perl 5.10 и 5.12Perl 5.10 и 5.12
Perl 5.10 и 5.12
 
Реализация шаблонов корпоративных приложений в Magento
Реализация шаблонов корпоративных приложений в MagentoРеализация шаблонов корпоративных приложений в Magento
Реализация шаблонов корпоративных приложений в Magento
 
MySQL replication from setup to advanced features. Hidden MySQL replication o...
MySQL replication from setup to advanced features. Hidden MySQL replication o...MySQL replication from setup to advanced features. Hidden MySQL replication o...
MySQL replication from setup to advanced features. Hidden MySQL replication o...
 

Erlang data operation caveats