3. Redis深度解析:数据结构与命令、单线程模型与性能瓶颈、持久化(RDB/AOF)、主从与哨兵模式
各位同学,咱们今天聊聊Redis。说实话,Redis在风控系统里几乎是标配。我见过不少团队,上来就怼Redis,但用着用着就出问题——要么内存爆了,要么主从切换丢了数据。嗯,这章咱们就把Redis的底裤扒干净。
3.1 数据结构与命令:不只是缓存
很多人觉得Redis就是个缓存,存个key-value完事。其实它的数据结构才是真正的杀手锏。我当年做风控规则引擎时,就靠Redis的几种结构撑起了整个实时计算层。
| 数据结构 | 底层实现 | 风控典型场景 |
|---|---|---|
| String | SDS(动态字符串) | 设备指纹、Token存储 |
| Hash | ziplist / hashtable | 用户画像字段、策略配置 |
| List | quicklist | 消息队列、操作流水 |
| Set | intset / hashtable | 黑名单、IP集合 |
| Sorted Set | skiplist + hashtable | 排行榜、滑动窗口限流 |
我个人习惯用Sorted Set做滑动窗口限流。为什么?因为它天然支持按分数排序,时间戳就是分数。你想想看,要统计过去1秒的请求量,一条ZREMRANGEBYSCORE命令就搞定了。
避坑指南:我曾经在项目里用List做消息队列,结果消费者挂了,消息全丢了。后来改用Stream结构,支持消费者组和消息持久化,稳多了。
3.2 单线程模型与性能瓶颈
Redis是单线程的,这事儿大家都知道。但为什么单线程还能这么快?说白了,就三点:
- 纯内存操作——内存比磁盘快几个数量级
- IO多路复用——epoll/kqueue,一个线程管所有连接
- 避免上下文切换——没有锁竞争,没有线程切换开销
但单线程也有坑。我记得有一次线上告警,Redis的CPU飙到100%,查了半天发现是有人在生产环境执行了KEYS *命令。嗯,这命令会遍历所有key,单线程下直接卡死。
警告:生产环境严禁使用KEYS、FLUSHALL、FLUSHDB等阻塞命令。用SCAN代替KEYS,用RENAME重命名危险命令。
性能瓶颈主要出现在几个地方:
- 大key问题——一个hash里有几百万字段,操作一次耗时几十毫秒
- 慢查询——比如ZRANGEBYSCORE取大量数据
- fork阻塞——RDB持久化时fork子进程,内存越大阻塞越久
怎么排查?用SLOWLOG命令看慢查询,用redis-cli --bigkeys扫描大key。我一般会设置慢查询阈值到10毫秒,超过就报警。
3.3 持久化:RDB vs AOF
Redis默认是内存数据库,但数据不能丢啊。持久化就两个方案:RDB和AOF。我刚开始用Redis时,觉得RDB简单粗暴,后来被坑过一次才明白AOF的重要性。
3.3.1 RDB(快照)
RDB就是定期把内存数据dump到磁盘。优点是文件小、恢复快。缺点是可能丢数据——比如你设置5分钟保存一次,那这5分钟内的数据就没了。
# redis.conf配置
save 900 1 # 900秒内至少1个key变化就保存
save 300 10 # 300秒内至少10个key变化就保存
save 60 10000 # 60秒内至少10000个key变化就保存
我个人习惯在风控场景下,RDB的保存间隔设短一点。因为风控数据丢了,可能就漏判了一笔欺诈交易。
3.3.2 AOF(追加文件)
AOF记录每一条写命令,类似MySQL的binlog。优点是数据更安全,可以做到每秒同步。缺点是文件大、恢复慢。
# redis.conf配置
appendonly yes
appendfsync everysec # 每秒同步,兼顾性能和安全
我的建议:风控系统用AOF + everysec模式。RDB可以关掉或者只做备份用。我曾经遇到过RDB丢数据的惨案,从那以后AOF就是标配了。
3.4 主从与哨兵模式
单机Redis挂了怎么办?主从复制是基础,哨兵是高可用的保障。
3.4.1 主从复制
主从复制就是一台Master写,多台Slave读。风控系统里,读多写少,主从正好合适。
# Slave节点配置
replicaof 192.168.1.100 6379
replica-read-only yes
但主从有个问题——Master挂了,不会自动切换。这时候就需要哨兵了。
3.4.2 哨兵模式
哨兵就是监控Redis集群的守护进程。它会自动检测Master是否挂了,然后从Slave里选一个升为Master。
我记得有一次线上Master挂了,哨兵在3秒内完成了切换,业务几乎无感知。但要注意,哨兵本身也要高可用,至少部署3个节点。
核心配置:
# sentinel.conf
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
其中2表示至少2个哨兵同意才能判定Master挂了。
3.5 知识体系总览
下面这张图是我自己画的,把Redis的核心知识点串起来了。你想想看,从数据结构到持久化,再到高可用,其实是一条线。
嗯,这张图把Redis的核心脉络理清了。从底层数据结构到上层高可用,再到风控落地,每一步都有坑,但也都有解法。
最后说一句:Redis不是银弹。我见过有人把所有数据都塞Redis,结果内存爆了,性能反而比MySQL还差。选型时一定要想清楚:你的数据量多大?读写比例多少?能不能接受丢数据?想清楚了,再用Redis。