Slide 1

Slide 1 text

Riak Pipe: Distributed Processing System Bryan Fink Principal Software Engineer, Basho Technologies RICON2012 10.Oct.2012 San Francisco, CA 1

Slide 2

Slide 2 text

What is Riak Pipe? • Abstraction of Riak Core • Stages consuming inputs and producing outputs (instead of vnodes answering commands) 2

Slide 3

Slide 3 text

Core Abstraction 3 pipe core get X Data get X Data

Slide 4

Slide 4 text

Core Abstraction 4 pipe core get X Data get X Data Data’

Slide 5

Slide 5 text

Core Abstraction 5 pipe core get X Data get X Data Data’ Data’’

Slide 6

Slide 6 text

Conceptual Example Fetch Render “comment/12345” “{“author”:”bryan”, “time”:20120905040000 “text”:”What a great slide!”}” “
bryan said:

What a great slide!

” 6

Slide 7

Slide 7 text

Pipe Example Spec = [#fitting_spec{name=fetch, module=riak_kv_pipe_get chashfun={riak_kv_pipe_get, bkey_chash}, nval={riak_kv_pipe_get, bkey_nval}}, #fitting_spec{name=render, module=riak_pipe_w_xform, arg={my_app, render_comment}, chashfun=follow}], Options = [], {ok, Pipe} = riak_pipe:exec(Spec, Options), ok = riak_pipe:send_input({<<“comment”>>, <<“one”>>}, Pipe), ok = riak_pipe:send_input({<<“comment”>>, <<“two”>>}, Pipe), ok = riak_pipe:send_input({<<“comment”>>, <<“three”>>}, Pipe), riak_pipe:eoi(Pipe), {eoi, RenderedComments, _Log} = riak_pipe:collect_outputs(Pipe). 7

Slide 8

Slide 8 text

Fitting Example -module(riak_pipe_w_xform). -behaviour(riak_pipe_vnode_worker). -export([init/2,process/3,done/1]). -record(state, {p :: riak_pipe_vnode:partition(), fd :: riak_pipe_fitting:details()}). init(Partition, FittingDetails) -> {ok, #state{p=Partition, fd=FittingDetails}}. process(Input, _Last, #state{p=P, fd=FD}=State) -> {Mod,Fun} = FittingDetails#fitting_details.arg, Results = Mod:Fun(Input), [ riak_pipe_vnode_worker:send_output(R,P,FD) || R <- Results ], {ok, State}. done(_State) -> ok. 8

Slide 9

Slide 9 text

Fitting Example -module(my_app). -behaviour(riak_pipe_vnode_worker). -export([render_comment/1]). render_comment({ok, RiakObject}) -> Value = riak_object:get_value(RiakObject), HTML = ...render Value to HTML... [HTML]; render_comment({error,Reason}) -> HTML = ...render error Reason... [HTML]. 9

Slide 10

Slide 10 text

Consistent Hashing 0 2160 2160/2 2160/4 node 0 node 1 node 2 node 3 riak_kv_pipe_get:bkey_chash({<<"comment">>,<<"one">>}) 10

Slide 11

Slide 11 text

Spread Work 11 {“comment”, “one”} {“comment”, “two”} {“comment”, “three”} hash(X) -> crypto:sha(X).

Slide 12

Slide 12 text

Funnel Results 12 {“comment”, “one”} {“comment”, “two”} {“comment”, “three”} hash(X) -> crypto:sha(element(1, X)).

Slide 13

Slide 13 text

Bin Results 13 {“comment”, “one”} {“comment”, “two”} {“comment”, “three”} hash(X) -> crypto:sha(hd(element(2, X)).

Slide 14

Slide 14 text

Constant 14 {“comment”, “one”} {“comment”, “two”} {“comment”, “three”} hash(_) -> <<123,321,234,0,0,...>>.

Slide 15

Slide 15 text

Maintain Locality 15 {“comment”, “three”} ‘follow’. {“comment”, “two”} {“comment”, “one”}

Slide 16

Slide 16 text

Practical Example [#fitting_spec{name = {kvget_map,0}, module = riak_kv_pipe_get, arg = undefined, chashfun = {riak_kv_pipe_get,bkey_chash}, nval = {riak_kv_pipe_get,bkey_nval}, q_limit = 64}, #fitting_spec{name = {xform_map,0}, module = riak_kv_mrc_map, arg = {{modfun,riak_kv_mapreduce,map_object_value}, none}, chashfun = follow, nval = 1, q_limit = 64}, #fitting_spec{name = 1, module = riak_kv_w_reduce, arg = {rct,#Fun,none}, chashfun = <<252,254,56,192,68,143,70,78,255,139,154,26, 177,15,123,219,36,185,221,145>>, nval = 1, q_limit = 64}] 16 map reduce

Slide 17

Slide 17 text

Practical Example [#fitting_spec{name = {kvget_map,0}, module = riak_kv_pipe_get, arg = undefined, chashfun = {riak_kv_pipe_get,bkey_chash}, nval = {riak_kv_pipe_get,bkey_nval}, q_limit = 64}, #fitting_spec{name = {xform_map,0}, module = riak_kv_mrc_map, arg = {{modfun,riak_kv_mapreduce,map_object_value}, [do_prereduce]}, chashfun = follow, nval = 1, q_limit = 64}, #fitting_spec{name = {prereduce,0}, module = riak_kv_w_reduce, arg = {rct,#Fun,none}, chashfun = follow, nval = 1, q_limit = 64}, #fitting_spec{name = 1, module = riak_kv_w_reduce, arg = {rct,#Fun,none}, chashfun = <<252,254,56,192,68,143,70,78,255,139,154,26, 177,15,123,219,36,185,221,145>>, nval = 1, q_limit = 64}] 17 map reduce

Slide 18

Slide 18 text

Practical Example 18 map get prereduce reduce map get reduce

Slide 19

Slide 19 text

Practical Example 19 map get prereduce reduce map get reduce node boundary millions of messages 64 messages

Slide 20

Slide 20 text

SEDA Figures 5 & 6, M. Welsh, D. Culler, E. Brewer. SEDA: An Architecture for Well-Conditioned, Scalable Internet Services. SOSP 2001, October 21-24, 2001, Chateau Lake Louise, Canada. 20

Slide 21

Slide 21 text

SEDA Advantages • Queues can be size-capped to limit backlog • Size of worker pool can be managed to limit resource usage 21

Slide 22

Slide 22 text

Riak Pipe “Vnode” 22 Workers Queues

Slide 23

Slide 23 text

Riak Pipe “Vnode” 23 Workers Queues {<<"comment">>,<<"one">>}, hd(Pipe) riak_kv_pipe_get:process({<<"comment">>,<<"one">>}, State)

Slide 24

Slide 24 text

Possible Apps? • KV Could be redone as a Pipe app • Get = fetch -> reconcile -> repair • Put = pre-commit -> write -> post-commit 24

Slide 25

Slide 25 text

Current Work •Performance •Other-language Fittings •External Interface 25

Slide 26

Slide 26 text

Thanks! • Source: github.com/basho/riak_pipe • Me: @hobbyist • News: twitter.com/basho/team 26