タイトルの通り、redis-pyというPythonライブラリを使ってRedis Clusterから全件取得する記事です。
方針
- 全マスターノードで
SCAN
- 全スロットで
CLUSTER COUNTKEYSINSLOT
でKEY数を取得しCLUSTER GETKEYSINSLOT
でKEYを取得
の2種類の方針があると思っています。
今回は後者のやり方になります。
環境
- Python 3.7.10
- redis-py 4.3.4
- hiredis 2.0.0
$ python --version
Python 3.7.10
$ pip list | grep redis
hiredis 2.0.0
redis 4.3.4
全件取得してみる
Redis Clusterに接続
from redis.cluster import RedisCluster, ClusterNode
nodes = [
{"host": "host_name_1", "port": 6379},
{"host": "host_name_2", "port": 6379},
{"host": "host_name_3", "port": 6379}
]
cluster_nodes = [ClusterNode(**node) for node in nodes]
redis_cluster = RedisCluster(startup_nodes=cluster_nodes, readonly_mode=True)
スロットの全キーを取得
slot_id = 0
num_keys = redis_cluster.cluster_countkeysinslot(slot_id)
keys = redis_cluster.cluster_get_keys_in_slot(slot_id, num_keys)
これで特定のスロットslot_id
のKEY数を取得できます。
スロットはデフォルト設定であれば0〜16383まであるのでforとかでやれば全件取得できます。
対話モードでやってみた結果が下です。
>>> slot_id = 1392
>>> num_keys = redis_cluster.cluster_countkeysinslot(slot_id)
>>> num_keys
1
>>> keys = redis_cluster.cluster_get_keys_in_slot(slot_id, num_keys)
>>> keys
['key_name']
>>>
注意点
SCAN
系で取得したときとCLUSTER GETKEYSINSLOT
では型が違います。(1敗)
SCAN
だとbytes
、CLUSTER GETKEYSINSLOT
だとstr
でKEYが返ってきます。
>>> type(redis_cluster.cluster_get_keys_in_slot(slot_id, num_keys)[0])
<class 'str'>
>>>
>>> type(next(redis_cluster.scan_iter(match='*')))
<class 'bytes'>
>>>
コード全文
やってきたことをまとめるとこんな感じです。
from redis.cluster import RedisCluster, ClusterNode
nodes = [
{"host": "host_name_1", "port": 6379},
{"host": "host_name_2", "port": 6379},
{"host": "host_name_3", "port": 6379}
]
cluster_nodes = [ClusterNode(**node) for node in nodes]
redis_cluster = RedisCluster(startup_nodes=cluster_nodes, readonly_mode=True)
for slot_id in range(16384):
num_keys = redis_cluster.cluster_countkeysinslot(slot_id)
keys = redis_cluster.cluster_get_keys_in_slot(slot_id, num_keys)
# keysを使った何かの処理