Kvs tips2. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-1-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
アジェンダ
• SimpleなKVSとのIO
• 複数データ処理をシーケンシャルに行った場合(KVS一台)
• 複数データ処理を高速に行う方法(redis)
• 複数KVSによるデータ分散のcase
3. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-2-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
SimpleなKVSとのIO
• Applicationがwrite(send) system callにより、sndbufに格納
• OSがsndbufのデータをrcvbufへ送信
• KVSがread(recv) systemcallでrcvbufからdata取得
• KVSが取得したdataより、処理を実行し、結果をwriteし、sndbufへ格納
• OSがsndbufに格納されたデータをrcvbufへ送信
• Applicationがread(recv) system callにより、rcvbufよりデータ取得
4. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-3-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数データ処理をシーケンシャルに行った場合(KVS一台)
• Applicationがwrite(send) system callにより、sndbufに格納
• OSがsndbufのデータをrcvbufへ送信
• KVSがread(recv) systemcallでrcvbufからdata取得
• KVSが取得したdataより、処理を実行し、結果をwriteし、sndbufへ格納
• OSがsndbufに格納されたデータをrcvbufへ送信
• Applicationがread(recv) system callにより、rcvbufよりデータ取得
✖️ 2
5. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-4-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数データ処理を高速に行う方法(redis)
• Redis handler
• Lua scripting
• Pipe line
複数のデータ処理を1IOで行う
複数の処理を非同期で行う
6. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-5-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
データ分散複数KVSのcase
• Redis handler
• Lua scripting
複数のデータ処理を1IOで行う
• Pipeline
複数の処理を非同期で行う
7. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-6-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数KVSでのPipelineの問題点(hiredisでの例)
8. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-7-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数KVSでのPipelineの問題点1
redisAppendCommandはclient libraryのbufferに格納されるだけで、
sndbufには格納されない。
sndbufに格納されるのは、最初のRedisGetReply時。
9. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-8-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
動きの違い
[期待]
[実際]
10. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-9-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数KVSでのPipelineの問題点1
11. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-10-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
複数KVSでのPipelineの問題点2
sndbufに入れた順番で、rcvbufに戻ってくるとは限らない。
12. 11 July 2018Copyright © , ValueCommerce Co., Ltd.
-11-
本書類の内容に関する一切の権利につきましては当社に帰属し、本書類の全部または一部
を当社の事前承諾なしに公表または第三者に開示することはできませんので、貴社限りとして
お取扱いください。
一般
まとめ
• 非同期処理はsndbufもしくは類似する役割のbufferに入れるところまで確認し
ないと実際そう動かない可能性がある
• 非同期処理では、どのInputに対してのOutputかわかるように設計しないといけ
ない(順番を信じることは基本できない)
Editor's Notes 軽く自己紹介し、
前の二人はプロダクトの流れを説明したので、
自分はちょっと仕組みにフォーカスしたことを話します。 簡単にこんなアジェンダで話そうと思います
最終的には、データ分散系のKVSでのIOを効率的しようっていう話になります TCP全体の話で、
real time biddingだのだと、
connection time outだの、
no blocking modeだの、
そもそもこのソケットをつなぐネタもあると思いますが、割愛します。
processからみると、sendしたあとに、select, kqueue, epollなんかで待つ
Systemcallの先はOSの仕事なので、ここで、selectしなければ、
そもそもここで非同期になります。 processは、sendし、select, kqueue, epollって流れを二回行う
network io2回分の時間待ちが発生 redisでの例
4.0系からはhandler、3系まではluaが上のアプローチ
人間が荷物運ぶのでいうと、
上は、一度で二つ荷物を運ぶっていうアプローチで
下は、運ぶ人を増やすっていうアプローチ
ちなみにうちでは、全部パターン使ってるんですが、
redis handlerはactiveな状態で、moduleの更新をどうエレバンとにやればいいのか自分はわかってないので、
知って人がいたら、この後教えてもらえると嬉しいです。 上のアプローチは、1台のサーバー上で、2つのデータをとりあつかう処理をつくるっていうアプローチのため、
データが複数サーバーにわかれてて、個別にとりにいく、もしくはやきにいく場合には使えない。 hiredisっていうクライアントライブラリを使う例
hiredisっていう、client libraryのpipelineのとこにのってるサンプルプログラムをぱくって適当に変更したもの
うまくうごくようにみえる
ちなみに、本当のベストは、同じサーバー(socket)での処理は、pipe lineじゃなく、
luaなりhandlerなりで複数データを同時に扱うほうがいい
が、KVSを横に並べれば並べるほど、keyが分散していくようになるため、
効果はさがっていく。 systemcallを減らすためのバッファリングをlibraryがしてくれてるため、NG
これは、file ioでも標準出力とか、無バッファリングじゃない限りよくある事象
send,send,send,recv,recv,recvという動きを期待したい
が、
send,send,recv,recv,send,recvっていう動きになってしまう。
ここでは、たまたま同じKVSにいくデータが二つの例にしてるが、
KVSが増えれば増えるほど、keyが分散されやすくなり、
同時に扱いたいデータ分待つ時間に近づいてしまう。 1回ごとに、buffer flushするようにすれば解決するようにみえます シーケンシャルから非同期にすることで、送った順番で返ってくるとは限らないっていうことが起こり得る。
httpなんかでは、libcurl、libevtなんかで、同じように、複数のサーバーに、非同期で同時に情報おくったり、とったりすると思うが、そちらでも同じことが起き得る。 で、いきなりまとめですが、
データ分散で複数KVS使う場合には、この二箇所に注意して行うといいのでわないかと思います。
下は、サーバー、クライアントによると思いますが、
例えば、valueにprefixでkeyもいれるだのするとかが例となります。