0

Riak のドキュメント (Python バインディングを使用) によると、get_keys()は非常に高価であり、本番環境には適していません。私の質問は、非常に単純なマップ クエリが適しているかどうかです。たとえば、次の関数でのみ map ステージを使用します。

function(v) { return [v.key]; }

これは get_keys() よりも優れたパフォーマンスを発揮しますか? なぜ Riak は現在のバージョンの get_keys() ではなく、この実装を同梱しないのでしょうか? バケットのキーをリストするより良い方法はありますか?

4

2 に答える 2

2

get_keys()関数はバックエンドで呼び出し、list_keysキースペースのフルスキャンを実行するため、コストのかかる操作と見なされます。Riakバックエンドによっては、ディスクに保存されているデータのフルスキャンが含まれる場合もあります(InnoStoreが思い浮かびます)。デフォルトのストレージバックエンド(Bitcask)はすべてのキーをメモリに保存するため、パフォーマンスはそれほど問題にはなりません。

もう1つの理由list_keysは、芭蕉の開発者がすべてのキーの「折り畳み」と呼んでいるものを含んでいたため、以前はブロッキング操作であったためです。list_keys(ライブキースペースを読み取る代わりに)バケットのスナップショットを使用するようになりました。これにより、より軽量な操作も可能になります。

これは、Riak1.0へのアップグレードで簡単になります。LevelDBバックエンドを使用している場合は、バケットでセカンダリインデックスを有効にし、$keyインデックス(Riakによって自動的に提供される)を使用して、バケット内のすべてのキーのリストを取得できます。

Riakがこのようなもののより良い実装で出荷されない理由については:機能が何のためにあるのか尋ねてください。RDBMSでは、テーブルのすべての主キーを取得するには、全表スキャンが必要です。Riakでは、バケットからすべてのキーを取得するには、すべてのノードのすべてのデータをスキャンしてから、キー名を元のノードに返送し、そのデータを結合して、呼び出し元のクライアントに送信する必要があります。Riakは分散されており、順序付けされていないため、この操作はどのようにスライスしてもコストがかかると述べています。上で概説したように、それをより良くする方法があります。

于 2011-10-01T13:23:07.193 に答える
2

eleveldb バックエンド ( LevelDBライブラリで実装されている) を使用している場合、キーはソートされた順序で保存されるため、次のようなことができます。

def get_bucket_keys(riak_client, bucket_name, start='0', stop='Z'):
    for record_key in riak_client.index(bucket_name, '$key', start, stop).run():
        yield record_key

for key in get_bucket_keys(riak.RiakClient(), 'mybucket'):
    print key

eleveldb を使用すると、riak はすべてのノードをスキャンして、指定された範囲のみを検索します。そのため、キー範囲を制御できる方法でバケットに入力すると、リスト バケット キーのパフォーマンスが非常に高くなります。

トレードオフは、各ノードで処理されるキーの数に LIMIT を指定できないことです。そのため、キーのリストが必要なバケットのキーを制御する必要があります。

于 2011-12-22T13:23:39.260 に答える