背景
公司的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发发发。