问题背景

公司原先的预发布环境和测试环境共用同一个redis实例,各自的数据存储在不同的数据库(db)中。项目在使用redis的Pub/Sub功能时遇到了一些麻烦,主要问题是redis的发布订阅系统不会区分不同的数据库:即使消息是在db10发布的,db1上的订阅者也能接收到这些消息,这一行为与redis官方文档所描述的一致

Pub/Sub has no relation to the key space. It was made to not interfere with it on any level, including database numbers.

Publishing on db 10, will be heard by a subscriber on db 1.

https://redis.io/docs/interact/pubsub/

之后在测试环境单独部署了一个redis,写了一个python脚本迁移数据

Python迁移单个redis的db数据

  • 新建一个名字为migrate_redis.py的文件

import redis

def migrate_key(src_redis, target_redis, k):
    data_type = src_redis.type(k)

    if data_type == 'string':
        target_redis.set(k, src_redis.get(k))

    elif data_type == 'hash':
        keys = src_redis.hkeys(k)
        for key in keys:
            target_redis.hset(k, key, src_redis.hget(k, key))

    elif data_type == 'set':
        target_redis.sadd(k, *src_redis.smembers(k))

    elif data_type == 'list':
        target_redis.lpush(k, *src_redis.lrange(k, 0, -1))

    elif data_type == 'zset':
        values = src_redis.zrange(k, 0, -1, withscores=True)
        for value, score in values:
            target_redis.zadd(k, {value: score})

    else:
        print(f'Unknown type for key {k}: {data_type}')
        return False

    return True

def main():
    src_redis = redis.Redis(host='172.17.20.1', port=6379, db=11, password="", decode_responses=True)
    target_redis = redis.Redis(host='171.17.20.5', port=6379, db=12, password="", decode_responses=True)

    num = 0
    errornum = 0

    for k in src_redis.keys():
        if migrate_key(src_redis, target_redis, k):
            num += 1
        else:
            errornum += 1

    print('Total keys migrated:', num)
    print('Error total:', errornum)

if __name__ == "__main__":
    main()
  • 安装redis包

 pip install redis
  • 运行migrate_redis.py,我当前的环境是python3

python3 migrate_redis.py

文章作者: 陆壹
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 陆壹笔记
Python 运维 Redis shell linux
喜欢就支持一下吧