背景
公司的A业务与B业务共用一套redis存储,架构如下:
 前期业务量小,多个业务共用同一套 Redis 的好处如下:
- 节省资源:使用同一套 Redis 实例可以减少资源的占用,避免多个业务都需要独立运行 Redis 实例的情况。
 - 简化部署和管理:只需要维护和管理一个 Redis 实例,可以大大简化部署和运维的工作量。
 - 共享缓存:多个业务可以共享同一个 Redis 缓存,避免重复缓存同样的数据,提高缓存命中率和性能。
 - 数据一致性:通过使用同一套 Redis 实例,可以实现多个业务共享相同的数据,并且保持数据一致性。
 - 统一监控和调优:通过集中管理同一套 Redis 实例,可以集中监控和调优,更好地掌握整体性能和瓶颈。
 
随着业务量的上涨,与共用 Redis 实例相比,下面的因素不得不考虑:
- 安全性:不同业务共享同一套 Redis 实例,需要考虑数据隔离和权限控制的问题,确保数据安全。
 - 争抢资源:如果多个业务同时对 Redis 进行频繁读写操作,可能会导致资源竞争和性能瓶颈,需要进行合理的并发控制和调优。
 - 影响范围:如果某个业务对 Redis 造成异常负载或错误操作,可能会影响到其它共用 Redis 实例的业务。
 - 依赖关系:多个业务共用同一套 Redis 实例,要确保任何一方的更新操作不会破坏其他业务的正常运行,并且确保所有相关业务对 Redis 的使用是相互兼容的。
 
线上多次发生A与B业务对redis资源的争夺,导致相互影响自己的业务,因此必须做redis集群实例的隔离。A与B业务独立使用各自的redis集群,架构如下图:

A业务继续使用redis集群1,新搭建redis集群2给B业务使用,这样就做到了redis实例的隔离。看似方案完美,但同时也带来了新的问题,如下:
- 业务B存在redis的数据,是在新的redis2集群上新建,还是从redis集群1迁移到redis集群2
 - 怎么把redis集群1业务B的数据迁移到redis集群2
 - B业务的数据迁移了,在redis集群1上要删除B业务的数据,释放内存空间
 
以上问题的共同点,需要在redis集群1上找出业务B的数据,才能做数据迁移以及删除。
业务分析
目前业务使用redis的情况如下:
- A业务与B业务都是默认使用0号db,redis默认是16个db,0-15。
 - A业务与B业务的数据,通过key的前缀做了区分,比如:A业务都是以a:开头,b业务都是以b:开头
 - redis的持久化策略,使用rdb,每天凌晨保存一次
 
通过以上分析,如果能解析rdb,同时过滤出b:开头的所有key,那我们就能做到redis数据的迁移,以及数据的删除。我前面的文章 redis存储可视化分析 Rdr工具能分析rdb分件,但是有个问题是 rdr没提供key前缀匹配的功能。可以使用redis-rdb-tools进行分析
redis-rdb-tools工具介绍
描述
redis-rdb-tools 解析 Redis dump.rdb 文件、分析内存并将数据导出为 JSON 格式.
Rdbtools is a parser for Redis' dump.rdb files. The parser generates events similar to an xml sax parser, and is very efficient memory wise.
In addition, rdbtools provides utilities to :
- Generate a Memory Report of your data across all databases and keys
 - Convert dump files to JSON
 - Compare two dump files using standard diff tools
 
安装
通过python的pip工具安装(推荐),这种方式最简单
            
            
              js
              
              
            
          
          pip install rdbtools python-lzf
        使用方式
安装完成后,通过 rdb -h 查看使用方式
            
            
              shell
              
              
            
          
          rdb -h
usage: usage: rdb [options] /path/to/dump.rdb
Example : rdb --command json -k "user.*" /var/redis/6379/dump.rdb
positional arguments:
  dump_file             RDB Dump file to process
optional arguments:
  -h, --help            show this help message and exit
  -c CMD, --command CMD
                        Command to execute. Valid commands are json, diff,
                        justkeys, justkeyvals, memory and protocol
  -f FILE, --file FILE  Output file
  -n DBS, --db DBS      Database Number. Multiple databases can be provided.
                        If not specified, all databases will be included.
  -k KEYS, --key KEYS   Keys to export. This can be a regular expression
  -o NOT_KEYS, --not-key NOT_KEYS
                        Keys Not to export. This can be a regular expression
  -t TYPES, --type TYPES
                        Data types to include. Possible values are string,
                        hash, set, sortedset, list. Multiple typees can be
                        provided. If not specified, all data types will be
                        returned
  -b BYTES, --bytes BYTES
                        Limit memory output to keys greater to or equal to
                        this value (in bytes)
  -l LARGEST, --largest LARGEST
                        Limit memory output to only the top N keys (by size)
  -e {raw,print,utf8,base64}, --escape {raw,print,utf8,base64}
                        Escape strings to encoding: raw (default), print,
                        utf8, or base64.
  -x, --no-expire       With protocol command, remove expiry from all keys
  -a N, --amend-expire N
                        With protocol command, add N seconds to key expiry
                        time
        我这里需要通过 前缀匹配,输出到文件,命令如下:
            
            
              js
              
              
            
          
          rdb --command justkeyvals --key "b:*" dump.rdb > data.txt
        以上,获取到redis集群1里面业务B的数据,到此,我就可以对数据进行迁移删除
实施步骤
双读单写
进行数据迁移前,如果直接迁移,业务B里面读取不到数据,影响业务,所以先改造业务,双读单写,业务B新的数据写入到redis集群2,读取数据,先从redis集群1读,如果没有数据再去redis集群2读取,这样保持数据能从reids获取,如图:

数据迁移
业务B发布线上后,新的数据写入到redis2集群,迁移前,redis执行bgasve,拿到最新的rdb快照信息,就可以开始解析rdb文件,进行数据的迁移
- 解析rdb文件,查找以b: 开头的前缀,如果你的业务有多种key开头,就多次解析
 
            
            
              js
              
              
            
          
          rdb --command justkeyvals --key "b:*" dump.rdb > data.txt
        解析出的格式如下: 前面key,后面是value,解析的时候 以空格分隔
            
            
              js
              
              
            
          
          b:user003 fname Ron,sname Bumquist,
b:user001 fname Raoul,sname Duke,
b:user002 fname Gonzo,sname Dr,
b:user_list user003,user002,user001
        把这些数据写入到redis集群2,同时根据key,删除redis集群1种业务B的数据,释放内存
单写单读 完成隔离
数据迁移完成后,业务B改造,数据读写都在redis集群2上进行,优化完后,再次上线,如图:

至此,redis数据的迁移完成
总结
- redis数据的分析,使用redis-rdb-tools
 - 数据的迁移前,需要对业务进行分析,制定方案,以免脱离实际,造成线上事故
 
写作不易,刚好你看到,刚好对你有帮助,动动小手,点点赞,有疑问的欢迎留言或者私信讨论
2023年最后一天班,再见2024,祝大家:2024发发发。