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?