単一の MGET では、このような数の値を取得することはできません。このコマンドは、そのようなワークロードを維持するようには設計されていません。非常に大きな Redis コマンドを生成するのは間違った考えです:
サーバー側では、すべてのコマンドが入力バッファーに収まる必要があります。コマンドのすべての結果は、出力バッファーに収まる必要があります。入力バッファは 1 GB に制限されています。出力バッファには、クライアントの性質に応じてソフト制限とハード制限があります。しかし、バッファをこれらの制限に近づけると、実際に問題が発生します。制限に達すると、Redis は単純に接続を閉じます。
クライアント側にも、おそらく同様のバッファとハードコーディングされた制限があります。
Redis はシングルスレッドのイベント ループです。コマンドの実行はシリアル化されます。そのため、コマンドが非常に大きいと、他のすべてのクライアントに対して Redis が応答しなくなります。
大量のデータを取得する必要がある場合は、いくつかの GET または MGET コマンドをパイプライン処理する必要があります。たとえば、次のコードを使用すると、ラウンドトリップ数とサーバー側の CPU 消費を最小限に抑えながら、任意の数のアイテムを取得できます。
import redis
N_PIPE = 50 # number of MGET commands per pipeline execution
N_MGET = 20 # number of keys per MGET command
# Return a dictionary from the input array containing the keys
def massive_get( r, array ):
res = {}
pipe = r.pipeline(transaction=False)
i = 0
while i < len(array):
keys = []
for n in range(0,N_PIPE):
k = array[i:i+N_MGET]
keys.append( k )
pipe.mget( k )
i += N_MGET
if i>=len(array):
break
for k,v in zip( keys, pipe.execute() ):
res.update( dict(zip(k,v)) )
return res
# Example: retrieve all keys from 0 to 1022:
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
array = range(0,1023)
print massive_get(r,array)