バケットに大量の小さなレコードを書き込むのは書き込み時に簡単で効率的ですが、キーを知らない可能性が高いため、値を読み取ろうとすると代わりに高額になるというペナルティがあります。これらのキーをセカンダリインデックス、キーフィルター、またはさらに悪いことに、バケット内のすべてのキーを調べる必要がある場合(これは非常に重い操作であり、実稼働環境では推奨されません)、これはかなり効率が悪くなりますキーでデータを取得するよりも、スケーリングもしません。
Riakには追加機能もありません。つまり、レコードを更新して新しいログエントリを追加するには、最初にレコードを読み取ってから書き込む必要があります。執筆をどのように整理および調整するかによっては、これにより、同じレコードが同時に更新される可能性があります。これは、ソリューションを設計するときに考慮する必要があります。
ログエントリなど、収集しているレコードをセットとして扱うことができると仮定すると、私がお勧めする手法はタイムボックス化です。タイムボックス化する場合、期間に基づいてデータを集約します。たとえば、一連のサーバー(この例ではserverという名前)のログを収集していると仮定すると、サーバーIDと日時識別子(測定期間の開始など)に基づいたキーを持つレコードを作成できます。レコードを識別できるようにするために、完全なタイムスタンプは必要ありません。2013/03/07の14:15から14:20までの期間をカバーするserver3のログエントリを保持するレコードには、「server3_20130307_1415」という名前を付けることができます。したがって、次の5分間は、「server3_20130307_1420」という名前になります。一定期間のデータがない場合、レコードは作成されません。
これにより、特定の期間をカバーするレコードのキーを自動的に知ることができ、キーアクセスに厳密に基づいてレコードを取得できます。これにより、スケーリングとパフォーマンスが非常に向上します。通常、Riakのオブジェクトのサイズを1〜2 MB未満に保ちたいため、生成するデータの量に応じて、1つのレコードがカバーする期間を調整する必要があります。この推奨サイズを下回るために、各期間に大量のデータがある場合は、アプリケーションレベルでデータを圧縮することも検討する価値があります。
潜在的に多数のレコードを取得せずに、より大きなデータチャンクにアクセスできるようにしたい場合は、レコードを定期的に集約できます。たとえば、1時間をカバーするすべてのレコードを読み取り、14:00〜15:00の全期間をカバーする「server3_20130307_14」という名前の新しいレコードに集約データを書き込むことができます。キーをご存知のように、これは簡単で、バッチジョブとして簡単に実装できます。
このアプローチを採用する場合、前述のように、同時書き込みの可能性を考慮する必要があります。これを行う最良の方法は、兄弟を許可することです(バケットのプロパティを使用して、バケットの「allow_mult」をtrueに設定し、「last_write_wins」をfalseに設定します[1])。これにより、同時更新の場合にRiakはレコードのすべてのバージョンを保持し、代わりに、兄弟を含むレコードを読み取るときに、アプリケーション層で作成された兄弟を解決する必要があります。これにより少し複雑になりますが、データが失われることはありません。
この場合のログエントリはセットとして扱うことができると想定しているため、セットユニオンを介してすべての兄弟のセットをマージし、兄弟を解決するためにオブジェクトを(正しいベクタークロックで)更新できます。
[1] http://docs.basho.com/riak/latest/references/apis/http/HTTP-Set-Bucket-Properties/