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?

piątek, 17 sierpnia 2012

Maksymalna liczba ...

 
 Atoms
By default, the maximum number of atoms is 1048576. This limit can be raised or lowered using the +t option.

+t size
Set the maximum number of atoms the VM can handle. Default is 1048576.
 
 
Process
+P Number
Sets the maximum number of concurrent processes for this system. Number must be in the range 16..134217727. Default is 32768. 


Processes
The maximum number of simultaneously alive Erlang processes is by default 32768. This limit can be raised up to at most 268435456 processes at startup (see documentation of the system flag +P in the erl(1) documentation). The maximum limit of 268435456 processes will at least on a 32-bit architecture be impossible to reach due to memory shortage.

Distributed nodes
Known nodes
A remote node Y has to be known to node X if there exist any pids, ports, references, or funs (Erlang data types) from Y on X, or if X and Y are connected. The maximum number of remote nodes simultaneously/ever known to a node is limited by the maximum number of atoms available for node names. All data concerning remote nodes, except for the node name atom, are garbage-collected.

czwartek, 2 sierpnia 2012

dets

dets:open_file(abc, [{type, bag}]).

type:
bag - w pliku ni będą trzymane duplikaty
duplicate_bag - w pliku trzymane są duplikaty

auto_save - czas po jakim ma być zapisywany plik
 0 - ustawiam zero aby po każdym insert/delete tabela została zapisana


dets:open_file(abc1, [{type, duplicate_bag},{auto_save,0}]).

dets:insert(abc1, {1,2,3}).
dets:insert(abc1, {1,3,4}).
dets:lookup(abc1, 1).  
[{1,2,3},{1,3,4}]

przykład znaleziony w sieci:

{ok, N} = dets:open_file(schema, [{file, "./schema.DAT"},{repair,false}, 
                                  {keypos, 2}]),
F = fun(X) -> io:format("~p~n", [X]), continue end.,
dets:traverse(N, F),
dets:close(N). 

środa, 1 sierpnia 2012

eclipse - erlang


Instalacja środowiska eclipse.


Help -> Install new software. Następnie dodać http://erlide.org/update
Po instalacji restart środowiska i wszystko powinno działać.