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