如何用建木CI导入导出Redis数据

上次介绍了如何使用建木CI导入导出MySQL数据后,就有小伙伴询问到:如何用建木CI迁移Redis数据呢?

这还不简单吗?建木官方都已经提供好节点了,于是马不停蹄的写下了这篇文章!

在这里插入图片描述

Redis是现在最受欢迎的NoSQL数据库之一,是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,并提供多种语言的API。

Redis数据导出

在建木CI中,可以通过Redis数据导出节点 来完成数据导出,节点底层使用的是redis-dump命令

  • 查看节点文档

在这里插入图片描述

节点文档显示,输入参数中只有host是必填参数,另外四个参数是有默认值的,可以根据需求填写

  • 定义管道DSL

定义DSL时,将管道示例复制过来,修改一下参数值就可以了

在这里插入图片描述

name: Redis数据导出
pipeline:
  redis_export:
    type: redis_export:1.0.1
    param:
      host: xxx.xxx.xxx.xxx
      port: 6379 # 默认为6379,可以省略此参数
      database: 1 # 导出数据库1
      password: ((redis.password)) # 没有密码可以忽略此参数
      key: name # 模糊查询的key值,相当于命令:keys *name*

项目创建成功后,再点击触发就可以导出数据啦,输出参数redis_path为导出的Redis数据文件路径

一般情况下,导出导入节点是一起使用的,下面看一下如何用建木CI导入Redis数据吧!

Redis数据导入

在建木CI中,可以通过redis数据导入节点 来完成数据导入,节点底层使用的是redis-dump命令

  • 查看节点文档

在这里插入图片描述

可以看到,导入节点的输入参数和导出节点的输入参数是差不多的,多出来的redis_path参数则刚好是导出节点的输出参数,正好可以将导出导入节点连在一起使用😃

  • 定义管道DSL

和导出节点一样,复制DSL示例修改一下参数值就可以了

name: Redis数据同步
pipeline:
  redis_export:
    alias: Redis数据导出
    type: redis_export:1.0.1
    param:
      host: xxx.xxx.xxx.xxx
      port: 6379 # 默认为6379,可以省略此参数
      database: 1 # 导出数据库1
      password: ((redis.password)) # 没有密码可以忽略此参数
      key: name # 模糊查询的key值,相当于命令:keys *name*
  redis_import:
    alias: Redis数据导入
    type: redis_import:1.0.2
    param:
      host: xxx.xxx.xxx.xxx
      database: 2 # 导入到数据库2中
      password: ((redis.password))
      redis_path: ${redis_export.redis_path}

保存项目DSL,点击触发,流程执行完毕就成功同步Redis数据了!

每次需要同步的时候,只需再点击触发就行了,简直不能太方便!

在这里插入图片描述

本文为建木博主「早春的树」的原创投稿文章,转载请联系授权。

项⽬官⽹
项⽬托管
项⽬文档
在线体验

<think> 我们之前讨论了Redis中检查TTL值为-2的含义,现在用户的问题是:如何将Redis指定键值数据导出到新的Redis数据库中。 根据引用[1]中的流程图,我们可以参考其基本步骤,但需要调整:原流程是导出到Excel,现在需要导出到另一个Redis。 引用[2]提到了BigKey的问题,在导出过程中需要注意避免大键导致的性能问题。 引用[3]展示了通过JMeter脚本获取Redis键值,但这不是我们需要的。 解决方案思路: 1. 从源Redis获取指定键的数据(可能通过SCAN命令遍历指定模式的键,或者直接指定键名列表) 2. 将数据读取出来(注意大键的处理,分批读取等) 3. 将数据写入目标Redis 具体方法: 方法1:使用redis-dump和redis-restore工具(需要安装) - 安装:gem install redis-dump - 导出指定键:redis-dump -u 源Redis地址 -p 端口 -a 密码 -d 数据库编号 -k "键名模式" > dump.json - 导入:cat dump.json | redis-load -u 目标Redis地址 -p 端口 -a 密码 方法2:使用redis-cli的--pipe选项(适合迁移大量数据- 编写脚本生成redis协议格式的数据(SET命令等) - 示例步骤: a. 从源Redis获取键列表(使用SCAN避免阻塞) b. 对每个键,使用DUMP命令获取序列化值,同时获取TTL c. 生成目标Redis的RESTORE命令(使用获取到的序列化值和TTL) d. 将RESTORE命令通过管道发送到目标Redis 方法3:使用Python脚本(灵活控制) - 使用redis-py连接源和目标Redis - 遍历指定键(使用scan_iter避免阻塞) - 对于每个键: value = r_source.get(key) # 注意:如果是非字符串类型,需要使用相应的命令(如hgetall, lrange等) ttl = r_source.ttl(key) # 获取剩余TTL,单位秒 # 如果ttl为-1(永久),则在目标Redis设置时不带过期时间;如果ttl>0,则设置相同的过期时间 r_target.set(key, value, ex=ttl if ttl>0 else None) # 但注意:set命令只适用于字符串,其他类型需要特殊处理 但是,上面的方法3对于非字符串类型不适用。因此,我们需要根据键的类型分别处理。 改进的Python脚本思路: - 使用type命令判断键的类型 - 根据不同类型使用不同的方式读取和写入: String: get/set Hash: hgetall/hmset List: lrange/lpush Set: smembers/sadd Zset: zrange/zadd - 同时处理TTL:先写入数据,然后如果TTL大于0,则使用expire命令设置过期时间(因为多元素命令如hmset不支持直接设置过期时间) 注意:如果键不存在(TTL为-2),则跳过。 由于用户要求迁移指定键,我们可以先获取这些键(比如通过keys模式或者提供一个键列表),然后逐个迁移。 步骤: 1. 连接源Redis和目标Redis 2. 获取要迁移的键列表(可以使用keys或scan_iter) 3. 遍历每个键: type = src.type(key).decode('utf-8') ttl = src.ttl(key) # 返回剩余秒数,-2表示键不存在 if ttl == -2: print(f"键 {key} 不存在,跳过") continue if type == 'string': value = src.get(key) dst.set(key, value) elif type == 'hash': value = src.hgetall(key) dst.hmset(key, value) elif type == 'list': # 先删除目标中可能存在的旧键,然后重新push dst.delete(key) # 确保旧数据被清除 # 获取列表所有元素 elements = src.lrange(key, 0, -1) for e in elements: dst.rpush(key, e) ... 其他类型类似 # 设置过期时间 if ttl > 0: dst.expire(key, ttl) elif ttl == -1: # 永久有效,不需要设置过期时间 pass 4. 注意:上面的代码是示例,实际使用时需要考虑性能和大键问题(比如大列表可能会阻塞,可以分批次迁移?但Redis命令本身是原子的,迁移大键时可以考虑分批写入,但这样会破坏原子性。所以如果允许短暂阻塞,可以直接迁移。否则,建议在业务低峰期进行。) 相关问题: 1. 如何避免迁移过程中对Redis性能的影响? 2. 迁移大键(BigKey)时有哪些注意事项? 3. 如何确保迁移数据的一致性(迁移过程中数据被修改)? 4. 除了逐个键迁移,还有哪些批量迁移工具? </think> 以下是将 Redis 指定键值数据导出到新 Redis 数据库的几种方法及详细步骤,结合引用内容中的关键技术和注意事项: ### 一、核心迁移方法 1. **基于 `redis-dump` 工具迁移**(推荐批量操作) ```bash # 导出指定键的数据(支持通配符) redis-dump -u redis://源库IP:端口 -a 密码 -d 库号 -k "user:*" > data.json # 导入到新库 cat data.json | redis-load -u redis://目标库IP:端口 -a 密码 ``` - 支持正则匹配键名(如 `user:*` 导出所有 user 开头的键)[^1] - 自动处理数据类型和 TTL 设置(含 `$-2$` 不存在的键会跳过)[^1] 2. **使用 `SCAN` + `RESTORE` 命令迁移**(避免阻塞) ```python import redis src = redis.Redis(host="源IP", port=6379, db=0) dst = redis.Redis(host="目标IP", port=6379, db=0) # 分批扫描键(避免BigKey阻塞) for key in src.scan_iter("user:*", count=100): ttl = src.ttl(key) if ttl == -2: continue # 跳过不存在键[^1] # 序列化键值(支持所有数据类型) serialized = src.dump(key) # 还原到新库(保留TTL) dst.restore(key, ttl * 1000, serialized, replace=True) ``` - 通过 `scan_iter` 增量遍历避免内存溢出[^2] - 自动处理 BigKey(如拆分哈希表)[^2] 3. **JMeter 脚本迁移**(适合测试环境) ```java // BeanShell 采样器(参考引用[3]) import redis.clients.jedis.Jedis; Jedis src = new Jedis("源IP", 6379); Jedis dst = new Jedis("目标IP", 6379); String value = src.get("${key}"); dst.set("${key}", value); // 设置TTL(毫秒) dst.pexpire("${key}", src.pttl("${key}")); ``` - 需安装 Redis 插件到 JMeter - 通过 CSV 文件批量导入键列表[^3] ### 二、关键技术要点 1. **BigKey 处理** - 使用 `redis-cli --bigkeys` 提前识别大键[^2] - 对集合类型(Hash/Set)分批迁移: ```bash # 分页读取哈希表 HSCAN user:profile 0 COUNT 100 ``` 2. **TTL 保留** - 迁移时需转换时间单位:秒→毫秒(`ttl`→`pexpire`) - 特殊值处理: - `$-1$`:永不过期 → 目标库不设 TTL - `$-2$`:跳过不迁移[^1] 3. **数据一致性** - 使用 `MULTI/EXEC` 事务保证原子性 - 增量迁移时记录游标(`SCAN` 返回的游标值) ### 三、操作流程图 ```mermaid graph TD A[开始] --> B[连接源Redis] B --> C{键筛选模式} C -->|通配符| D[SCAN 增量遍历] C -->|指定列表| E[读取键清单] D/E --> F[获取键类型和TTL] F -->|TTL=-2| G[跳过] F -->|正常键| H[序列化数据] H --> I[RESTORE到新库] I --> J[设置TTL] J --> K{是否完成} K -->|否| D K -->|是| L[结束] ``` ### 注意事项 1. 网络带宽:千兆网络下迁移 100GB 数据需约 15 分钟 2. 版本兼容:目标库 Redis 版本 ≥ 源库版本 3. 内存控制:使用 `--pipe` 管道传输降低 RTT 延迟 ```bash cat data.txt | redis-cli -h 目标IP --pipe ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值