狠狠撸

狠狠撸Share a Scribd company logo
riak-erlang-client
                                2012/12/11 @nobu_k




Thursday, December 13, 12
自己绍介
                    ? 久保田展行(@nobu_k)

                    ? Preferred Infrastructure(PFI, ピーFI)

                            ? Architect: Sedue, Bazil
                    ? DB, Distributed Systems, C++
                    ? Erlang素人

                            ? Riakのコードを読みながら勉強したい
                    ?       IIDX




Thursday, December 13, 12
読むもの

                    ? riak-erlang-client
                    ? +周辺のコード

                            ? riak_pb (pb=Protocol Buffers)
                            ? riak_kv
                             ? リクエストを処理してる部分


Thursday, December 13, 12
riak-erlang-client



Thursday, December 13, 12
概要


                    ? Erlang用のクライアント

                    ? ソースコード

                            ? git://github.com/basho/riak-erlang-
                              client.git



Thursday, December 13, 12
使い方
                > {ok, Pid} = riakc_pb_socket:start_link(Address, Port).
                {ok,<0.34.0>}
                > riakc_pb_socket:ping(Pid).
                pong


                    ? https://github.com/basho/riak-erlang-
                      client
                            ? githubのREADMEがわかりやすい

                    ? Portはcon?gのriak_api/pb_portの値

                    ? 返値のPidをriakc_pb_socketに渡す感じで

Thursday, December 13, 12
本日のターゲット


                    ? riakc_obj.erl
                            ? 値

                    ? riakc_pb_socket.erl
                            ? API



Thursday, December 13, 12
riakc_obj.erl



Thursday, December 13, 12
riak_obj.erl
                > Object = riakc_obj:new(<<"groceries">>, <<"mine">>,
                                         <<"eggs & bacon">>).
                {riakc_obj,<<"groceries">>,<<"mine">>,undefined,
                 [],undefined,<<"eggs & bacon">>}



                    ? Riakに保存される値の情報

                    ? riakc_obj:new(Bucket, Key, Value).
                            ? getで取得する値もこれ


Thursday, December 13, 12
中身
                            -type   bucket() :: binary().
                            -type   key() :: binary() | 'undefined'.
                            -type   vclock() :: binary().
                            -type   metadata() :: dict().
                            -type   content_type() :: string().
                            -type   value() :: binary().
                            -type   contents() :: [{metadata(), value()}].


                            -record(riakc_obj, {
                                      bucket :: bucket(),
                                      key :: key(),
                                      vclock :: vclock(),
                                      contents :: contents(),
                                      updatemetadata :: dict(),
                                      updatevalue :: value()
                                     }).




Thursday, December 13, 12
関数とか


                    ? recordの中身に対する操作がほとんど

                    ? ところで
                            dict:store(?MD_CTYPE, CT, M1)


                            ?MD_CTYPEの頭に付いてる?はなに?

                            追記:マクロと教えて頂きました!

Thursday, December 13, 12
蝉别迟系の関数はどこ?
                    ? contentなどをセットする関数はない

                    ? 代わりにupdateがある

                            ? 今の値と更新後の値を別扱い

                            ? newに渡した値はupdateに入る

                            ? putするとupdateの値が保存される

                             ? Riakから元のcontentsは消える

Thursday, December 13, 12
なんで肠辞苍迟别苍迟蝉は配列?
                    ? コンフリクトしたときのため

                    ? riakc_obj:value_count(Obj).
                    ? riakc_obj:get_values(Obj).
                    ? コンフリクト除去

                            ? updateに適切な値を入れる

                            ? 値を選択 or 適切にマージ

Thursday, December 13, 12
riakc_pb_socket.erl



Thursday, December 13, 12
riakc_pb_socket.erl
                    ? RPC(?)の部分

                    ? 読む順序

                            ? 通信っぽい部分

                            ? CRUD関係

                            ? list系

                            ? mapredはMasahitoさんから解説がありそう

                    ? 後は実際にコードを読みながら???

Thursday, December 13, 12
全体的なメモ1

                    ? ***_optionsの書き方が綺麗

                            ? リスト+中身のパターンマッチングで再帰

                    ? rpb***req
                            ? riak_pbのriak_kv.protoを参照

                    ? コードの40%がテスト

                            ? Riakが起動してることが前提?

Thursday, December 13, 12
全体的なメモ2


                    ? 基本はgen_server:call

                            ? 値の入ったタプルを投げてるだけ

                            ? {req, #pbなrecord, Timeout}




Thursday, December 13, 12
驳别迟/辫耻迟の疑问点

                    ? encode
                            ? putではencodeした値を送っている

                            ? getは受け取った値をそのまま返す

                                ? どこかでdecodeされてる?
                    ?       そもそもgen_server:callを理解してなかった

                            ?   後述しますがhandle_infoの中でレスポンスを処理してます




Thursday, December 13, 12
get: サーバ側の処理
                    ? リクエストの処理場所が分からない

                            ? rpb***reqを処理してるとこを探す

                            ? →riak_kv/riak_kv_pb_object.erl
                            ? processのgetreqを処理してるやつ

                    ? 中でriak:local_clientのgetを呼んでる

                            ? が、今は追わなくてよさそう

Thursday, December 13, 12
get: riak_objectの処理
                    ? local_clientが返した値の処理を追う

                            ? riakc_objじゃなくてriak_object

                    ? riak_pb_kv_codec:encode_contents
                            ? 値を返す前にPBにエンコードしてる

                            ? やっぱりclientでデコードが必要!?

                    ? put側の処理も見てみる
                    ?       TODO: vclockに対してなんかやってるのも気になる???



Thursday, December 13, 12
put: ちょっと寄り道
                    ? clientがエンコードした値の処理され方

                            ? riak_kv_pb_object.erl
                            ? process putreqの中

                              ? update_rpbcontentで値を取り出す

                              ? ここでは明示的にデコードしてる

                  %% Update riak_object with the pbcontent provided
                  update_rpbcontent(O0, RpbContent) ->
                      {MetaData, Value} =
                          riak_pb_kv_codec:decode_content(RpbContent),
                      O1 = riak_object:update_metadata(O0, MetaData),
                        ?
                      riak_object:update_value(O1, Value).

Thursday, December 13, 12
get: process_response
                    ? clientに戻る

                    ? decode_contentsを呼んでるとこ発見

                            ? handle_info からの process_response
                            ?   (再)そもそもgen_server:callを理解してなかった
               process_response(#request{msg = #rpbgetreq{bucket = Bucket, key = Key}},
                                #rpbgetresp{content = RpbContents, vclock = Vclock},
                                State) ->
                   Contents = riak_pb_kv_codec:decode_contents(RpbContents),
                   {reply, {ok, riakc_obj:new_obj(Bucket, Key, Vclock, Contents)},
                    State};




Thursday, December 13, 12
list_keys
                    ? 中身はstream_list_keysとwait

                    ? strean_list_keys
                            ? キーをreceiveしまくる戦法

                            ? 対応するのはriak_kv_pb_bucket.erl

                            ? riak_clientのstream_list_keysを呼び出し

                             ? 中身はまさかのmapred!?

Thursday, December 13, 12
まとめ



Thursday, December 13, 12
まとめ
                    ?       riak-erlang-client
                            ?   Protocol Buffersを使ってる

                            ?   riak_kv/src/riak_kv_pb_{bucket,object}.erlに対応

                    ?       すごいエロ本(Learn You Some Erlang for Great Good!)は神

                            ?   分からないところを調べながらやってました!

                            ?   翻訳した@ymotongpooさんも神

                    ?       TODO
                            ?   vclockまわり

                            ?   サーバ側のリクエスト処理部をもうちょっと追いたい


Thursday, December 13, 12

More Related Content

Riak Source Code Reading #2: Erlang Client

  • 1. riak-erlang-client 2012/12/11 @nobu_k Thursday, December 13, 12
  • 2. 自己绍介 ? 久保田展行(@nobu_k) ? Preferred Infrastructure(PFI, ピーFI) ? Architect: Sedue, Bazil ? DB, Distributed Systems, C++ ? Erlang素人 ? Riakのコードを読みながら勉強したい ? IIDX Thursday, December 13, 12
  • 3. 読むもの ? riak-erlang-client ? +周辺のコード ? riak_pb (pb=Protocol Buffers) ? riak_kv ? リクエストを処理してる部分 Thursday, December 13, 12
  • 5. 概要 ? Erlang用のクライアント ? ソースコード ? git://github.com/basho/riak-erlang- client.git Thursday, December 13, 12
  • 6. 使い方 > {ok, Pid} = riakc_pb_socket:start_link(Address, Port). {ok,<0.34.0>} > riakc_pb_socket:ping(Pid). pong ? https://github.com/basho/riak-erlang- client ? githubのREADMEがわかりやすい ? Portはcon?gのriak_api/pb_portの値 ? 返値のPidをriakc_pb_socketに渡す感じで Thursday, December 13, 12
  • 7. 本日のターゲット ? riakc_obj.erl ? 値 ? riakc_pb_socket.erl ? API Thursday, December 13, 12
  • 9. riak_obj.erl > Object = riakc_obj:new(<<"groceries">>, <<"mine">>, <<"eggs & bacon">>). {riakc_obj,<<"groceries">>,<<"mine">>,undefined, [],undefined,<<"eggs & bacon">>} ? Riakに保存される値の情報 ? riakc_obj:new(Bucket, Key, Value). ? getで取得する値もこれ Thursday, December 13, 12
  • 10. 中身 -type bucket() :: binary(). -type key() :: binary() | 'undefined'. -type vclock() :: binary(). -type metadata() :: dict(). -type content_type() :: string(). -type value() :: binary(). -type contents() :: [{metadata(), value()}]. -record(riakc_obj, { bucket :: bucket(), key :: key(), vclock :: vclock(), contents :: contents(), updatemetadata :: dict(), updatevalue :: value() }). Thursday, December 13, 12
  • 11. 関数とか ? recordの中身に対する操作がほとんど ? ところで dict:store(?MD_CTYPE, CT, M1) ?MD_CTYPEの頭に付いてる?はなに? 追記:マクロと教えて頂きました! Thursday, December 13, 12
  • 12. 蝉别迟系の関数はどこ? ? contentなどをセットする関数はない ? 代わりにupdateがある ? 今の値と更新後の値を別扱い ? newに渡した値はupdateに入る ? putするとupdateの値が保存される ? Riakから元のcontentsは消える Thursday, December 13, 12
  • 13. なんで肠辞苍迟别苍迟蝉は配列? ? コンフリクトしたときのため ? riakc_obj:value_count(Obj). ? riakc_obj:get_values(Obj). ? コンフリクト除去 ? updateに適切な値を入れる ? 値を選択 or 適切にマージ Thursday, December 13, 12
  • 15. riakc_pb_socket.erl ? RPC(?)の部分 ? 読む順序 ? 通信っぽい部分 ? CRUD関係 ? list系 ? mapredはMasahitoさんから解説がありそう ? 後は実際にコードを読みながら??? Thursday, December 13, 12
  • 16. 全体的なメモ1 ? ***_optionsの書き方が綺麗 ? リスト+中身のパターンマッチングで再帰 ? rpb***req ? riak_pbのriak_kv.protoを参照 ? コードの40%がテスト ? Riakが起動してることが前提? Thursday, December 13, 12
  • 17. 全体的なメモ2 ? 基本はgen_server:call ? 値の入ったタプルを投げてるだけ ? {req, #pbなrecord, Timeout} Thursday, December 13, 12
  • 18. 驳别迟/辫耻迟の疑问点 ? encode ? putではencodeした値を送っている ? getは受け取った値をそのまま返す ? どこかでdecodeされてる? ? そもそもgen_server:callを理解してなかった ? 後述しますがhandle_infoの中でレスポンスを処理してます Thursday, December 13, 12
  • 19. get: サーバ側の処理 ? リクエストの処理場所が分からない ? rpb***reqを処理してるとこを探す ? →riak_kv/riak_kv_pb_object.erl ? processのgetreqを処理してるやつ ? 中でriak:local_clientのgetを呼んでる ? が、今は追わなくてよさそう Thursday, December 13, 12
  • 20. get: riak_objectの処理 ? local_clientが返した値の処理を追う ? riakc_objじゃなくてriak_object ? riak_pb_kv_codec:encode_contents ? 値を返す前にPBにエンコードしてる ? やっぱりclientでデコードが必要!? ? put側の処理も見てみる ? TODO: vclockに対してなんかやってるのも気になる??? Thursday, December 13, 12
  • 21. put: ちょっと寄り道 ? clientがエンコードした値の処理され方 ? riak_kv_pb_object.erl ? process putreqの中 ? update_rpbcontentで値を取り出す ? ここでは明示的にデコードしてる %% Update riak_object with the pbcontent provided update_rpbcontent(O0, RpbContent) -> {MetaData, Value} = riak_pb_kv_codec:decode_content(RpbContent), O1 = riak_object:update_metadata(O0, MetaData), ? riak_object:update_value(O1, Value). Thursday, December 13, 12
  • 22. get: process_response ? clientに戻る ? decode_contentsを呼んでるとこ発見 ? handle_info からの process_response ? (再)そもそもgen_server:callを理解してなかった process_response(#request{msg = #rpbgetreq{bucket = Bucket, key = Key}}, #rpbgetresp{content = RpbContents, vclock = Vclock}, State) -> Contents = riak_pb_kv_codec:decode_contents(RpbContents), {reply, {ok, riakc_obj:new_obj(Bucket, Key, Vclock, Contents)}, State}; Thursday, December 13, 12
  • 23. list_keys ? 中身はstream_list_keysとwait ? strean_list_keys ? キーをreceiveしまくる戦法 ? 対応するのはriak_kv_pb_bucket.erl ? riak_clientのstream_list_keysを呼び出し ? 中身はまさかのmapred!? Thursday, December 13, 12
  • 25. まとめ ? riak-erlang-client ? Protocol Buffersを使ってる ? riak_kv/src/riak_kv_pb_{bucket,object}.erlに対応 ? すごいエロ本(Learn You Some Erlang for Great Good!)は神 ? 分からないところを調べながらやってました! ? 翻訳した@ymotongpooさんも神 ? TODO ? vclockまわり ? サーバ側のリクエスト処理部をもうちょっと追いたい Thursday, December 13, 12