LevelDB をバックエンドとして使用している場合に Riak でオブジェクトを更新することによるパフォーマンスへの影響は、各インデックスにいくつのエントリがあるかによって影響を受けるべきではありません。ただし、各パーティションに格納されている合計データ量、キーが最後に更新されてから書き込まれたデータ量、個々のオブジェクトに指定された異なるインデックス エントリの数によって影響を受ける可能性があります。
LevelDB がデータを保存する方法
値が LevelDB に書き込まれると.log
、最上位のファイルに追加されます。ファイルが特定のサイズ (1Mb だと思います。そのサイズが構成可能かどうかは覚えていません) に達すると、.log
ファイルが切断され、新しいファイルが開始されます。これらのファイルはソートされていません。最上位 (レベル 0) に複数のファイルがある場合、圧縮がトリガーされます。圧縮では、1 つまたは複数のトップ レベル ファイルが結合され、それらに含まれるキーが並べ替えられ、これらの並べ替えられたリストが.sst
レベル 1 の適切なファイルとマージされます。保存されているキーの範囲を示す、並べ替えられたレベルごとにマニフェスト ファイルが作成されます。各.sst
ファイルにあります。このプロセスは、下位レベルでも必要に応じて繰り返され、各レベルは前のレベルの約 10 倍のデータ量を格納できます。
既に存在するキーに新しい値が書き込まれると、最上位レベルに単純に書き込まれ、以前に書き込まれた下位レベルの値がマスクされます。以前の値は、通常の圧縮によって新しい値が下位レベルに移動するときに置き換えられます。
これが読書に与える影響
キーが要求されると、LevelDB はレベル 0 から開始し、そこにある各ファイルをチェックして、キーが含まれているかどうかを確認します。そうでない場合は、レベル 1 に移動し、マニフェストが示すファイルにキーが含まれていることを確認します。これは、キーが見つかるか、最低レベルに到達するまで、連続して低いレベルに対して繰り返されます。したがって、最後に書き込まれたキーの値が返されます。各 LevelDB バックエンドに保存されるデータの総量が増加するにつれて、使用されるレベルの数、検索する必要があるファイルの数、したがって最も古いデータを読み取る時間が増加します。
LevelDB バックエンドでのインデックスの実装方法
LevelDB バックエンドに値を格納する場合、バックエンドで使用される生のキーは の sext エンコーディングです{o,Bucket,Key}
。オブジェクトでインデックス エントリが指定されている場合、インデックスごとに、 の sext エンコーディングである追加のキーが格納され{i,Bucket,IndexName,IndexValue,Key}
ます。
値が更新されたときに古いインデックス エントリを削除するには、各 PUT または DELETE の前に GET を実行し、以前のオブジェクトのインデックス仕様を格納されているオブジェクトのインデックス仕様と比較し、古いキーを削除し、すべての古い{i,...}
キーを削除する必要があります。新しいものが追加されました。
インデックス クエリ
LevelDB はソートされた方法でデータを格納するため、インデックス クエリは、キー{i,Bucket,IndexName,FirstValue,<<>>}
スルー{i,Bucket,IndexName,LastValue,<<255,255,255,255>>}
(バイナリ<<255,...
は、ソート順の最後の可能なキーを示す理論値) から開始するフォールドとして実装されます。ソートされた各レベルのマニフェストが参照されるため、折り畳まれる範囲の一部を含むデータ ファイルのみを開く必要があります。
概要
example_bin のほぼすべての値は異なる値です。インデックスの 1 つの特定の値に対するクエリは、1 つまたは少数のオブジェクトのみを返します。このようなインデックスは、電子メール アドレスまたは登録時間 (UNIX タイムスタンプとして) である可能性があります。
クエリに必要なインデックス エントリと個々の値は、並べ替えられた各レベルの 1 つのファイル内に完全に収まる可能性が高いため、このクエリでは、レベル 0 のすべてのファイルと、それより下位の各レベルの 1 つのファイルを開いて検索する必要があります。保存されているデータの量に依存する存在するレベルの数は、最大の決定要因になります。
example_int インデックスの可能な値はいくつかしかありません。したがって、特定のインデックス値のクエリは、膨大な数のオブジェクトを返します。このようなインデックスは、「管理者」や「顧客」などのユーザーのカテゴリを表すことができます。
個々の値をクエリするためのインデックス エントリの範囲が広いほど、ソートされたレベルごとに複数のファイルを参照する必要が生じる可能性が高くなります。このクエリは、フォールドに含まれるインデックス エントリの数が多く、開く必要があるファイルの数が多い可能性があるため、前のクエリよりも時間がかかります。
これらのオブジェクトを更新すると、パフォーマンスにどのような影響がありますか? オブジェクトが更新されるたびにインデックスをチェックする必要があることを理解しています。上記の例のいずれも、Riak にとって時間またはリソースを消費するタスクを構成できますか?
ここで必要な時間は、古いオブジェクトを取得するために必要な時間と、インデックス エントリへの変更の数によって異なります。このプロセスでは、インデックス全体が全体と見なされることはなく、前のオブジェクトのエントリと新しいオブジェクトのエントリのみが考慮されます。したがって、パフォーマンスはインデックスのエントリ数ではなく、このオブジェクトがエントリを持っている、または持っていたインデックスの数によって影響を受けます。