7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MicroAd (マイクロアド) Advent Calendar 2022

Day 9

redis-pyでRedis Clusterから全件取得する

Last updated at Posted at 2022-12-08

タイトルの通り、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だとbytesCLUSTER 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を使った何かの処理
7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?