2016-11-28 10 views
0

私はRedisを初めて利用しました。Redisでサポートされているさまざまなデータ構造があり、要件に基づいて選択できます。私の必要条件は、リスト(key-list)に文字列を1つずつ挿入し、すべてを一度に取得(および削除)することです。また、これを頻繁にやりたいので、最適な方法を見つけようとしています。どのデータ構造/方法がこれに適していますか?前もってありがとうございますRedis - 文字列を1つずつ挿入して一度に削除するデータ構造

P .:私はキーを取り除きたいとは思いません。取り出すときに、リストを取得して空にするだけです。

答えて

1

Listのように聞こえます。リストにLPUSHまたはRPUSHのいずれかを追加し、LRANGEDELのキーですべてを取得します。

P.S.リストを格納しているようなRedisのキーは、空にすることはできません。一度リストのメンバーをすべて削除すると、キー自体は存在しなくなります。そのため、キーを空にする代わりに削除できます。

OPのコメントへの回答で更新されました:実際には、無料のランチはありません。また、方法に関係なく、O(N)の読み取りと削除が必要です。 1回の反復を行うことが好ましい場合がある。ネットワーク通信を減らすことができますが、これはその1つではありません。

いずれにしても、両方の機能の組み合わせに最も近いのは、Luaです。

$ cat popall.lua 
local r={} 
local e=redis.call('LPOP', KEYS[1]) 
while e do 
    r[#r+1]=e 
    e=redis.call('LPOP', KEYS[1]) 
end 
return r 
$ redis-cli LPUSH list 1 2 3 4 5 6 7 8 9 
(integer) 9 
$ redis-cli --eval popall.lua list 
1) "9" 
2) "8" 
3) "7" 
4) "6" 
5) "5" 
6) "4" 
7) "3" 
8) "2" 
9) "1" 
$ redis-cli EXISTS list 
(integer) 0 
+0

「LRANGE」と「DEL」はどちらもO(N)操作です。リストが空になるまで 'POP 'を実行すると、N * O(1)の操作が行われます。両方を組み合わせる方法はありますか? (O)N( – RaR

1

あなたはおそらくこれを達成するために、単純なlistを使用したい:これは必ずしも良く、その後LRANGE & DELが行われないこと、しかし、注意してください。あなたがセットを使用したいかもしれない1つの理由がありますが、私は後でそれに着きます。

LPUSHを使用して、リストに項目を追加します。この操作を初めて実行するには、リストが存在する必要はありません。これはO(1)(一定の時間)操作です。できるだけ速いです。すべてのアイテムを取得するにはLRANGE 0 -1を使用します。これにより、(類似のセット操作)と同じO(N)になります。最後にDELを使用します。これは再びO(N)になり、セットまたはリストを使用する場合と同じパフォーマンスを持ちます。

前述のとおり、リストを使用して1つのセットを使用する状況があります。つまり、重複を防ぎたいが、順序は気にしない。この場合、SADDのメンバーを追加し、SMEMBERSのメンバーをすべて取得します。セットを使用すると、注文ユニークの取引を除いて、リストを使用する場合と全く同じのパフォーマンスが同じになります。重複を防ぎたいだけでなく、順序を気にしたい場合は、ソートされたセットを使用することになります。あなたはスコアを記録する必要があるので、操作は少し複雑になりますが、それはまだかなり簡単です。ソートされたセットを使用することで、パフォーマンスが大幅に低下します。これは、Redisがのように非常にのように心配するものではありません。

+1

)まず、このような素晴らしい説明に感謝します。リストやセットを使って提案したやり方では、少なくとも2つのO(N)操作が必要です。単一のO(N)操作でそれを行う方法はありません。 '(L/R)POP'は1つを取り除き、それを返します。これはO(1)の操作です。そのように、すべてをポップしてO(N)を取っている間にすべてを返す方法はありません。 – RaR

+1

@RaR心配はいりません。それは大きなポイントです。範囲を指定してから削除するのではなく、あなたが言ったように繰り返しポップすることで最高のパフォーマンスを達成できるようです。私は、Redisのデータ構造のいずれにも「バルクポップ」はないと思います。リストのサイズが(おそらく何百万というように)大きくなり、この操作が頻繁に起こる場合、手動ポップ方法を行う価値があるかもしれません。それ以外の場合は、簡単にするためにrange/deleteメソッドを使用することをおすすめします。 –

1

セパレータとして使用できる文字がある場合は、APPENDを使用することもできます。それはO(1)です。その後、文字列全体を取得し、GETSETを使用してリセットすることができます。欠点は、それがあなたが必要とするものなら、あなた自身のコードで再びリストに戻さなければならないことです。

関連する問題