generic replication bahaviour

Johan Montelius johanmon@REDACTED
Wed May 26 12:31:29 CEST 2010


Hi,

has anyone played around with a generic replication behaviour in the style  
of gen_server? I've benchmarked a prototype and it works ok if the read to  
write ratio is high. The idea is to, rather than provide a toolbox of  
group membership functionality, provide a very simple way of setting up a  
replicated server; hopefully gaining some performance advantages. The  
target is small scale replication.

I've so far benchmarked it on a quad-core cpu and it has its advantages,  
distributed benchmarking is in the pipeline.

http://web.it.kth.se/~johanmon/replicator.html

One question is how the interface should look like i.e. initialization and  
call-back functions. Below is how to implement a replicated ets table.  
Does it make sense to have a gen_replicated module or will each  
application be so different that one model does not fit. Another question  
is what operations to provide and what consistency to provide. As it is  
right now I provide three functions:

atomic multicast (abcast): performed in the same order by all replicas
local call (call):  performed by the local replica, does not change the  
state
atomic call (acall): performed in total order with the multicast messages

The very tricky issue on how to handle state transfer is below implemented  
simply by passing the whole state in a message but another solution could  
be to give the new replica a file name etc. It might be these decisions  
that make any generic replication scheme useless.

Comments are welcome,

   Johan



-module(rets).

-export([start/1, replicate/2, init/1, init_replica/1, join/2,  
terminate/2]).

-export([handle_abcast/2, handle_call/2, handle_acall/2]).

start(Node) ->
     gen_replicated:start(Node, ?MODULE, [], []).

replicate(Node, Replica) ->
     gen_replicated:replicate(Node, ?MODULE, Replica, please, []).

init(_Args) ->
     {ok, ets:new(noname, [])}.

init_replica(Copy) ->
     Table = ets:new(noname, []),
     ets:insert(Table, Copy),
     {ok, Table}.

join(Request, Table) ->
     case Request of
	please ->
	    {accepted, ets:tab2list(Table)};
	_ ->
	    {denied, "say please"}
     end.

terminate(_Reason, Table) ->
     ets:delete(Table).

handle_abcast({insert, Entry}, Table) ->
     ets:insert(Table, Entry),
     {noreply, Table};
handle_abcast(stop, _Table) ->
     {stop, normal}.

handle_call({lookup, Key}, Table) ->
     {reply, ets:lookup(Table, Key)}.

handle_acall({update_element, Key, PosValue}, Table) ->
     {reply, ets:update_element(Table, Key, PosValue), Table}.




-- 
Associate Professor Johan Montelius
Royal Institute of Technology - KTH
School of Information and Communication Technology - ICT


More information about the erlang-questions mailing list