kai-devel-ja Mailing List for kai (Page 6)
Kai is a distributed key-value datastore
Status: Beta
Brought to you by:
takemaru
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(14) |
Jun
(95) |
Jul
(94) |
Aug
(44) |
Sep
(5) |
Oct
(8) |
Nov
(14) |
Dec
(6) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
(18) |
Mar
(19) |
Apr
|
May
(11) |
Jun
(8) |
Jul
(4) |
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Takeru I. <tak...@gm...> - 2008-08-09 06:49:02
|
目的が違うので,本来は memcached と比較する意味は余りありません. それでも比較したがる人がいるので (まぁ,いるんですよ),同条件で性能測定を行ってみました. 以下のようなチューニングを行い,高い性能を狙いました. 1 ノードで動作させ,単体の memcached と比較できるようにしました. もちろん,(N,R,W) = (1,1,1) です. また,kai_sync.erl, kai_membership.erl の TIMER を infinity にしました (そうしないと,過負荷でこれらのプロセスが異常終了することがあるので). 性能を上げるために,次のように設定を変更してプロエス数を増やしました. max_connections: 90 memcache_max_connections: 30 対象となるソースコードは,trunk/ (r66) です. 1 KB のデータを数十万回操作して,その性能を測定しました. クライアント数が 12-14 のときに最も高い性能を発揮しました. 以下がその性能値です. set: rate: 7136 qps latency: median: 1.55 ms 99%: 2.76 ms CPU: 370 % くらい get: rate: 10193 qps latency: median: 1.21 ms 99%: 3.71 ms CPU: 355 % くらい 10,000 qps を超えると "速い" という気がしますね. C で実装して memory allocation にまで気を遣っている memcached ほどではないと思いますが,かなり速いソフトウェアと言えるのではないでしょうか. また,単純に latency の逆数をとると 1,000 qps にも満たないわけですが,多数のプロセスが協調することでその 10倍以上の値を実現しているというのは,Erlang ならではですね. 総スループットは 100Mbps に満たないので,帯域には余裕があります (1000Base-T です). CPU 使用率が 400% 近いのは 4 コアだからです (CPU Xeon 2.13 GHz x4). 今回のボトルネックは CPU だと思われます. 2008/8/9 Takeru INOUE <tak...@gm...>: >>> データサイズは 100 KB とやや大きめにし, (N,R,W) = (3,2,2) としました. >>> - rate: 731 qps (585 Mbps) >>> latency: >>> median: 12.9/10.5 ms (set/get) >>> 99%: 15.4/44.0 ms >>> >>> データを複製するタイプの key-value store としては,悪くない数値ではないでしょうか? >> >> 同感です。ひとつ、不思議なのは、median と 99% があまり離れていないことでしょうか? >> set ではこの 2 つの数字からは、標準偏差が 1ms 以下になっているとおもいます。 >> ちょっとバラつかなさすぎな??? > > この値は間違い (typo) でした m(_ _)m > この後に出すメールを参考にしてください. > >>> Latency の平均値は 1.67 ms で,逆数は 599 qps でした. >>> 実際のスループットは 6 倍のスループットでしかなく,先ほどの高い並行性は発揮できませんでした. >> >> kai_store は、1 ノードで 1 プロセスなので、そこがボトルネックになったりするでしょうか? >> おおざっぱに、3500qps だと、ノードあたり、3500*3/5 =~ 2000 qps くらいさばくので、 >> シングルスレッド化すると、逆数にして、500usec ですね。まだ捌けそうなきもする。 >> とすると、memcache 側かなぁ?? > > max_connections を増やしたり,connection pooling を実装したりして,かなり性能が伸びました. > これも,後で出すメールを. > >>> 最後に,CPU 使用率についてです. >>> 前回と同様に,4 core のマシンを使いましたが,1 core しか使われていませんでした. >>> CPU 使用率は 40-70% の間を変化していました. >>> >> >> これ、解決したいですねぇ。なんでなんだろ?? > > これも解決しました. > 単に top の見方をわかってなかっただけで,負荷を高めていったら CPU 使用率が 370% くらいまであがりました. > つまり,ちゃんとマルチコアで動いてたってことです. > > -- > Takeru INOUE <tak...@gm...> > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-08-09 06:24:49
|
>> データサイズは 100 KB とやや大きめにし, (N,R,W) = (3,2,2) としました. >> - rate: 731 qps (585 Mbps) >> latency: >> median: 12.9/10.5 ms (set/get) >> 99%: 15.4/44.0 ms >> >> データを複製するタイプの key-value store としては,悪くない数値ではないでしょうか? > > 同感です。ひとつ、不思議なのは、median と 99% があまり離れていないことでしょうか? > set ではこの 2 つの数字からは、標準偏差が 1ms 以下になっているとおもいます。 > ちょっとバラつかなさすぎな??? この値は間違い (typo) でした m(_ _)m この後に出すメールを参考にしてください. >> Latency の平均値は 1.67 ms で,逆数は 599 qps でした. >> 実際のスループットは 6 倍のスループットでしかなく,先ほどの高い並行性は発揮できませんでした. > > kai_store は、1 ノードで 1 プロセスなので、そこがボトルネックになったりするでしょうか? > おおざっぱに、3500qps だと、ノードあたり、3500*3/5 =~ 2000 qps くらいさばくので、 > シングルスレッド化すると、逆数にして、500usec ですね。まだ捌けそうなきもする。 > とすると、memcache 側かなぁ?? max_connections を増やしたり,connection pooling を実装したりして,かなり性能が伸びました. これも,後で出すメールを. >> 最後に,CPU 使用率についてです. >> 前回と同様に,4 core のマシンを使いましたが,1 core しか使われていませんでした. >> CPU 使用率は 40-70% の間を変化していました. >> > > これ、解決したいですねぇ。なんでなんだろ?? これも解決しました. 単に top の見方をわかってなかっただけで,負荷を高めていったら CPU 使用率が 370% くらいまであがりました. つまり,ちゃんとマルチコアで動いてたってことです. -- Takeru INOUE <tak...@gm...> |
From: shunichi s. <shi...@gm...> - 2008-08-08 13:34:13
|
しばらく考えたのですが、まとまらなかったのでひとまず文字におとします。 このメールは主に 2 点、ひとつめはプロトコルとして、 2つめは衝突の解消の可能性について # 特に 2 つめが練れてない f(--) 2008/8/6 Takeru INOUE <tak...@gm...>: > 次に cas unique ですが,こんな風に考えてました. > クラスタ内部では,データに対して vector clocks と checksum の両方を付けて保存しておく. > checksum のサイズは 64 bit とする. > クラスタ内部でバージョン不整合を解消するときには vector clocks を用いる. > クライアントにデータを返すときは,checksum を付随させる. これはおもいつかなかったです。興味深いですねー。 > クライアントから cas リクエストを受け取ったら,kai_store で書き込むときに checksum を比較する. > checksum が一致しなければエラーを返す. ここでプロトコルがちょっとわからないです。例えば、 get(s?) の結果として (checksum1, data1), (checksum2, data2) というものが返ってきたとします。 すると、その後の cas で、cas unique として指定するのはなににしましょうか? data1 と data2 をマージするような解消法をとると、checksum1/2 のどっちか? というわけには いかないですよね。 もしどちらかを選択したとすると、選択されなかった側の checksum をもった ノード(B と呼ぶ)は store するときにエラーになってしまうようにおもいます。 すると、B のデータは古いままで、いつまでたっても concurrent になってしまうのではないでしょうか? vector clocks (VC) の場合は、クライアントが VC も"マージ"するところに ひとつのキモがあるとおもいます。 すると、checksum の派生案として、checksum の桁をちいさくする方法があるかな、とおもいました。 クライアントが要求した キー に対するデータを区別すれば良いだけなので、64bit の checksum は かなり冗長でしょう。そこで、たとえば 16 bit にしてみると。 すると、クライアントの cas リクエストにのせる cas unique としては、 checksum1 と 2 を単純に 並べたものを使うことが出来ます。 # 最大 4 つまで並べられる store ノードは、これを"マージ"された情報として扱えば、上のノード B もエラーにしなくて 良いかとおもいました。 # これも思いつきベースなので、ツッコミよろしくです m(_ _)m > 上の案は,memcache API に準拠することを優先しています. > memcache API に準拠していることは Kai の大きな特徴になっているので,なるべく守ったほうがいいかなと. たしかにあの単純なプロトコルは良いです。クライアント実装が簡単にできるのはとても重要 > クライアントが vector clocks > を見れなくなってしまうので,クライアントによるバージョン解決が少し難しくなるかもしれませんが,クライアントが解決すべきは vector > clocks で解決できない場合なので,まぁいいかなと. 2つめ。 VC で解決できないときにタイムスタンプがけっこう大事な役割を果すかなぁ、とおもっていたので それがメタデータとして無いのが勿体無いなぁ、と「感じて」います # まだ自分の中でも明確じゃない 例えば、「タイムスタンプベースのマージ」という衝突解消法の可能性があるかと考えました。 具体例としては、クライアントは連想配列をデータとして格納するとします。 # たとえば、買い物カゴの品目ID と 個数みたいな感じ get(s) で返ってきたデータが以下のようなものだったとしましょう。タイムスタンプが付いてるとして ノード A から Timestamp = 5 key1: value1 key2: value2 ノード B から Timestamp = 10 key1: value1-dash key3: value3 ここでクライアントでの「タイムスタンプベースのマージ」を以下のように定義 key1: value1-dash key2: value2 key3: value3 このような解消が本当に有用なのか、まともな例をおもいつかないので判断できていなのですが、 可能性としてあるかなぁ、と。 この方法のためであれば、cas unique として、checksum の代わりにTimestamp を使うのも 良いのかもしれない、と妄想しています。 以下、蛇足 どうも、僕は、(大量のデータの分別をしたいわけではなくて、) 特定のキーに対する数個の値を区別したい、 というのが kai での cas unique の役割なので、もっと意味のある値を使う手もあるのかと思っているようです。 # 弱いなぁ。。。 例えば、ハッシュ値とタイムスタンプの折衷というのもありなのかもしれない? -- shino |
From: Takeru I. <tak...@gm...> - 2008-08-06 14:28:16
|
set があるので,cas をサポートしているクライアントが少ないのは気にしないことにしましょう. 次に cas unique ですが,こんな風に考えてました. クラスタ内部では,データに対して vector clocks と checksum の両方を付けて保存しておく. checksum のサイズは 64 bit とする. クラスタ内部でバージョン不整合を解消するときには vector clocks を用いる. クライアントにデータを返すときは,checksum を付随させる. クライアントから cas リクエストを受け取ったら,kai_store で書き込むときに checksum を比較する. checksum が一致しなければエラーを返す. 上の案は,memcache API に準拠することを優先しています. memcache API に準拠していることは Kai の大きな特徴になっているので,なるべく守ったほうがいいかなと. クライアントが vector clocks を見れなくなってしまうので,クライアントによるバージョン解決が少し難しくなるかもしれませんが,クライアントが解決すべきは vector clocks で解決できない場合なので,まぁいいかなと. 厳密には考えてないので,穴があるかもしれないです. 気づいたらドンドン突っ込んでください. 2008/8/6 shunichi shino <shi...@gm...>: > しのはらです。 > > vector clocks をクライアントに返すときにどのようにするかを相談させてください。 > まず現状。 > Kai は、 memcache プロトコルをクライアントAPI として使っています。 > で、vector clocks のやりとりには、gets/cas をつかって、<cas unique> をやりとり > すれば良いかと考えていました。 > memcache プロトコルはここ > http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt > > また、vector clocks は、{{IP, Port}, Counter, TimeStamp} の形式です。 > > 問題(大) > 上記のプロトコルによると、<cas unique> は、 > ======= > - <cas unique> is a unique 64-bit value of an existing entry. > Clients should use the value returned from the "gets" command > when issuing "cas" updates. > ======= > と、 「64ビットの値」で「gets で得た値をそのまま使え」とあります。 > > vector clocks をここに入れようとしても、64bit だと 8バイトしかないので > ちょっと苦しいです。 > > 問題(小) > cas を実装したクライアントは以外とすくないようにみえる。 > たけるが性能測定につかっていた Cache::Memcache や、 > ぼくがローカルでつかっている ruby の memcache-client は > cas を実装していないようです。 > # Perl はあまり自信ない、Cache::Memcache::Fast は、ソースを見ると > # 実装してそう > ただ、これは実装するのが難しいわけではないので、それほど大きな問題では > ないとおもっています。 > > そこで、相談です。 > どのようなクライアント API にしましょうか? > いま、思っているのは以下くらいです。 > a) <cas unique> が 64bit というのはあまり気にせずに、memcache プロトコル(のような > もの) を使う > b) 別のもうちょっと汎用なプロトコル(たとえば HTTP) のうえに乗せる > メタデータは、X- 野良ヘッダーでのせる > 複数のデータを返すのは、、、マルチパートでしょうか?? > c) オレオレのプロトコルにする > (だいぶ嫌) > > 意見をきかせてください m(_ _)m > > -- > shino > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Kai-devel-ja mailing list > Kai...@li... > https://lists.sourceforge.net/lists/listinfo/kai-devel-ja > -- Takeru INOUE <tak...@gm...> |
From: shunichi s. <shi...@gm...> - 2008-08-06 14:03:00
|
しのはらです。 vector clocks をクライアントに返すときにどのようにするかを相談させてください。 まず現状。 Kai は、 memcache プロトコルをクライアントAPI として使っています。 で、vector clocks のやりとりには、gets/cas をつかって、<cas unique> をやりとり すれば良いかと考えていました。 memcache プロトコルはここ http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt また、vector clocks は、{{IP, Port}, Counter, TimeStamp} の形式です。 問題(大) 上記のプロトコルによると、<cas unique> は、 ======= - <cas unique> is a unique 64-bit value of an existing entry. Clients should use the value returned from the "gets" command when issuing "cas" updates. ======= と、 「64ビットの値」で「gets で得た値をそのまま使え」とあります。 vector clocks をここに入れようとしても、64bit だと 8バイトしかないので ちょっと苦しいです。 問題(小) cas を実装したクライアントは以外とすくないようにみえる。 たけるが性能測定につかっていた Cache::Memcache や、 ぼくがローカルでつかっている ruby の memcache-client は cas を実装していないようです。 # Perl はあまり自信ない、Cache::Memcache::Fast は、ソースを見ると # 実装してそう ただ、これは実装するのが難しいわけではないので、それほど大きな問題では ないとおもっています。 そこで、相談です。 どのようなクライアント API にしましょうか? いま、思っているのは以下くらいです。 a) <cas unique> が 64bit というのはあまり気にせずに、memcache プロトコル(のような もの) を使う b) 別のもうちょっと汎用なプロトコル(たとえば HTTP) のうえに乗せる メタデータは、X- 野良ヘッダーでのせる 複数のデータを返すのは、、、マルチパートでしょうか?? c) オレオレのプロトコルにする (だいぶ嫌) 意見をきかせてください m(_ _)m -- shino |
From: shunichi s. <shi...@gm...> - 2008-08-06 13:45:12
|
まだ理解できていないので、もうちょっと詳しくお願いします m(_ _)m 2008/8/3 Takeru INOUE <tak...@gm...>: > 2008/8/2 Takeru INOUE <tak...@gm...>: >> deadlock の理由は次の通りです. >> >> Node A: >> - クライアントからリクエストを受信する (kai_memcache) >> - キーをチェックし,Node B にリクエストを転送する (kai_coordinator, kai_api) >> - この時点で,Node A の kai_coordinator は待ち状態に入る >> >> Node B: >> - Node A から転送されたリクエストを受信する前に,Node A と同様にリクエストを処理し,Node B に転送する > > 転送先は Node B ではなく Node Aが正しいです. > >> - この時点で,Node B の kai_coordinator は待ち状態に入る >> >> このようにして,お互いの kai_coordinator が待ちとなり,deadlock となります. >> わかりにくいけど,伝わってるかな? Node A から、 node B に転送されたリクエストは、kai_api を通じるのはわかるけど、 kai_coordinator(B) は通らないのではないかと思っとります と、ここまで書いたら分かりました!! # 上のパラグラフ消そうかとおもったけど、理解の順序を晒したら役にたつかと?たたねーか クライアントが繋ぎにきたノードがそのままコーディネータになれば、 get/put を 投げるだけなので、その後は kai_api しか通らない。 しかし、転送(route) のパスにはいると、その後に、別ノードの kai_coordinator に 入るってことですね。ああ、すっきりしました。 >> kai_coordinator は gen_server だったので,単一プロセスでした. >> kai_api の多重度は関係なくて,kai_coordinator が単一プロセスであることが deadlock の原因でした. >> >> 解決方法はいくつかあると思いますが,もっとも簡単なのが gen_server をやめて通常の関数呼び出しにすることでした. >> こうすることで,kai_coordinator を呼び出している kai_memcache や kai_api のプロセスから関数が呼び出されることになります. >> 結果的にマルチプロセスとなるため,上のような deadlock を回避できます. >> なお,kai_coordinator は state を持っていなかったので,gen_server をやめることは簡単でした. >> >> ちなみに,deadlock とは関係なく gen_server をやめるつもりでした. >> というのは,kai_coordinator はかなり処理時間の長いモジュールでありながら,単一プロセスにしておくと,ボトルネックになることが明白だったからです. そうですね。プロセス構成図ちゃんと書いて手元においとこう、とおもいました。 ところで、dynamo の論文、ようやっと読み終えたのですが、そこでは、kai_coordinator に あたる部分は状態機械でコーディングしてあるよ、って書いてありましたね。 今後、書き戻しの処理とか複雑になりそうな部分なので、リクエスト毎に gen_fsm を 生成するのが最終形なのでしょうかね。 > Takeru INOUE <tak...@gm...> > -- shino |
From: shunichi s. <shi...@gm...> - 2008-08-06 13:26:32
|
性能測定ごくろうさまでした m(_ _)m 2008/8/5 Takeru INOUE <tak...@gm...>: > 改めて,性能測定の結果です. > > クラスタは前回と同じ 5ノードです. > 10のクライアントが,set/get を交互に 10,000 回繰り返し,その時間を測定しました. > 今回は,応答時間 (latency) に中央値 (median) と 99% の結果があります. おおぉー、すばらしいっす。 > データサイズは 100 KB とやや大きめにし, (N,R,W) = (3,2,2) としました. > - rate: 731 qps (585 Mbps) > latency: > median: 12.9/10.5 ms (set/get) > 99%: 15.4/44.0 ms > > データを複製するタイプの key-value store としては,悪くない数値ではないでしょうか? 同感です。ひとつ、不思議なのは、median と 99% があまり離れていないことでしょうか? set ではこの 2 つの数字からは、標準偏差が 1ms 以下になっているとおもいます。 ちょっとバラつかなさすぎな??? > 実際にはこの 10 倍のスループットが出ているので,10 倍の並行性を実現できているということでしょうか. クライアントスレッド数といっしょってことはスゴいですねー。 ちょっとびっくりです (^ ^)v > クライアント数と memcache_max_connections を増やせば,もっと性能を伸ばせたかもしれません. > > また,ノードを 1 つ止めてみましたが,データが失われることはなく,応答時間もほとんど変化しませんでした. すげー > ただし,データサイズを 1 KB にすると,Kai/Dynamo のオーバヘッドが目立つようになり,期待したほど性能が伸びませんでした. > > - rate: 3541 qps > latency: > median: 1.37/1.40 ms > 99% latency 8.93/6.77 ms > > データサイズは 1/100 ですが,スループットは 5 倍くらいにしかなっていません. > > Latency の平均値は 1.67 ms で,逆数は 599 qps でした. > 実際のスループットは 6 倍のスループットでしかなく,先ほどの高い並行性は発揮できませんでした. kai_store は、1 ノードで 1 プロセスなので、そこがボトルネックになったりするでしょうか? おおざっぱに、3500qps だと、ノードあたり、3500*3/5 =~ 2000 qps くらいさばくので、 シングルスレッド化すると、逆数にして、500usec ですね。まだ捌けそうなきもする。 とすると、memcache 側かなぁ?? > 最後に,CPU 使用率についてです. > 前回と同様に,4 core のマシンを使いましたが,1 core しか使われていませんでした. > CPU 使用率は 40-70% の間を変化していました. > これ、解決したいですねぇ。なんでなんだろ?? shino |
From: Takeru I. <tak...@gm...> - 2008-08-05 14:08:38
|
改めて,性能測定の結果です. クラスタは前回と同じ 5ノードです. 10のクライアントが,set/get を交互に 10,000 回繰り返し,その時間を測定しました. 今回は,応答時間 (latency) に中央値 (median) と 99% の結果があります. データサイズは 100 KB とやや大きめにし, (N,R,W) = (3,2,2) としました. - rate: 731 qps (585 Mbps) latency: median: 12.9/10.5 ms (set/get) 99%: 15.4/44.0 ms データを複製するタイプの key-value store としては,悪くない数値ではないでしょうか? Latency の平均値は 13.1 ms だったので,単純に逆数をとると 76.3 qps になります. 実際にはこの 10 倍のスループットが出ているので,10 倍の並行性を実現できているということでしょうか. クライアント数と memcache_max_connections を増やせば,もっと性能を伸ばせたかもしれません. また,ノードを 1 つ止めてみましたが,データが失われることはなく,応答時間もほとんど変化しませんでした. と,ここまでは上々の結果です. ただし,データサイズを 1 KB にすると,Kai/Dynamo のオーバヘッドが目立つようになり,期待したほど性能が伸びませんでした. - rate: 3541 qps latency: median: 1.37/1.40 ms 99% latency 8.93/6.77 ms データサイズは 1/100 ですが,スループットは 5 倍くらいにしかなっていません. Latency の平均値は 1.67 ms で,逆数は 599 qps でした. 実際のスループットは 6 倍のスループットでしかなく,先ほどの高い並行性は発揮できませんでした. また,2000 qps を超えると,timeout error が発生することがありました. 最後に,CPU 使用率についてです. 前回と同様に,4 core のマシンを使いましたが,1 core しか使われていませんでした. CPU 使用率は 40-70% の間を変化していました. 2008/8/2 Takeru INOUE <tak...@gm...>: >> 第一回目(?) の性能測定としては充分な結果のようにおもいます \(^ ^)/ > > 別スレで書いたように deadlock を修正したので、そのコードでもう一度計って現時点での性能としましょう。 > >>> Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. >>> これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. >> >> これはネットワークサーバとしては、(いつも忘れてたハマるんだけど)大事な >> 設定ですよね。 > > いずれは、ソケットの使い捨てを改めたほうがいいかも。 > でも、コネクションプールは deadlock の原因になることもありそう。 > >>>> 最初に,1ノードで測定しました. >>>> N,R,W = 1,1,1 です. >>>> >>>> set 510 us/query >>>> get 588 us/query >>>> >>>> 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). >> >> Dynamo クローンを目指しているので、(99.9 は未だだとして) 99% の値がでると >> いいなぁ、とおもいました。 >> # クライアントを書くのがメンドクサイ気もしますが f(--) > > 加算平均と標準偏差だけ計算したのですが、測った後に median や 1-99 % のほうが役に立つと思ったり。 > それほど面倒でもないので、つぎはそうします。 > >> しかし、結構速いもんですね。 >> オンメモリとはいえ、(直列での) turn-around time は充分だと思いました。 > > この測定の後でも少し実験してみた感じだと、データサイズの影響がかなり大きいですね。 > 結果は後ほど。 > >>>> 1. ひとつの core processor しか使われない >> >> みかログ: Erlangの+Aオプション >> ==== >> ブロックするシステムコールを呼ぶと,スケジューラスレッドが応答待ちをしてしまうので,効率が悪くなってしまう. >> +A オプションを使って async thread pool >> を追加すると,このブロックしてしまう処理をasyncスレッドへ移動でき,スケジューラスレッドは別のErlangコードの実行を続けることが出来る. >> その結果,I/O待ちが多く発生するようなコードがかなり高速化できる. >> ==== http://blog.mikage.to/mika/2007/06/erlanga_89f7.html >> >> このへんが関係するのかな?? >> しかし、コア 1 つしか使われない、っていうのは説明できないですね >> # kai_coordinator が gen_server で直列化される?? > > +A はやってみたけど、変わらなかった。 > >> ふと、思ったのですが、クライアントが単一スレッドでリクエストを >> 発行していたのだとすると、どの erlang ノードも、ソケット読み込み、 >> データ処理、書き込みを直列でやるだけなので、本質的には 1 コアしか >> 使われないので正しいのではないでしょうか? > > Erlang VM の実装がどうなっているのか分からないのだけど、プロセスを起動した時点でコアに割り当てるのだとしたら、その後のリクエストにかかわらずに複数コアが使われるべきだと思う。 > Kai は数十のプロセスを使うので。 > > あと、coordinator は N > プロセスを起動して他ノードにリクエストを転送するのだけど、これは完全に並列して行われるので、リクエストが直列であっても内部では複数コアが使われてもいい気がする。 > 処理が軽いので、top で見えなかっただけという可能性はあるけど。 > >>>> 2. ボトルネックプロセス >>>> >>>> 上では 1 クライアントでアクセスした結果しか示しませんでした. >>>> というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. >> >> TCP のレスポンスを返しそこなっているのでしょうかね? >> あ、でも、accept したあと、read - write - close は単一プロセスでやってるから >> それは無いように思いますね。 >> これも難しい。。。 > > これは別スレッドで書いた deadlock が原因でした. > >> なんにしても、こういう数字がでてくるとワクワクしますね! >> >> # 環境はどうやって用意したん? > > まぁ、そのへんは空気読む感じで :-) > >> ノード障害のテストを行うときには、接続タイムアウトとかも関係してくる >> ようにおもいます。 > > いまの Kai では、connect するときに数秒でタイムアウトするようにしています。 > なので、SYN の再送には期待せずに諦めるようにしていますね。 > > -- > Takeru INOUE <tak...@gm...> > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-08-03 10:10:43
|
Typo を発見. 2008/8/2 Takeru INOUE <tak...@gm...>: > deadlock の理由は次の通りです. > > Node A: > - クライアントからリクエストを受信する (kai_memcache) > - キーをチェックし,Node B にリクエストを転送する (kai_coordinator, kai_api) > - この時点で,Node A の kai_coordinator は待ち状態に入る > > Node B: > - Node A から転送されたリクエストを受信する前に,Node A と同様にリクエストを処理し,Node B に転送する 転送先は Node B ではなく Node Aが正しいです. > - この時点で,Node B の kai_coordinator は待ち状態に入る > > このようにして,お互いの kai_coordinator が待ちとなり,deadlock となります. > わかりにくいけど,伝わってるかな? > > # というか,自分がなにか勘違いしてる可能性もちょっとあるような… > > kai_coordinator は gen_server だったので,単一プロセスでした. > kai_api の多重度は関係なくて,kai_coordinator が単一プロセスであることが deadlock の原因でした. > > 解決方法はいくつかあると思いますが,もっとも簡単なのが gen_server をやめて通常の関数呼び出しにすることでした. > こうすることで,kai_coordinator を呼び出している kai_memcache や kai_api のプロセスから関数が呼び出されることになります. > 結果的にマルチプロセスとなるため,上のような deadlock を回避できます. > なお,kai_coordinator は state を持っていなかったので,gen_server をやめることは簡単でした. > > ちなみに,deadlock とは関係なく gen_server をやめるつもりでした. > というのは,kai_coordinator はかなり処理時間の長いモジュールでありながら,単一プロセスにしておくと,ボトルネックになることが明白だったからです. > > > 2008/8/2 shunichi shino <shi...@gm...>: >> しのはらです。 >> >> 2008/8/2 Takeru INOUE <tak...@gm...>: >>> 性能測定したときに発見した,高負荷時に kai_api がタイムアウトするという問題点を解決しました. >>> 高負荷時に,kai_coordinator がときどき deadlock していました. >> >> もし原因が分かったのであれば、どのようなデッドロックだったのか >> 説明してもらってもいいですか? >> >> 一つ思いついたのは、 >> api -(route)-> coordinator -(get)-> api -> store >> のような、api に再度入ってくるフローがあるところかなぁ、と思っています。 >> これと api の多重度固定(デフォ 10 だっけ)を合わせると、 >> たとえば、20 並列のリクエストが来て、10 個の api が埋まってしまうと、 >> -(get)-> api のところがふんづまるのかな? と。 >> >> でもこれだと、 coodinator を gen_server じゃなくす理由にはならない >> ように思うので、違う気がしています (T-T) >> >>> kai_coordinator >>> - gen_server を使わずに,直接関数を呼び出すように >>> - (念のため) check_node を呼ばないように >>> >> >> shino >> > > > > -- > Takeru INOUE <tak...@gm...> > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-08-02 14:20:59
|
deadlock の理由は次の通りです. Node A: - クライアントからリクエストを受信する (kai_memcache) - キーをチェックし,Node B にリクエストを転送する (kai_coordinator, kai_api) - この時点で,Node A の kai_coordinator は待ち状態に入る Node B: - Node A から転送されたリクエストを受信する前に,Node A と同様にリクエストを処理し,Node B に転送する - この時点で,Node B の kai_coordinator は待ち状態に入る このようにして,お互いの kai_coordinator が待ちとなり,deadlock となります. わかりにくいけど,伝わってるかな? # というか,自分がなにか勘違いしてる可能性もちょっとあるような… kai_coordinator は gen_server だったので,単一プロセスでした. kai_api の多重度は関係なくて,kai_coordinator が単一プロセスであることが deadlock の原因でした. 解決方法はいくつかあると思いますが,もっとも簡単なのが gen_server をやめて通常の関数呼び出しにすることでした. こうすることで,kai_coordinator を呼び出している kai_memcache や kai_api のプロセスから関数が呼び出されることになります. 結果的にマルチプロセスとなるため,上のような deadlock を回避できます. なお,kai_coordinator は state を持っていなかったので,gen_server をやめることは簡単でした. ちなみに,deadlock とは関係なく gen_server をやめるつもりでした. というのは,kai_coordinator はかなり処理時間の長いモジュールでありながら,単一プロセスにしておくと,ボトルネックになることが明白だったからです. 2008/8/2 shunichi shino <shi...@gm...>: > しのはらです。 > > 2008/8/2 Takeru INOUE <tak...@gm...>: >> 性能測定したときに発見した,高負荷時に kai_api がタイムアウトするという問題点を解決しました. >> 高負荷時に,kai_coordinator がときどき deadlock していました. > > もし原因が分かったのであれば、どのようなデッドロックだったのか > 説明してもらってもいいですか? > > 一つ思いついたのは、 > api -(route)-> coordinator -(get)-> api -> store > のような、api に再度入ってくるフローがあるところかなぁ、と思っています。 > これと api の多重度固定(デフォ 10 だっけ)を合わせると、 > たとえば、20 並列のリクエストが来て、10 個の api が埋まってしまうと、 > -(get)-> api のところがふんづまるのかな? と。 > > でもこれだと、 coodinator を gen_server じゃなくす理由にはならない > ように思うので、違う気がしています (T-T) > >> kai_coordinator >> - gen_server を使わずに,直接関数を呼び出すように >> - (念のため) check_node を呼ばないように >> > > shino > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-08-02 09:17:10
|
> 第一回目(?) の性能測定としては充分な結果のようにおもいます \(^ ^)/ 別スレで書いたように deadlock を修正したので、そのコードでもう一度計って現時点での性能としましょう。 >> Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. >> これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. > > これはネットワークサーバとしては、(いつも忘れてたハマるんだけど)大事な > 設定ですよね。 いずれは、ソケットの使い捨てを改めたほうがいいかも。 でも、コネクションプールは deadlock の原因になることもありそう。 >>> 最初に,1ノードで測定しました. >>> N,R,W = 1,1,1 です. >>> >>> set 510 us/query >>> get 588 us/query >>> >>> 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). > > Dynamo クローンを目指しているので、(99.9 は未だだとして) 99% の値がでると > いいなぁ、とおもいました。 > # クライアントを書くのがメンドクサイ気もしますが f(--) 加算平均と標準偏差だけ計算したのですが、測った後に median や 1-99 % のほうが役に立つと思ったり。 それほど面倒でもないので、つぎはそうします。 > しかし、結構速いもんですね。 > オンメモリとはいえ、(直列での) turn-around time は充分だと思いました。 この測定の後でも少し実験してみた感じだと、データサイズの影響がかなり大きいですね。 結果は後ほど。 >>> 1. ひとつの core processor しか使われない > > みかログ: Erlangの+Aオプション > ==== > ブロックするシステムコールを呼ぶと,スケジューラスレッドが応答待ちをしてしまうので,効率が悪くなってしまう. > +A オプションを使って async thread pool > を追加すると,このブロックしてしまう処理をasyncスレッドへ移動でき,スケジューラスレッドは別のErlangコードの実行を続けることが出来る. > その結果,I/O待ちが多く発生するようなコードがかなり高速化できる. > ==== http://blog.mikage.to/mika/2007/06/erlanga_89f7.html > > このへんが関係するのかな?? > しかし、コア 1 つしか使われない、っていうのは説明できないですね > # kai_coordinator が gen_server で直列化される?? +A はやってみたけど、変わらなかった。 > ふと、思ったのですが、クライアントが単一スレッドでリクエストを > 発行していたのだとすると、どの erlang ノードも、ソケット読み込み、 > データ処理、書き込みを直列でやるだけなので、本質的には 1 コアしか > 使われないので正しいのではないでしょうか? Erlang VM の実装がどうなっているのか分からないのだけど、プロセスを起動した時点でコアに割り当てるのだとしたら、その後のリクエストにかかわらずに複数コアが使われるべきだと思う。 Kai は数十のプロセスを使うので。 あと、coordinator は N プロセスを起動して他ノードにリクエストを転送するのだけど、これは完全に並列して行われるので、リクエストが直列であっても内部では複数コアが使われてもいい気がする。 処理が軽いので、top で見えなかっただけという可能性はあるけど。 >>> 2. ボトルネックプロセス >>> >>> 上では 1 クライアントでアクセスした結果しか示しませんでした. >>> というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. > > TCP のレスポンスを返しそこなっているのでしょうかね? > あ、でも、accept したあと、read - write - close は単一プロセスでやってるから > それは無いように思いますね。 > これも難しい。。。 これは別スレッドで書いた deadlock が原因でした. > なんにしても、こういう数字がでてくるとワクワクしますね! > > # 環境はどうやって用意したん? まぁ、そのへんは空気読む感じで :-) > ノード障害のテストを行うときには、接続タイムアウトとかも関係してくる > ようにおもいます。 いまの Kai では、connect するときに数秒でタイムアウトするようにしています。 なので、SYN の再送には期待せずに諦めるようにしていますね。 -- Takeru INOUE <tak...@gm...> |
From: shunichi s. <shi...@gm...> - 2008-08-02 04:31:39
|
ゴミレスですが。。 ノード障害のテストを行うときには、接続タイムアウトとかも関係してくる ようにおもいます。 Manpage of TCP ==== tcp_syn_retries (integer; default: 5) アクティブな TCP 接続に初期 SYN の再送を試みる最大回数。 この数値は 255 よりも大きくすべきではない。 デフォルトの値は 5 で、およそ 180 秒に対応する。 ==== http://www.linux.or.jp/JM/html/LDP_man-pages/man7/tcp.7.html 将来の自分への備忘として f(--) 2008/7/28 Takeru INOUE <tak...@gm...>: > Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. > これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. > > % echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle > > 詳しくは man 7 tcp をみてください. > -- shino |
From: shunichi s. <shi...@gm...> - 2008-08-02 04:08:28
|
しのはらです。 2008/8/2 Takeru INOUE <tak...@gm...>: > 性能測定したときに発見した,高負荷時に kai_api がタイムアウトするという問題点を解決しました. > 高負荷時に,kai_coordinator がときどき deadlock していました. もし原因が分かったのであれば、どのようなデッドロックだったのか 説明してもらってもいいですか? 一つ思いついたのは、 api -(route)-> coordinator -(get)-> api -> store のような、api に再度入ってくるフローがあるところかなぁ、と思っています。 これと api の多重度固定(デフォ 10 だっけ)を合わせると、 たとえば、20 並列のリクエストが来て、10 個の api が埋まってしまうと、 -(get)-> api のところがふんづまるのかな? と。 でもこれだと、 coodinator を gen_server じゃなくす理由にはならない ように思うので、違う気がしています (T-T) > kai_coordinator > - gen_server を使わずに,直接関数を呼び出すように > - (念のため) check_node を呼ばないように > shino |
From: shunichi s. <shi...@gm...> - 2008-08-02 03:52:33
|
2008/8/2 shunichi shino <shi...@gm...>: >>> ■ 問題点 >>> >>> 現時点で,いくつか疑問点があります. >>> >>> 1. ひとつの core processor しか使われない ふと、思ったのですが、クライアントが単一スレッドでリクエストを 発行していたのだとすると、どの erlang ノードも、ソケット読み込み、 データ処理、書き込みを直列でやるだけなので、本質的には 1 コアしか 使われないので正しいのではないでしょうか? -- shino |
From: shunichi s. <shi...@gm...> - 2008-08-02 03:45:47
|
第一回目(?) の性能測定としては充分な結果のようにおもいます \(^ ^)/ 2008/7/28 Takeru INOUE <tak...@gm...>: > Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. > これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. これはネットワークサーバとしては、(いつも忘れてたハマるんだけど)大事な 設定ですよね。 > 2008/7/28 Takeru INOUE <tak...@gm...>: >> 現在の Kai の大雑把な性能を知っておきたかったので,簡単に測定してみました. >> >> 最初に,1ノードで測定しました. >> N,R,W = 1,1,1 です. >> >> set 510 us/query >> get 588 us/query >> >> 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). Dynamo クローンを目指しているので、(99.9 は未だだとして) 99% の値がでると いいなぁ、とおもいました。 # クライアントを書くのがメンドクサイ気もしますが f(--) しかし、結構速いもんですね。 オンメモリとはいえ、(直列での) turn-around time は充分だと思いました。 >> 遅くなっているのは,他のノードに複製を作るためだと思われます. >> >> 5ノードにすると,coordinator への転送時間が追加され,もう少し遅くなります. >> >> set 920 us/query >> get 982 us/query >> >> ■ 問題点 >> >> 現時点で,いくつか疑問点があります. >> >> 1. ひとつの core processor しか使われない みかログ: Erlangの+Aオプション ==== ブロックするシステムコールを呼ぶと,スケジューラスレッドが応答待ちをしてしまうので,効率が悪くなってしまう. +A オプションを使って async thread pool を追加すると,このブロックしてしまう処理をasyncスレッドへ移動でき,スケジューラスレッドは別のErlangコードの実行を続けることが出来る. その結果,I/O待ちが多く発生するようなコードがかなり高速化できる. ==== http://blog.mikage.to/mika/2007/06/erlanga_89f7.html このへんが関係するのかな?? しかし、コア 1 つしか使われない、っていうのは説明できないですね # kai_coordinator が gen_server で直列化される?? >> 2. ボトルネックプロセス >> >> 上では 1 クライアントでアクセスした結果しか示しませんでした. >> というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. TCP のレスポンスを返しそこなっているのでしょうかね? あ、でも、accept したあと、read - write - close は単一プロセスでやってるから それは無いように思いますね。 これも難しい。。。 なんにしても、こういう数字がでてくるとワクワクしますね! # 環境はどうやって用意したん? shino |
From: Takeru I. <tak...@gm...> - 2008-08-01 15:41:22
|
性能測定したときに発見した,高負荷時に kai_api がタイムアウトするという問題点を解決しました. 高負荷時に,kai_coordinator がときどき deadlock していました. 変更点が多いので,trunk ではなく branch にあります. branches/takemaru_deadlock_avoidance_in_coordinator もう少しテストして問題なさそうなら trunk に merge しようと思います. ■ 主な修正点 kai_coordinator - gen_server を使わずに,直接関数を呼び出すように - (念のため) check_node を呼ばないように kai_sup, kai.app - coordinator プロセスを削除 kai_api - 自ノードへの RPC をやめて,直接関数を呼び出すように kai_log - ログにプロセス ID を出力 2008/7/28 Takeru INOUE <tak...@gm...>: > ひとつ書き忘れました. > > 現在の kai_api はソケットを使い捨てるような実装になっています. > 一回リクエストするたびに,ソケットを閉じてしまうということです. > TODO に接続プール (ソケットを保存しておいて使い回すこと) がありますが,現在の実装で高い負荷をかけるときには注意が必要です. > > TCP では,閉じたソケットはしばらく TIME_WAIT という状態に置かれます. > この間,同じ送信元ポート番号を再利用することはできません. > Linux では,デフォルトで 60秒間のようです. > > Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. > これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. > > % echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle > > 詳しくは man 7 tcp をみてください. > > > 2008/7/28 Takeru INOUE <tak...@gm...>: >> 現在の Kai の大雑把な性能を知っておきたかったので,簡単に測定してみました. >> ついでに,いくつかバグを見つけたので修正しておきました. >> >> ■ 測定環境 >> >> まずは測定環境です. >> >> Kai ノード (1-5台) >> CPU Xeon 2.13 GHz x4 >> Memory 8GB >> Gbit Ethernet (RTT 90 us) >> Debian Etch >> OTP R12B-3 >> >> クライアント (1台) >> Perl Cache::Memcached >> クエリ数 10,000 >> データサイズ 1KB >> >> ■ 結果 >> >> 最初に,1ノードで測定しました. >> N,R,W = 1,1,1 です. >> >> set 510 us/query >> get 588 us/query >> >> 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). >> get のほうが遅い理由ははっきりしませんが,データの一貫性を計算するあたりでしょうか. >> CPU 使用率は 70% くらいでしたが,1 core しか使われていませんでした. >> >> 3ノードにし,N,R,W = 3,2,2 にすると,次のようになります. >> >> set 795 us/query >> get 842 us/query >> >> 遅くなっているのは,他のノードに複製を作るためだと思われます. >> >> 5ノードにすると,coordinator への転送時間が追加され,もう少し遅くなります. >> >> set 920 us/query >> get 982 us/query >> >> CPU 使用率は約 20% でした (やはり,1 core しか使われず). >> これが,Kai の基準となる性能です. >> >> ■ 問題点 >> >> 現時点で,いくつか疑問点があります. >> >> 1. ひとつの core processor しか使われない >> >> 起動時に [smp:4] と表示されているにもかかわらず,top で見る限りは,1 core しか使われていないようでした. >> beam.smp と表示される行は 1 つだけであり,その行には 70% と表示され,最上部にはその 1/4 である 14% くらいの数値が表示されます. >> -smp +32 のように明示的に指定しても変わりませんでした. >> kai_coordinator は N のプロセスを spawn しているので,並行処理が行われてしかるべきなのですが.. >> >> 2. ボトルネックプロセス >> >> 上では 1 クライアントでアクセスした結果しか示しませんでした. >> というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. >> はっきりした理由は分かっていませんが,どこかにボトルネックがあるようです (dead lock ではなさそうだし,するようなところもないと思う). >> >> 今の段階で最適化をする予定はありませんが,明らかなボトルネックなどを見つけたら修正しておこうと思います. >> >> ■ 修正したバグ >> >> 測定の過程でいくつかバグを発見したので修正しておきました. >> kai_hash:update_nodes はノードを追加・削除する関数ですが,自分を削除してしまわないように修正しました >> (過負荷時に,自分を削除してしまうことがあったため). >> kai_coordinator:do_route に引数の順番を間違えている箇所があったため,修正しました. >> >> また,通信エラーが発生したときに警告を出力するようにしておきました. >> >> -- >> Takeru INOUE <tak...@gm...> >> > > > > -- > Takeru INOUE <tak...@gm...> > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-07-28 14:08:28
|
ひとつ書き忘れました. 現在の kai_api はソケットを使い捨てるような実装になっています. 一回リクエストするたびに,ソケットを閉じてしまうということです. TODO に接続プール (ソケットを保存しておいて使い回すこと) がありますが,現在の実装で高い負荷をかけるときには注意が必要です. TCP では,閉じたソケットはしばらく TIME_WAIT という状態に置かれます. この間,同じ送信元ポート番号を再利用することはできません. Linux では,デフォルトで 60秒間のようです. Kai は 1000 qps という高い負荷で動作しますが,数十秒で約 60000のポート番号をすべて使い切ってしまうことになります. これを避けるためには,次のようにして TIME_WAIT 状態を短くする必要がありました. % echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 詳しくは man 7 tcp をみてください. 2008/7/28 Takeru INOUE <tak...@gm...>: > 現在の Kai の大雑把な性能を知っておきたかったので,簡単に測定してみました. > ついでに,いくつかバグを見つけたので修正しておきました. > > ■ 測定環境 > > まずは測定環境です. > > Kai ノード (1-5台) > CPU Xeon 2.13 GHz x4 > Memory 8GB > Gbit Ethernet (RTT 90 us) > Debian Etch > OTP R12B-3 > > クライアント (1台) > Perl Cache::Memcached > クエリ数 10,000 > データサイズ 1KB > > ■ 結果 > > 最初に,1ノードで測定しました. > N,R,W = 1,1,1 です. > > set 510 us/query > get 588 us/query > > 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). > get のほうが遅い理由ははっきりしませんが,データの一貫性を計算するあたりでしょうか. > CPU 使用率は 70% くらいでしたが,1 core しか使われていませんでした. > > 3ノードにし,N,R,W = 3,2,2 にすると,次のようになります. > > set 795 us/query > get 842 us/query > > 遅くなっているのは,他のノードに複製を作るためだと思われます. > > 5ノードにすると,coordinator への転送時間が追加され,もう少し遅くなります. > > set 920 us/query > get 982 us/query > > CPU 使用率は約 20% でした (やはり,1 core しか使われず). > これが,Kai の基準となる性能です. > > ■ 問題点 > > 現時点で,いくつか疑問点があります. > > 1. ひとつの core processor しか使われない > > 起動時に [smp:4] と表示されているにもかかわらず,top で見る限りは,1 core しか使われていないようでした. > beam.smp と表示される行は 1 つだけであり,その行には 70% と表示され,最上部にはその 1/4 である 14% くらいの数値が表示されます. > -smp +32 のように明示的に指定しても変わりませんでした. > kai_coordinator は N のプロセスを spawn しているので,並行処理が行われてしかるべきなのですが.. > > 2. ボトルネックプロセス > > 上では 1 クライアントでアクセスした結果しか示しませんでした. > というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. > はっきりした理由は分かっていませんが,どこかにボトルネックがあるようです (dead lock ではなさそうだし,するようなところもないと思う). > > 今の段階で最適化をする予定はありませんが,明らかなボトルネックなどを見つけたら修正しておこうと思います. > > ■ 修正したバグ > > 測定の過程でいくつかバグを発見したので修正しておきました. > kai_hash:update_nodes はノードを追加・削除する関数ですが,自分を削除してしまわないように修正しました > (過負荷時に,自分を削除してしまうことがあったため). > kai_coordinator:do_route に引数の順番を間違えている箇所があったため,修正しました. > > また,通信エラーが発生したときに警告を出力するようにしておきました. > > -- > Takeru INOUE <tak...@gm...> > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-07-28 13:35:05
|
現在の Kai の大雑把な性能を知っておきたかったので,簡単に測定してみました. ついでに,いくつかバグを見つけたので修正しておきました. ■ 測定環境 まずは測定環境です. Kai ノード (1-5台) CPU Xeon 2.13 GHz x4 Memory 8GB Gbit Ethernet (RTT 90 us) Debian Etch OTP R12B-3 クライアント (1台) Perl Cache::Memcached クエリ数 10,000 データサイズ 1KB ■ 結果 最初に,1ノードで測定しました. N,R,W = 1,1,1 です. set 510 us/query get 588 us/query 毎秒 2000弱のクエリを処理できる計算になります (並列性は考慮せず). get のほうが遅い理由ははっきりしませんが,データの一貫性を計算するあたりでしょうか. CPU 使用率は 70% くらいでしたが,1 core しか使われていませんでした. 3ノードにし,N,R,W = 3,2,2 にすると,次のようになります. set 795 us/query get 842 us/query 遅くなっているのは,他のノードに複製を作るためだと思われます. 5ノードにすると,coordinator への転送時間が追加され,もう少し遅くなります. set 920 us/query get 982 us/query CPU 使用率は約 20% でした (やはり,1 core しか使われず). これが,Kai の基準となる性能です. ■ 問題点 現時点で,いくつか疑問点があります. 1. ひとつの core processor しか使われない 起動時に [smp:4] と表示されているにもかかわらず,top で見る限りは,1 core しか使われていないようでした. beam.smp と表示される行は 1 つだけであり,その行には 70% と表示され,最上部にはその 1/4 である 14% くらいの数値が表示されます. -smp +32 のように明示的に指定しても変わりませんでした. kai_coordinator は N のプロセスを spawn しているので,並行処理が行われてしかるべきなのですが.. 2. ボトルネックプロセス 上では 1 クライアントでアクセスした結果しか示しませんでした. というのは,複数のクライアントに同時にアクセスさせると,kai_api:route がタイムアウトすることがあったためです. はっきりした理由は分かっていませんが,どこかにボトルネックがあるようです (dead lock ではなさそうだし,するようなところもないと思う). 今の段階で最適化をする予定はありませんが,明らかなボトルネックなどを見つけたら修正しておこうと思います. ■ 修正したバグ 測定の過程でいくつかバグを発見したので修正しておきました. kai_hash:update_nodes はノードを追加・削除する関数ですが,自分を削除してしまわないように修正しました (過負荷時に,自分を削除してしまうことがあったため). kai_coordinator:do_route に引数の順番を間違えている箇所があったため,修正しました. また,通信エラーが発生したときに警告を出力するようにしておきました. -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-07-27 13:19:50
|
ありがとうございます. common_test の準備と同じで,開発者が事前にやっておくべきことなのかなと思いました. 単に使うだけであれば不要なので,Makefile に入れなくてもいい気がします. Erlang ML をみても,仕様変更に関する記述は見つかりませんねぇ. どういう経緯だったんだろう? 2008/7/27 masahito ikuta <coo...@gm...>: > メッセージ通り、下記を実行して ~/.dialyzer_plt を作成する事で > Makefile を修正する事なく make dialyze できました。 > > ERL_LIB=/opt/local/lib/erlang/lib/ > dialyzer --build_plt -r $ERL_LIB/kernel-2.12.3/ebin > $ERL_LIB/stdlib-1.15.3/ebin $ERL_LIB/mnesia-4.4.3/ebin > > んー、~/.dialyzer_plt が存在しない際の処理を Makefile に入れるべきですかねぇ? > そもそも、build_plt する時の引数は ./ebin だけでも十分のような気がするなぁ・・・。 > もう少し調べてみますね。 > > 2008/7/27 masahito ikuta <coo...@gm...>: >> R12B-3 をインストールして実行した所、エラーが再現しました。 >> 早速、調べてみますね。 >> >> Could not find the plt: /Users/cooldaemon/.dialyzer_plt >> Use the options >> --build_plt to build a new one; or >> --add_to_plt to add to an existing plt. >> For example: >> dialyzer --build_plt -r $ERL_TOP/lib/kernel/ebin\ >> $ERL_TOP/lib/stdlib/ebin\ >> $ERL_TOP/lib/mnesia/ebin >> dialyzer: Internal problems were encountered in the analysis. >> make[1]: *** [dialyze] Error 1 >> make: *** [dialyze] Error 2 >> >> >> 2008/7/26 Takeru INOUE <tak...@gm...>: >>>> 余談ですが、test_single に感動しました。 >>> >>> こういうのがあるんだろうなぁと思ってたところだったので,同じく感動しました. >>> >>>> んー、そろそろ、CouchDB みたいに Autotools に対応したいですね。 >>>> >>>> 2008/7/26 masahito ikuta <coo...@gm...>: >>>>> 小さい修正だったので >>>>> いきなり trunk に追加してしまいました。 >>>>> >>>>> make docs >>>>> doc ディレクトリ配下に HTML 形式のドキュメントを生成します。 >>>>> >>>>> make dialyze >>>>> src 配下の *.src に対して dialyzer を実行します。 >>>>> >>>>> 不備等ございましたら、ご指摘をお願い致します。 >>> >>> ドキュメント周りまでやってもらっちゃって,ありがとうです. >>> >>> R12B-3 で make dialyze すると↓のようなエラーが出ています. >>> ググった限りでは解決方法はわかってないのですが,共有しておきます. >>> あとでもうちょっと見てみます. >>> >>> % make dialyze >>> cd src; make dialyze >>> make[1]: ディレクトリ `/home/inoue/src/kai/trunk/src' に入ります >>> dialyzer --succ_typings -c kai_config.erl kai_log.erl kai_hash.erl >>> kai_store.erl kai_version.erl kai_coordinator.erl kai_sync.erl >>> kai_membership.erl kai_sup.erl kai.erl kai_tcp_server.erl kai_api.erl >>> kai_memcache.erl vclock.erl >>> Checking whether the PLT /home/inoue/.dialyzer_plt is up-to-date... >>> Could not find the plt: /home/inoue/.dialyzer_plt >>> >>> >>>>> -- >>>>> cooldaemon >>>>> >>>> >>>> -- >>>> cooldaemon >>>> >>>> ------------------------------------------------------------------------- >>>> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge >>>> Build the coolest Linux based applications with Moblin SDK & win great prizes >>>> Grand prize is a trip for two to an Open Source event anywhere in the world >>>> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >>>> _______________________________________________ >>>> Kai-devel-ja mailing list >>>> Kai...@li... >>>> https://lists.sourceforge.net/lists/listinfo/kai-devel-ja >>>> >>> >>> >>> >>> -- >>> Takeru INOUE <tak...@gm...> >>> >> >> >> >> -- >> cooldaemon >> > > > > -- > cooldaemon > -- Takeru INOUE <tak...@gm...> |
From: masahito i. <coo...@gm...> - 2008-07-27 12:44:11
|
メッセージ通り、下記を実行して ~/.dialyzer_plt を作成する事で Makefile を修正する事なく make dialyze できました。 ERL_LIB=/opt/local/lib/erlang/lib/ dialyzer --build_plt -r $ERL_LIB/kernel-2.12.3/ebin $ERL_LIB/stdlib-1.15.3/ebin $ERL_LIB/mnesia-4.4.3/ebin んー、~/.dialyzer_plt が存在しない際の処理を Makefile に入れるべきですかねぇ? そもそも、build_plt する時の引数は ./ebin だけでも十分のような気がするなぁ・・・。 もう少し調べてみますね。 2008/7/27 masahito ikuta <coo...@gm...>: > R12B-3 をインストールして実行した所、エラーが再現しました。 > 早速、調べてみますね。 > > Could not find the plt: /Users/cooldaemon/.dialyzer_plt > Use the options > --build_plt to build a new one; or > --add_to_plt to add to an existing plt. > For example: > dialyzer --build_plt -r $ERL_TOP/lib/kernel/ebin\ > $ERL_TOP/lib/stdlib/ebin\ > $ERL_TOP/lib/mnesia/ebin > dialyzer: Internal problems were encountered in the analysis. > make[1]: *** [dialyze] Error 1 > make: *** [dialyze] Error 2 > > > 2008/7/26 Takeru INOUE <tak...@gm...>: >>> 余談ですが、test_single に感動しました。 >> >> こういうのがあるんだろうなぁと思ってたところだったので,同じく感動しました. >> >>> んー、そろそろ、CouchDB みたいに Autotools に対応したいですね。 >>> >>> 2008/7/26 masahito ikuta <coo...@gm...>: >>>> 小さい修正だったので >>>> いきなり trunk に追加してしまいました。 >>>> >>>> make docs >>>> doc ディレクトリ配下に HTML 形式のドキュメントを生成します。 >>>> >>>> make dialyze >>>> src 配下の *.src に対して dialyzer を実行します。 >>>> >>>> 不備等ございましたら、ご指摘をお願い致します。 >> >> ドキュメント周りまでやってもらっちゃって,ありがとうです. >> >> R12B-3 で make dialyze すると↓のようなエラーが出ています. >> ググった限りでは解決方法はわかってないのですが,共有しておきます. >> あとでもうちょっと見てみます. >> >> % make dialyze >> cd src; make dialyze >> make[1]: ディレクトリ `/home/inoue/src/kai/trunk/src' に入ります >> dialyzer --succ_typings -c kai_config.erl kai_log.erl kai_hash.erl >> kai_store.erl kai_version.erl kai_coordinator.erl kai_sync.erl >> kai_membership.erl kai_sup.erl kai.erl kai_tcp_server.erl kai_api.erl >> kai_memcache.erl vclock.erl >> Checking whether the PLT /home/inoue/.dialyzer_plt is up-to-date... >> Could not find the plt: /home/inoue/.dialyzer_plt >> >> >>>> -- >>>> cooldaemon >>>> >>> >>> -- >>> cooldaemon >>> >>> ------------------------------------------------------------------------- >>> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge >>> Build the coolest Linux based applications with Moblin SDK & win great prizes >>> Grand prize is a trip for two to an Open Source event anywhere in the world >>> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >>> _______________________________________________ >>> Kai-devel-ja mailing list >>> Kai...@li... >>> https://lists.sourceforge.net/lists/listinfo/kai-devel-ja >>> >> >> >> >> -- >> Takeru INOUE <tak...@gm...> >> > > > > -- > cooldaemon > -- cooldaemon |
From: masahito i. <coo...@gm...> - 2008-07-27 10:08:43
|
R12B-3 をインストールして実行した所、エラーが再現しました。 早速、調べてみますね。 Could not find the plt: /Users/cooldaemon/.dialyzer_plt Use the options --build_plt to build a new one; or --add_to_plt to add to an existing plt. For example: dialyzer --build_plt -r $ERL_TOP/lib/kernel/ebin\ $ERL_TOP/lib/stdlib/ebin\ $ERL_TOP/lib/mnesia/ebin dialyzer: Internal problems were encountered in the analysis. make[1]: *** [dialyze] Error 1 make: *** [dialyze] Error 2 2008/7/26 Takeru INOUE <tak...@gm...>: >> 余談ですが、test_single に感動しました。 > > こういうのがあるんだろうなぁと思ってたところだったので,同じく感動しました. > >> んー、そろそろ、CouchDB みたいに Autotools に対応したいですね。 >> >> 2008/7/26 masahito ikuta <coo...@gm...>: >>> 小さい修正だったので >>> いきなり trunk に追加してしまいました。 >>> >>> make docs >>> doc ディレクトリ配下に HTML 形式のドキュメントを生成します。 >>> >>> make dialyze >>> src 配下の *.src に対して dialyzer を実行します。 >>> >>> 不備等ございましたら、ご指摘をお願い致します。 > > ドキュメント周りまでやってもらっちゃって,ありがとうです. > > R12B-3 で make dialyze すると↓のようなエラーが出ています. > ググった限りでは解決方法はわかってないのですが,共有しておきます. > あとでもうちょっと見てみます. > > % make dialyze > cd src; make dialyze > make[1]: ディレクトリ `/home/inoue/src/kai/trunk/src' に入ります > dialyzer --succ_typings -c kai_config.erl kai_log.erl kai_hash.erl > kai_store.erl kai_version.erl kai_coordinator.erl kai_sync.erl > kai_membership.erl kai_sup.erl kai.erl kai_tcp_server.erl kai_api.erl > kai_memcache.erl vclock.erl > Checking whether the PLT /home/inoue/.dialyzer_plt is up-to-date... > Could not find the plt: /home/inoue/.dialyzer_plt > > >>> -- >>> cooldaemon >>> >> >> -- >> cooldaemon >> >> ------------------------------------------------------------------------- >> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge >> Build the coolest Linux based applications with Moblin SDK & win great prizes >> Grand prize is a trip for two to an Open Source event anywhere in the world >> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >> _______________________________________________ >> Kai-devel-ja mailing list >> Kai...@li... >> https://lists.sourceforge.net/lists/listinfo/kai-devel-ja >> > > > > -- > Takeru INOUE <tak...@gm...> > -- cooldaemon |
From: Takeru I. <tak...@gm...> - 2008-07-27 03:05:06
|
>> ドキュメントには,sync を呼ばなかったときの同期について書いてない気がする. >> 不親切だなぁ. > > そういうものだと思います。ファイルシステムでディスク(というか下回り)と > sync するコストは高い(高すぎる)ので、よっぽどなんか書いてあるのを除き、 > sync はしないんじゃないかと。 数十MB 書き込まないと自動的な sync は行われなかった,という記事がありました. detsの調査続き1 - Erlangとか,Hadoopとか,C++とか http://d.hatena.ne.jp/huchiyama1976/20080422/1208876182 > Dynamo は、レプリケーションで永続性を保証するんだと思ってました。 > なので、メモリベースでデータを持つんだろうなぁ、と。 > と、ここまで書いたところで、ノード毎に、物理的な RAM 以上のメモリを > 持つことを想定しているのならば、ファイルにマップする意味があるのかなぁ、と > おもいました。 基本は replication なんだろうけど,システムを止められるようにディスクに書き込むオプションも持たせてあるんだと思う. Amazon では,MySQL や BDB を使ってるらしい. Kai としては,まず単純な disk storage (dets?) をサポートして,毎回 sync するようにして,後でメモリキャッシュと組み合わせたり sync をサボったりという最適化を行うのが良いんじゃないかな. >> いまはディスクベースのストレージを比較しているので,ets は除くとします. >> dets (w/ sync) と couch_btree をランダムアクセスで比較すると, >> >> - set の速度はほぼ同じ > > これは、データの永続性を保証する書き込みであれば、 sync(2) なので、 > ディスク(永続化デバイス)の性能に依存するし、安いデスクトップサーバで > あれば、遅すぎる( =~ 1msec/sync) とおもています。 Amazon では基本的には常に sync させているっぽくて,どうしても速度が必要なときのみ遅延書き込みをさせているらしい. >> - get は dets のが速い >> - ファイルサイズは dets のが小さい >> 壊れにくさはよく分からないですが,dets には修復機能が付いているようです. > > こっちは実装依存なので分からんです f(--) > couchDB のほうが性能が悪いだけ、という可能性もあるですかね。 > >> ひとつ気になるのが,CouchDB がわざわざ自前の tree を作った理由です. >> ソースをみると範囲検索が必要だったのはわかるのですが,それにしても ordered_set dets ではいけなかったんだろうか? > > これは気になります。couchDB の人に聞いてみるのが、、、 > # といいつつ、このスレッドを英語でやれ、といわれると f(--) 単純に ordered_set dets を使ってない理由を聞いてみるという手はあるけど,Kai 的には直接役に立たない情報なんだよな (ordered である必要がない). >> Kai も Merkle tree を考えると set dets でいいのか? という疑問がないわけではないのですが,Merkle tree >> は外付けで作る可能性もあるので,ひとまず無視していいかなぁ. >> >>>> 64bit erlang だったら、ets でも容量制限は事実上無い、みたいな話が >>> >>> あれ? >>> ets って昔から容量制限が無いと思い込んでいたのですが >>> 容量制限ってあるんでしたっけ? >> >> 工夫がなければ 32bit アーキテクチャなら 4GB で頭打ちになりそう,ということかな? > > 仮想アドレス空間のうち、アプリが使えるのが、32bit Win なら 2GB、32bit Linux だったら > 3GB なので、メモリ上に単純に置くならその制限にひっかかるでしょうねぇ。 > 64bit Linux なら、制限はほぼない、と思っていいはず。 3GB なんだ. 知らなかった.. >>> dets と Mnesia は、1テーブルの最大サイズが 2GByte ですよね? >>> (Mnesia は、内部で dets を利用) >> >> ですね. >> これが面倒の元凶.. > > dets の実装は知らないのですが、file で 2GB と聞くと、いわゆる large file の問題 > な気がするのですが、それと一緒? たぶん,そうじゃないのかな. ドキュメントに 2GB まで,って書いてあったので,鵜呑みにしてる. > # 制限がどこでついてるのか、自分で分かってないので調べます > # OS なのか、erlang なのか、dets なのか?? > > -- > shino > -- Takeru INOUE <tak...@gm...> |
From: shunichi s. <shi...@gm...> - 2008-07-26 13:33:35
|
なんかおもしろくなってきました (o^<^)o 2008/7/26 Takeru INOUE <tak...@gm...>: >> で、dets には、 sync という関数が切られているので、ファイルの書き込みは >> クライアントに委ねられているようです。 > > ドキュメントには,sync を呼ばなかったときの同期について書いてない気がする. > 不親切だなぁ. そういうものだと思います。ファイルシステムでディスク(というか下回り)と sync するコストは高い(高すぎる)ので、よっぽどなんか書いてあるのを除き、 sync はしないんじゃないかと。 > ただし,ordered_set を指定すると balanced binary tree みたい. そうなのかぁーーー! # てもとに programming erlang が無い 。。。。 > それにしても,couch_btree のファイルサイズが 100倍ってのはひどいような.. > データが大きければ無視できるのかもしれないけど. これ分からないですねぇ。 >> 1.保存と取得の速度が早い >> 2.壊れ難い >> 3.ファイルサイズが小さい >> >> まー、1 の箇所でいきなり迷走してますが(w; > Dynamo は、レプリケーションで永続性を保証するんだと思ってました。 なので、メモリベースでデータを持つんだろうなぁ、と。 と、ここまで書いたところで、ノード毎に、物理的な RAM 以上のメモリを 持つことを想定しているのならば、ファイルにマップする意味があるのかなぁ、と おもいました。 > いまはディスクベースのストレージを比較しているので,ets は除くとします. > dets (w/ sync) と couch_btree をランダムアクセスで比較すると, > > - set の速度はほぼ同じ これは、データの永続性を保証する書き込みであれば、 sync(2) なので、 ディスク(永続化デバイス)の性能に依存するし、安いデスクトップサーバで あれば、遅すぎる( =~ 1msec/sync) とおもています。 > - get は dets のが速い > - ファイルサイズは dets のが小さい > 壊れにくさはよく分からないですが,dets には修復機能が付いているようです. こっちは実装依存なので分からんです f(--) couchDB のほうが性能が悪いだけ、という可能性もあるですかね。 > ひとつ気になるのが,CouchDB がわざわざ自前の tree を作った理由です. > ソースをみると範囲検索が必要だったのはわかるのですが,それにしても ordered_set dets ではいけなかったんだろうか? これは気になります。couchDB の人に聞いてみるのが、、、 # といいつつ、このスレッドを英語でやれ、といわれると f(--) > Kai も Merkle tree を考えると set dets でいいのか? という疑問がないわけではないのですが,Merkle tree > は外付けで作る可能性もあるので,ひとまず無視していいかなぁ. > >>> 64bit erlang だったら、ets でも容量制限は事実上無い、みたいな話が >> >> あれ? >> ets って昔から容量制限が無いと思い込んでいたのですが >> 容量制限ってあるんでしたっけ? > > 工夫がなければ 32bit アーキテクチャなら 4GB で頭打ちになりそう,ということかな? 仮想アドレス空間のうち、アプリが使えるのが、32bit Win なら 2GB、32bit Linux だったら 3GB なので、メモリ上に単純に置くならその制限にひっかかるでしょうねぇ。 64bit Linux なら、制限はほぼない、と思っていいはず。 >> dets と Mnesia は、1テーブルの最大サイズが 2GByte ですよね? >> (Mnesia は、内部で dets を利用) > > ですね. > これが面倒の元凶.. dets の実装は知らないのですが、file で 2GB と聞くと、いわゆる large file の問題 な気がするのですが、それと一緒? # 制限がどこでついてるのか、自分で分かってないので調べます # OS なのか、erlang なのか、dets なのか?? -- shino |
From: Takeru I. <tak...@gm...> - 2008-07-26 05:41:54
|
> で、dets には、 sync という関数が切られているので、ファイルの書き込みは > クライアントに委ねられているようです。 ドキュメントには,sync を呼ばなかったときの同期について書いてない気がする. 不親切だなぁ. > サイズについては、、よくわからんですね > # dets は、、、ハッシュテーブルだっけ?? # 忘れた f(--) ets がハッシュテーブルなので同じじゃないでしょうか. ただし,ordered_set を指定すると balanced binary tree みたい. # データ構造はプログラミング Erlang p.225 に書いてある. # Efficienty Guide に "ets に当てはまることは dets にもだいたい当てはまる" とある. それにしても,couch_btree のファイルサイズが 100倍ってのはひどいような.. データが大きければ無視できるのかもしれないけど. > gist 最高ですよね!! > fork して頂き、修正後のファイルを見せて頂けると助かります。 > push request を頂ければ、master に反映します。 > >> dets/btree の検証は、容量制限の回避が目的でしょうか? > > 単純に、どちらの方が、key/value ペアを保存するストレージとして > 優れているんだろうなー?という疑問を持ったのが発端です。 > > 私が考えている "優れている" の定義は下記の通りです。 > (優先順位が高いものから順に並べています) > 1.保存と取得の速度が早い > 2.壊れ難い > 3.ファイルサイズが小さい > > まー、1 の箇所でいきなり迷走してますが(w; いまはディスクベースのストレージを比較しているので,ets は除くとします. dets (w/ sync) と couch_btree をランダムアクセスで比較すると, - set の速度はほぼ同じ - get は dets のが速い - ファイルサイズは dets のが小さい ということですね. 壊れにくさはよく分からないですが,dets には修復機能が付いているようです. ここまでは,dets のほうが適していると考えて良さそうですが,どうでしょうか? ひとつ気になるのが,CouchDB がわざわざ自前の tree を作った理由です. ソースをみると範囲検索が必要だったのはわかるのですが,それにしても ordered_set dets ではいけなかったんだろうか? Kai も Merkle tree を考えると set dets でいいのか? という疑問がないわけではないのですが,Merkle tree は外付けで作る可能性もあるので,ひとまず無視していいかなぁ. >> 64bit erlang だったら、ets でも容量制限は事実上無い、みたいな話が > > あれ? > ets って昔から容量制限が無いと思い込んでいたのですが > 容量制限ってあるんでしたっけ? 工夫がなければ 32bit アーキテクチャなら 4GB で頭打ちになりそう,ということかな? > dets と Mnesia は、1テーブルの最大サイズが 2GByte ですよね? > (Mnesia は、内部で dets を利用) ですね. これが面倒の元凶.. > 2008/7/25 Shunichi Shinohara <shi...@gm...>: >> On 07/25/2008 "masahito ikuta" <coo...@gm...> wrote: >>> shino さんから、sync のご指摘を頂いているので >>> その辺りも考慮してみないといけませんね。 >> >> gist がすてきなので、手元でやってみました >> # が、ここから push できない f(--) >> >> 34> couchdb_btree_vs_dets:test(1000). >> --<dets>-- >> set:10(27)ms >> get:40(42)ms >> --<dets with sync>-- >> set:520(1868)ms >> get:40(41)ms >> --<CouchDB B-Tree(case1)>-- >> set:0(5)ms >> get:0(6)ms >> --<CouchDB B-Tree(case2)>-- >> set:450(648)ms >> get:150(171)ms >> --<CouchDB B-Tree(case3)>-- >> set:440(648)ms >> get:10(5)ms >> --<CouchDB B-Tree(case4)>-- >> set:0(5)ms >> get:210(228)ms >> >>> うーん、dets のテーブルを束ねて容量制限を回避して >>> 場合によっては ets をキャッシュとして使う >>> 等の方が初めは楽かもしれませんね。 >> >> dets/btree の検証は、容量制限の回避が目的でしょうか? >> 64bit erlang だったら、ets でも容量制限は事実上無い、みたいな話が >> erlang-questions で教えてもらったような。。。 うろ覚え。 >> >> shino >> > > > > -- > cooldaemon > -- Takeru INOUE <tak...@gm...> |
From: Takeru I. <tak...@gm...> - 2008-07-26 04:31:37
|
> 余談ですが、test_single に感動しました。 こういうのがあるんだろうなぁと思ってたところだったので,同じく感動しました. > んー、そろそろ、CouchDB みたいに Autotools に対応したいですね。 > > 2008/7/26 masahito ikuta <coo...@gm...>: >> 小さい修正だったので >> いきなり trunk に追加してしまいました。 >> >> make docs >> doc ディレクトリ配下に HTML 形式のドキュメントを生成します。 >> >> make dialyze >> src 配下の *.src に対して dialyzer を実行します。 >> >> 不備等ございましたら、ご指摘をお願い致します。 ドキュメント周りまでやってもらっちゃって,ありがとうです. R12B-3 で make dialyze すると↓のようなエラーが出ています. ググった限りでは解決方法はわかってないのですが,共有しておきます. あとでもうちょっと見てみます. % make dialyze cd src; make dialyze make[1]: ディレクトリ `/home/inoue/src/kai/trunk/src' に入ります dialyzer --succ_typings -c kai_config.erl kai_log.erl kai_hash.erl kai_store.erl kai_version.erl kai_coordinator.erl kai_sync.erl kai_membership.erl kai_sup.erl kai.erl kai_tcp_server.erl kai_api.erl kai_memcache.erl vclock.erl Checking whether the PLT /home/inoue/.dialyzer_plt is up-to-date... Could not find the plt: /home/inoue/.dialyzer_plt >> -- >> cooldaemon >> > > -- > cooldaemon > > ------------------------------------------------------------------------- > This SF.Net email is sponsored by the Moblin Your Move Developer's challenge > Build the coolest Linux based applications with Moblin SDK & win great prizes > Grand prize is a trip for two to an Open Source event anywhere in the world > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > Kai-devel-ja mailing list > Kai...@li... > https://lists.sourceforge.net/lists/listinfo/kai-devel-ja > -- Takeru INOUE <tak...@gm...> |