piątek, 21 września 2012

db

Ponownie moim problemem okazała się metoda testowania oraz sprzęt.
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