Если ваша база данных mnesia
, это не должно быть сложно. Одним из способов было бы иметь функцию записи и функцию чтения. Тем не менее, обратите внимание, что есть несколько Activity access contexts
с мнезией. Чтобы проверить <i>write times</i>
, вы НЕ должны использовать контекст transaction
, поскольку он немедленно возвращается к вызывающему процессу, даже до того, как произошла запись на диск. Однако для записи на диск важно, чтобы вы смотрели на контекст, называемый: sync_transaction
. Вот пример:
write(Record)->
Fun = fun(R)-> mnesia:write(R) end,
mnesia:activity(sync_transaction,Fun,[Record],mnesia_frag).
Функция выше вернется только тогда, когда все активные реплики таблицы mnesia зафиксировали запись в файле диска с данными. Следовательно, чтобы проверить скорость при увеличении процессов, вам необходимо иметь record generator
, a process spawner
, write function
и, наконец, timing mechanism
. Для синхронизации у нас есть встроенная функция: timer:tc/1, timer:tc/2 and timer:tc/3
, которая возвращает точное время, необходимое для выполнения (полностью) данной функции. Короче говоря, вот как я бы это сделал:
-module(stress_test).
-compile(export_all).<br>
-define(LIMIT,10000).<br>
-record(book,{
isbn,
title,
price,
version}).<br>
%% ensure this table is {type,bag}<br>
-record(write_time,{
isbn,
num_of_processes,
write_time
}).<br>
%% Assuming table (book) already exists
%% Assuming mnesia running already<br>
start()->
ensure_gproc(),
tv:start(),
spawn_many(?LIMIT).<br>
spawn_many(0)-> ok;
spawn_many(N)->
spawn(?MODULE,process,[]),
spawn_many(N - 1).<br>
process()->
gproc:reg({n, l,guid()},ignored),
timer:apply_interval(timer:seconds(2),?MODULE,write,[]),
receive
<<"stop">> -> exit(normal)
end.<br>
total_processes()->
proplists:get_value(size,ets:info(gproc)) div 3.<br>
ensure_gproc()->
case lists:keymember(gproc,1,application:which_applications()) of
true -> ok;
false -> application:start(gproc)
end.<br>
guid()->
random:seed(now()),
MD5 = erlang:md5(term_to_binary([random:uniform(152629977),{node(), now(), make_ref()}])),
MD5List = lists:nthtail(3, binary_to_list(MD5)),
F = fun(N) -> f("~2.16.0B", [N]) end,
L = [F(N) || N <- MD5List],
lists:flatten(L).<br>
generate_record()->
#book{isbn = guid(),title = guid(),price = guid()}.<br>
write()->
Record = generate_record(),
Fun = fun(R)-> ok = mnesia:write(R),ok end,
%% Here is now the actual write we measure
{Time,ok} = timer:tc(mnesia,activity,[sync_transaction,Fun,[Record],mnesia_frag]),
%% The we save that time, the number of processes
%% at that instant
NoteTime = #write_time{
isbn = Record#book.isbn,
num_of_processes = total_processes(),
write_time = Time
},
mnesia:activity(transaction,Fun,[NoteTime],mnesia_frag).
Теперь здесь есть зависимости, особенно: gproc скачайте и встраивайте его в свой путь к erlang lib отсюда Загрузите Gproc .
Чтобы запустить это, просто позвоните: stress_test:start().
Таблица write_time
поможет вам нарисовать график количества процессов в зависимости от времени, затраченного на запись. Поскольку число процессов увеличивается от 0 до верхнего предела (?LIMIT
), мы отмечаем время, затрачиваемое на запись данной записи в данный момент, и мы также отмечаем количество процессов в это время.
UPDATE
f(S)-> f(S,[]).
f(S,Args) -> lists:flatten(io_lib:format(S, Args)).
Это недостающая функция. Извинения ....
Не забудьте изучить таблицу
write_time
, с помощью приложения
tv
открывается окно, в котором вы можете просмотреть таблицы мнезии. Используйте эту таблицу, чтобы увидеть увеличение времени записи / или снижение производительности по мере того, как число процессов время от времени увеличивается.
Элемент, который я пропустил, должен отметить фактическое время действия записи, используя
time()
, что может быть важным параметром. Вы можете добавить его в определение таблицы
write_time
.