線形の複雑さを回避するためにどのような巧妙なスキームを導入しても、KEYSの使用はRedisでは実際にはスケーラブルではないと思います。
パーティショニングはこのスキームの1つであり、フラットテーブルでのテーブルスキャンのコストを削減するために、従来のRDBMSで一般的に使用されています。あなたのアイデアは、実際にはこの概念をRedisに適応させたものです。
ただし、この機能を提供する従来のRDBMS(Oracle、MySQLなど)とは重要な違いがあります。Redisはシングルスレッドのイベントループです。したがって、スキャンを他のアクティビティ(たとえば、他のクライアント接続の提供など)と同時に実行することはできません。Redisがデータをスキャンすると、すべての接続でブロックされます。
良好なパフォーマンスを得るには、膨大な数のパーティション(つまりデータベース)をセットアップする必要があります。キーのグローバル数の1/1000または1/1000のようなもの。そして、これがスケーラブルではない理由です。Redisは、このような数のデータベースを処理するようには設計されていません。すべてのデータベースで反復する内部メカニズムで問題が発生する可能性があります。ソースコードから抽出したリストは次のとおりです。
- 自動再ハッシュ
- アイテムの有効期限管理
- データベースステータスログ(5秒ごと)
- INFOコマンド
- maxmemory管理
データベースの数を制限する必要があり、スケーラビリティも制限されます。1000個のデータベースを設定すると、たとえば100万個のアイテムでは正常に機能し、1,000万個のアイテムでは遅くなり、1億個のアイテムでは使用できなくなります。
それでもこの機能を実装するために線形スキャンに固執したい場合は、同時スキャンをサポートする他のストア(MySQL、MongoDBなど)の方が適しています。他の店舗では、アイテムの有効期限を効率的に実装することが重要です。
本当にRedisを使用する必要がある場合は、複数のデータベースに依存せずにデータを簡単にセグメント化できます。たとえば、ここで説明した方法を使用できます。この戦略では、キーのリストが段階的に取得され、検索は実際にはクライアント側で行われます。主な利点は、Redisがブロックしないように、多数のパーティションを持つことができることです。
現在、AFAIKのストレージエンジンは、任意の正規表現を使用してデータを効率的に検索する機能を提供していません(つまり、線形スキャンを回避します)。ただし、この機能は、通常n-gramインデックスを使用する一部の検索エンジンによって提供されます。
これはラスコックスからのそれについての良い記事です:http ://swtch.com/~rsc/regexp/regexp4.html
このインデックス作成メカニズムは、おそらくRedisに適合させることができます(Redisを使用してキーのトリグラムインデックスを保存します)が、これは多くのコードを記述します。
正規表現をプレフィックス検索に制限することも想像できます。たとえば、U:SMITH:(。*)は、実際には接頭辞U:SMITH:を使用した検索です。
その場合、zsetを使用してキーにインデックスを付け、関心のあるキーの範囲が取得されたら、クライアント側で線形検索を実行できます。zset内のアイテムのスコアは、クライアント側のキーから計算されるため、スコアの順序はキーの辞書式順序に対応します。
このようなzsetを使用すると、zscoreコマンドとzrangeコマンドを組み合わせて、チャンクごとにスキャンする必要のあるキーの範囲を取得できます。その結果、スキャンするキーの数が(プレフィックスによって)制限され、検索がクライアント側で行われ、Redisの同時実行モデルに対応します。欠点は、複雑さ(特にアイテムの有効期限を処理するため)とネットワーク帯域幅の消費です。