2016-03-16 18 views
7

キューから複数のレコードを処理する必要があります。しかし、いくつかの外部の問題のために、アイテムは散発的に複数回現れる可能性があります。 アイテムを1回だけ処理する必要がありますRedis PFADDがセット内に存在するクエリを確認する

私が使用する予定だったのは、すべてのレコードを(md5sumとして)redisに変換し、成功したかどうかを確認することです。それが増分を示さないならば、そのレコードは重複したものであり、他のものはそのレコードを処理する。

これを行うには良い方法はありPFADD

を使用しながら、これは非常に簡単そうですが、私はあまりにも多くの偽陽性を取得していますか?まさにワンス
  • 少なくとも一度
  • 処理何かがしかし、これは便利だろう、最高1回

    • :分散システムで一般的に

    答えて

    2

    あなたは処理項目のいずれかの間で選択する必要があり一般的に不可能です。

    あなたの特定のユースケースに対して許容可能な回避策があると言われています。すでに処理されたアイテムを保存することをお勧めします。

    PFADDはHyperLogLogを使用していますが、これは高速であり、アイテムの数についてはscales but is approximateを使用していることに注意してください。この場合、私はこれがあなたの望むものではないと思います。 しかし、エラーの可能性が低いとうまくいれば、ここで最も適切なデータ構造はBloom filter(説明はhere for Redis)であり、非常にメモリ効率のよい方法で実装できます。

    シンプルで効率的なrecommendedソリューションは、ブール値のような値( "0"、 "1"または "true"、 "false")を格納する単純なレディスキー(たとえばハッシュ) HSETまたはSET with the NXオプション命令でインスタンス化します。また、namespaceの下に置くこともできます。キーを期限切れにできるという利点もあります。

    それはあなたが複数のノードに拡張したい場合は、必ずしもRedis clusterとうまく動作しない(むしろないSETコマンドが、SINTERSUNIONコマンド)のセットを、使用することを避けるだろう。 SISMEMBERはまだ問題ありません(しかし、生存時間のようなハッシュからいくつかの機能が欠けています)。

    ハッシュを使用する場合は、チャンスがcollisions than md5であるハッシュ関数を選択することをお勧めします(衝突は、2つの異なるオブジェクトが同じハッシュで終わることを意味します)。

    ハッシュの別の方法として、キューに入れるときにすべてのアイテムにuuidを割り当てることができます(時間情報が必要な場合はsquuid)。

    +1

    私はHSETが良い解決策であると考えています.NXオプションの通常のSETも良いオプションです。キューの中のアイテムがピリオドの後に繰り返されない場合は、有効期限を追加できます。 – PerroVerd

    +0

    @PerroVerd正確にそれについては気が散った)。基本的なRedis操作は通常十分です(唯一のことはデータベース全体のスキャンを避け、キー間の関係を単純に保つことです)。 – nha

    +0

    @nha Setの代わりに "ブーリアン"ハッシュを使うのは、厄介なだけでなく、fasle/0のエントリも保存することをお勧めしているので、無駄ではありません(Redis 'Setsは内部的にハッシュで実装されています。 ** ** **メンバーシップテストの自然な選択です。あなたの最後の編集で解答が減るだけです。ハッシュコリジョンに関する部分は実際には非常に正確ですが、不正確になってしまいます。最後に、セットは完全にクラスターセーフであり、データ構造に関係なくサポートされないマルチキークロススロット操作です。 –

    4

    RedisのHyperLogLogは、確率論的データ構造であるため、0.81%の標準誤差を示します。あなたは、複数のHLLを使用して、それぞれがあなたのレコード上の異なるハッシュ関数の値を数えることによって、偽陽性の可能性を減らすことができます(ただし、決して排除することはできません)。

    また、単一のHLLを使用している場合は、実際にはレコードをハッシュする必要はありません。ちょうどPFADDです。

    また、すべての識別子/ハッシュ/レコードを保持するためにRedis Setを使用し、SISMEMBERで100%の正確なメンバーシップテストを実施してください。このアプローチでは、処理された各要素を格納するときに、より多くの(RAM)リソースが必要ですが、キューが本当に巨大でない限り、適度なRedisインスタンスにとっては問題ではありません。メモリ消費量を抑えるには、日付に応じてセット間を切り替え、セットキーの有効期限を設定します(もう1つの方法は、ソートセットを1つ使用してタイムスタンプをスコアに保持して古いアイテムを手動で削除する方法です)。

    +0

    SISMEMBERはすべての "メンバー"をメモリに保存しますが、1日に1000万md5のレコードを保存でき、1週間保存する必要があります – Ram

    +0

    @Ram Redisは基本的にメモリ内のデータベースです。 Redisクラスタではうまくいきません(多くのデータがある場合は、いつか使用したいかもしれません)。全体として、単純なハッシュ(set、hset)をお勧めします。 – nha

    +0

    @Ram - メンバーをセットに追加するには 'SADD'を使う必要があります。' SISMEMBER'はメンバシップテストだけです。そして、はい、すべての値はRAMに保存されます - 7000万md5の値は約2GBの生データでなければなりません。 –

    関連する問題