Wszystkie testy tak jak już wspomniałem wykonuje na słabym sprzęcie a na dodatek jeszcze proces "realplayer.exe" obciążał mi znacznie procek. Nie ma tego złego co by na dobre nie wyszło. Widzę teraz, że konieczne i tak jest dodanie kolejki połączeń do DB w celu delikatnego przyspieszenia wpisywania danych do bazy.
kod na którym początkowo testowałem umożliwiał mi wprowadzenie jedynie 500 rekordów do bazy. Nie najgorszy wynik ale lekko odbiega od oczekiwań i stawianych przeze mnie wymagań.
Zauważyłem tutaj jeszcze problem. Odpalając 1000 procesów po kilku minutach mój PC przestaje się wyrabiać nawet z 500 rekordami i całkowicie zatyka mi się proces obsługujący bazę danych wywalając timeouty.
Poniżej kod testujący 1:
-module(test_sk_device).
-behaviour(gen_server).
-export([start/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(state, {now, now2,socket,id}).
%%%%%%%%%%%%%%%%%%%%%%%%
start(0) ->
ok;
start(ID) ->
gen_server:start_link(?MODULE, [ID], []),
start(ID-1).
%%%%%%%%%%%%%%%%%%%%%%%%
init([ID]) ->
erlang:send_after(1000, self(), {check_update1}),
{ok, #state{now = now(), now2 = now(), socket = Socket,id = ID}}.
handle_call(Request, From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(Msg, State) ->
{noreply, State}.
handle_info({check_update1}, State) ->
{Mega, Secs, MS} =State#state.now2,
T1 = Mega*1000000*1000000 + Secs*1000000 +MS,
timer:sleep(1000),
{Mega2, Secs2, MS2} = now(),
T2 = Mega2*1000000*1000000 + Secs2*1000000 +MS2,
cs_DB:insert_timestamp(State#state.id,T1, T2, 1),
erlang:send_after(1000, self(), {check_update1}),
{noreply, State#state{now2 = now()}};
handle_info(Info, State) ->
io:format("Info ~p\n",[Info]),
{noreply, State}.
terminate(Reason, State) ->
ok.
code_change(OldVsn, State, Extra) ->
{ok, State}.
Wykorzystując następny kod udało mi się przyspieszyć do 600 rekordów/s trochę niewiele ale przynajmniej jakiś zysk.
Poniżej kod testujący 2:
start2(0) ->
ok;
start2(ID) ->
spawn(?MODULE,insert,[]),
start2(ID-1).
insert() ->
{Mega, Secs, MS} =now(),
T1 = Mega*1000000*1000000 + Secs*1000000 +MS,
timer:sleep(1000),
{Mega2, Secs2, MS2} = now(),
T2 = Mega2*1000000*1000000 + Secs2*1000000 +MS2,
cs_DB:insert_timestamp(1,T1, T2, 1),
insert().
Najlepiej wyszedł test, który kompletnie nie używał gen_servera. Jego osiąg to około 700 przy jednym procesie oraz 750 przy zapuszczonych 3 testach jednocześnie. Czyżby jednak rezygnacja z gen_server jednak była dobrym rozwiązaniem?
Poniżej kod testujący 3:
test_3() ->
case pgsql:connect(?HOST, ?USER, ?PASS, [{database, ?DATABASE}]) of
{ok, DB} ->
test(DB),
{ok};
Unkn ->
error_logger:error_msg("Connectiont: ~p",[Unkn]),
{false}
end.
test(DB) ->
{Mega, Secs, MS} = now(),
T1 = Mega*1000000*1000000 + Secs*1000000 +MS,
%% timer:sleep(1000),
{Mega2, Secs2, MS2} = now(),
T2 = Mega2*1000000*1000000 + Secs2*1000000 +MS2,
T3 = (T2 - T1)/1000000,
Query = io_lib:format("INSERT INTO \"statystyki\" (serialid, \"timestamp1\", \"timestamp2\", \"timestamp\", \"typ\") VALUES (~p,~p , ~p,~p,~p)",
[1,T1,T2,T3,1]),
Reply = case pgsql:squery(DB,Query) of
{ok, X} ->
ok;
Unknown ->
io:format("ERROR\n"),
error
end,
test(DB).
Sprawdziłem jeszcze testy 2 i 3 na sprzęcie 4 rdzeniowym i otrzymałem następujące wyniki
Test 2: 650 rekordów/s - czyli tyle samo co wcześniej. Odpalając kilka procesów wyciągnąłem z tego 1500 rekordów
Test 3: około 3000 rekordów/s przy 5 wątkach czyli na tym można troszkę zyskać.
Jak wy obsługujecie bazę danych? Czy moje podejście jest w miarę słuszne czy jednak, źle podchodzę do tematu?
Brak komentarzy:
Prześlij komentarz