redis跨实例迁移key(Python 版)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 测试区Codis集群之前废了,今天重新搭起来之后,测试程序发现很多key的数据都没了。如果整个库迁移过来没有必要。 只需要把特定的几个key迁移过来即可。

测试区Codis集群之前废了,今天重新搭起来之后,测试程序发现很多key的数据都没了。

如果整个库迁移过来没有必要。 只需要把特定的几个key迁移过来即可。

hash、list string 类型key 迁移


以下为Python版本实现

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :redis_key_mig 
@File :redisMigrate.py
@Author :ninesun
@Date :2021/11/29 14:22
@Desc: 
'''
import sys
import redis
# 迁移hash
def moveHash(cursor):
    cursor, data = r.hscan(key, cursor)
    for eachKey in data:
        rNew.hset(key, eachKey, data[eachKey])
    print(key, "---处理了---", len(data), '个')
    if cursor != 0:
        print(cursor, "批处理")
        moveHash(cursor)
    else:
        print(cursor, "处理完成了")
# 迁移list
def moveList():
    length = r.llen(key)
    if length == 0:
        print(key, "---list迁移结束---剩余长度", length)
    else:
        # 每次迁移一千个
        start = length - 1000;
        if start < 0:
            start = 0
        data = r.lrange(key, start, -1)
        pl = r.pipeline();
        for eachI in data:
            setAdd = r.sadd("ordernokey_move", eachI);
            if setAdd == 1:
                pl.rpush("aaaaaaa", eachI)
            else:
                print("迁移的key的值重复了", eachI)
        pl.execute()
        if start == 0:
            # 清空
            r.ltrim(key, 1, 0)
        r.ltrim(key, 0, start - 1)
        moveList()
############################
if __name__ == '__main__':
    # key = sys.argv[1]
    # opeID 迁移
    # key = 'ope_array'
    # key = 'ope_cf'
    # key = 'ope_oc'
    #
    # key = 'prod_array'
    # key = 'prod_cf'
    # key = 'prod_oc'
    key = 'basicOwn'
    print('输入的key是:' + key)
    # ip = '47.254.149.109'
    # password = 'Kikuu2018'
    ip1 = '10.50...'
    ip2 = '10.50...'
    # 连接redis
    r = redis.Redis(host=ip1,  port=19000, db=0,
                    decode_responses=True)
    # 连接redis  带接收的库
    rNew = redis.Redis(host=ip2,  port=19000, db=0,
                       decode_responses=True)
    keyType = r.type(key)
    if keyType == 'string':
        rNew.set(key, r.get(key))
        print("key=" + key + "迁移到新库")
    if keyType == 'hash':
        cursor = r.hlen(key)
        print(" key值长度是 + ", cursor)
        moveHash(0)
    if keyType == 'list':
        moveList()

批量迁移某个soted set 类型的key


由于业务需要,需要迁移集群中的几个key,数量不大,不过key需要自己拼接。

其中一个key的类型是string

另外一个key的类型是zset。

b06697ad9fd84216ab80972722d4d5dc.pngpy代码如下

# 迁移soted set
def moveZset(keyStr):
    key = keyStr.lstrip()
    length = r.zcard(key)
    if length == 0:
        get_logger().info("%s ---list迁移结束---剩余长度: %s", key, length)
        return
        # print(key, "---list迁移结束---剩余长度", length)
    else:
        # 每次迁移一千个
        start = length - 1000;
        if start < 0:
            start = 0
        data = r.zrange(key, 0, -1, withscores='true')
        pl = r.pipeline();
        count = 1
        for eachI in data:
            length = length - 1
            score = str(eachI[1])
            value = eachI[0]
            # ch=true 仅仅是update 了score 才会,原封不动的zadd直接返回0
            zaddRet = rNew.zadd(key, {value: score}, ch='true');
            scoreRet = r.zcard(key)
            scoreRetNew = rNew.zcard(key)
            # rNew.delete(key)
            # if scoreRet != scoreRetNew:
            #     get_logger().error("数据不一致,key: %s,scoreRet: %s, scoreRetNew: %s",key,scoreRet,scoreRetNew)
            if zaddRet == 1:
                pl.zadd(key, {value: score})
                count = count + 1;
            else:
                count = count + 1;
                # get_logger().info("迁移的key的值重复了,第: %s个key: %s,score: %s",count,key,scoreRet)
                # print("迁移的key的值重复了,key: ", key)
        get_logger().info("---剩余长度: %s", length);

normally the return value of ZADD only counts the number of new elements added.  zadd不会返回已存在的元素


更新score也意味着在有序集合中的位置变化。

zadd 中的score范围是多少呢?


between -9007199254740992 and 9007199254740992

踩的坑


错误的姿势

正确的姿势

zadd:db.zadd(REDIS_KEY, {member:score})

竟让是member在前score在后。和redis的操作刚好相反.

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
存储 NoSQL 数据库连接
在Python程序中实现LevelDB的海量key的分批次扫描
通过本文的步骤,您可以在Python程序中实现对LevelDB海量key的分批次扫描。这样不仅能够有效地管理大规模数据,还可以避免一次性加载过多数据到内存中,提高程序的性能和稳定性。希望这篇指南能为您的开发工作提供实用的帮助。
74 28
|
1月前
|
NoSQL API Redis
在C程序中实现类似Redis的SCAN机制的LevelDB大规模key分批扫描
通过上述步骤,可以在C程序中实现类似Redis的SCAN机制的LevelDB大规模key分批扫描。利用LevelDB的迭代器,可以高效地遍历和处理数据库中的大量键值对。该实现方法不仅简单易懂,还具有良好的性能和扩展性,希望能为您的开发工作提供实用的指导和帮助。
43 7
|
3月前
|
消息中间件 缓存 NoSQL
Redis 高并发竞争 key ,如何解决这个难点?
本文主要探讨 Redis 在高并发场景下的并发竞争 Key 问题,以及较为常用的两种解决方案(分布式锁+时间戳、利用消息队列)。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
Redis 高并发竞争 key ,如何解决这个难点?
|
3月前
|
存储 监控 NoSQL
Redis大Key问题如何排查?如何解决?
Redis大Key问题如何排查?如何解决?
174 0
Redis大Key问题如何排查?如何解决?
|
3月前
|
存储 NoSQL 算法
面试官:Redis 大 key 多 key,你要怎么拆分?
本文介绍了在Redis中处理大key和多key的几种策略,包括将大value拆分成多个key-value对、对包含大量元素的数据结构进行分桶处理、通过Hash结构减少key数量,以及如何合理拆分大Bitmap或布隆过滤器以提高效率和减少内存占用。这些方法有助于优化Redis性能,特别是在数据量庞大的场景下。
面试官:Redis 大 key 多 key,你要怎么拆分?
|
4月前
|
NoSQL Unix Redis
Redis 键(key)
10月更文挑战第15天
62 1
|
4月前
|
缓存 监控 负载均衡
如何解决Redis热点Key问题?技术干货分享
【10月更文挑战第2天】在Redis的使用过程中,热点Key问题是一个常见的性能瓶颈。热点Key指的是那些被频繁访问的Key,它们可能导致Redis服务器的负载不均衡,进而影响整体性能。本文将深入探讨热点Key问题的成因、影响以及多种解决方案,帮助读者在实际工作中有效应对这一挑战。
192 3
|
4月前
|
NoSQL Redis
redis 的 key 过期策略是怎么实现的(经典面试题)超级通俗易懂的解释!
本文解释了Redis实现key过期策略的方式,包括定期删除和惰性删除两种机制,并提到了Redis的内存淘汰策略作为补充,以确保过期的key能够被及时删除。
83 1
|
5月前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
74 1
|
5月前
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
118 3