python实现redis rdb迁移

前言

找了一圈redis迁移工具,包括:redis-port、redis-shake、redis-dump等等,涉及到各种语言和环境,折腾了半天没有成功。。最后还是自己写吧。

利用https://github.com/sripathikrishnan/redis-rdb-tools这个强大的python库简单写一个适用于单机的redis迁移脚本。

python脚本

import datetime
from typing import Dict, Optional, List

import redis
from loguru import logger
from rdbtools import RdbParser, RdbCallback
from rdbtools.encodehelpers import bytes_to_unicode, STRING_ESCAPE_UTF8


class RedisMigrator:
    """redis迁移"""
    def __init__(self, rdb_file: str, redis_config: Dict, source_dbs: Optional[List[int]] = None):
        self.rdb_file = rdb_file
        self.redis_config = redis_config
        self.source_dbs = source_dbs
        self.redis_client = self.init_redis()

    def init_redis(self):
        """初始化redis客户端"""
        redis_pool = redis.ConnectionPool(**self.redis_config)
        redis_client = redis.Redis(connection_pool=redis_pool)
        return redis_client

    def migrate(self):
        """
        迁移
        filters参数支持多种条件过滤
        {"dbs" : [0, 1], "keys" : "foo.*", "types" : ["hash", "set", "sortedset", "list", "string"]}
        """
        callback = MyCallback(redis_client=self.redis_client)
        filters = None
        if self.source_dbs:
            filters = {"dbs": self.source_dbs}
        parser = RdbParser(callback, filters=filters)
        parser.parse(self.rdb_file)


class MyCallback(RdbCallback):
    """回调"""
    def __init__(self, redis_client):
        super(MyCallback, self).__init__(string_escape=STRING_ESCAPE_UTF8)
        self.redis_client = redis_client

    def encode_key(self, key):
        return bytes_to_unicode(key, self._escape, skip_printable=True)

    def encode_value(self, val):
        return bytes_to_unicode(val, self._escape)

    def set(self, key, value, expiry, info):
        logger.info("set")
        key = self.encode_key(key)
        value = self.encode_value(value)
        if expiry:
            now = datetime.datetime.now()
            # 计算距离当前时间的秒数
            expiry = int((expiry - now).total_seconds())
        logger.info("{} {} {}".format(key, value, expiry))

        if not expiry:
            self.redis_client.set(key, value)
        elif expiry > 0:
            self.redis_client.setex(key, expiry, value)

    def hset(self, key, field, value):
        logger.info("hset")
        key = self.encode_key(key)
        value = self.encode_value(value)
        field = self.encode_value(field)
        logger.info("{} {}".format(key, value))

        self.redis_client.hset(key, field, value)

    def rpush(self, key, value):
        logger.info("rpush")
        key = self.encode_key(key)
        value = self.encode_value(value)
        logger.info("{} {}".format(key, value))

        self.redis_client.rpush(key, value)

    def zadd(self, key, score, member):
        logger.info("zadd")
        key = self.encode_key(key)
        score = self.encode_value(score)
        member = self.encode_value(member)
        logger.info("{} {} {}".format(key, score, member))

        self.redis_client.zadd(key, {member: score})

    def sadd(self, key, member):
        logger.info("sadd")
        key = self.encode_key(key)
        value = self.encode_value(member)
        logger.info("{} {}".format(key, value))

        self.redis_client.sadd(key, value)

    def start_database(self, db_number):
        logger.info("Starting database {}".format(db_number))

    def end_database(self, db_number):
        logger.info("End database {}".format(db_number))

if __name__ == '__main__':
    # 目标redis配置
    target_redis_config = {
        "host": "127.0.0.1",
        "port": 6379,
        "db": 13,
        "password": "123456"
    }
    # 要迁移的rdb文件
    _rdb_file = r'./dump.rdb'
    # 要迁移的数据库列表,不传代表全部0-15
    _source_dbs = [13]

    migrator = RedisMigrator(rdb_file=_rdb_file, redis_config=target_redis_config, source_dbs=_source_dbs)
    migrator.migrate()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python可以使用redis-py库来实现Redis数据迁移。以下是一个简单的示例代码,演示如何从一个Redis实例复制数据到另一个Redis实例。 首先,确保你已经安装了redis-py库。可以使用以下命令来安装: ``` pip install redis ``` 然后,使用以下代码实现数据迁移: ```python import redis def migrate_data(source_host, source_port, source_password, destination_host, destination_port, destination_password): # 连接源Redis source_redis = redis.Redis(host=source_host, port=source_port, password=source_password) # 连接目标Redis destination_redis = redis.Redis(host=destination_host, port=destination_port, password=destination_password) # 获取所有键 keys = source_redis.keys() # 迁移数据 for key in keys: key_type = source_redis.type(key) if key_type == b'string': value = source_redis.get(key) destination_redis.set(key, value) elif key_type == b'list': values = source_redis.lrange(key, 0, -1) for value in values: destination_redis.rpush(key, value) elif key_type == b'set': values = source_redis.smembers(key) for value in values: destination_redis.sadd(key, value) elif key_type == b'zset': values = source_redis.zrange(key, 0, -1, withscores=True) for value, score in values: destination_redis.zadd(key, {value: score}) elif key_type == b'hash': items = source_redis.hgetall(key) for field, value in items.items(): destination_redis.hset(key, field, value) print("数据迁移完成!") # 示例用法 migrate_data('source_host', 6379, 'source_password', 'destination_host', 6379, 'destination_password') ``` 请确保替换示例中的源Redis和目标Redis的主机、端口和密码信息。这段代码会将源Redis中的所有键和对应的值迁移到目标Redis中。 请注意,该示例代码只迁移了常见的Redis数据类型(字符串、列表、集合、有序集合和哈希)。如果你使用了其他数据类型,你需要相应地进行修改。 希望对你有所帮助!如有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值