Redis如何保证高可用?

NoSQL数据库关系型数据库数据库管理服务

大家好,我是苏三,又跟大家见面了。

前言

我亲历过Redis宕机导致损失惨重的教训。

真正的Redis高可用不是简单的主从复制,而是构建能自动愈合的分布式神经系统

这篇文章跟大家一起聊聊Redis如何保证高可用,希望对你会有所帮助。

这两天苏三的星球太火爆了,公众号上所有的优惠券都已经抢完了。

还需要优惠券的小伙伴,加一下我微信:li_su123,备注:优惠券,我单独发给你。

一、主从复制:高可用的基石与陷阱

主从复制全流程解析

picture.image

致命陷阱:异步复制导致的数据丢失

  
# 主节点写入后宕机(未同步到从节点)    
SET order:1001 "confirmed"    
# 从节点提升为主节点后,订单状态丢失    

解决方案:

  
// 强制同步写入(谨慎使用)    
Jedis jedis = new Jedis("master", 6379);    
jedis.waitReplicas(1, 1000); // 等待1个从节点同步    

二、哨兵模式:自动故障转移的艺术

三节点哨兵集群部署

picture.image

哨兵选举四部曲:

  1. 主观下线(SDOWN) :单个哨兵检测到主节点失联
  2. 客观下线(ODOWN) :超过 quorum 数量的哨兵确认
  3. 领导者选举 :基于Raft算法选出主哨兵
  4. 故障转移 :提升最优从节点为新主节点

Java客户端连接哨兵示例:

  
Set<String> sentinels = new HashSet<>();    
sentinels.add("192.168.1.10:26379");    
sentinels.add("192.168.1.11:26379");    
  
JedisSentinelPool pool = new JedisSentinelPool(    
    "mymaster", sentinels, poolConfig);    
  
try (Jedis jedis = pool.getResource()) {    
    // 自动路由到当前主节点    
    jedis.set("config:timeout", "500");     
}    

三、Redis Cluster:水平扩展的终极方案

数据分片原理

picture.image

节点通信Gossip协议:

  
// 模拟节点间状态传播    
public void gossip(Node node) {    
    // 随机选择3个节点交换状态    
    List<Node> peers = selectRandomPeers(3);    
    for (Node peer : peers) {    
        sendPing(peer, currentState);    
    }    
}    

跨槽位操作解决方案:

  
# 错误:多key不在同槽位    
MGET user:1001:name user:1002:age    
  
# 正确:使用hash tag强制同槽位    
MGET user:{1001}:name user:{1001}:age    

四、多级高可用架构设计

电商平台真实案例

picture.image

四层防护体系:

  1. 代理层 :Twemproxy自动路由+负载均衡
  2. 集群层 :双集群互备+就近访问
  3. 数据层 :1主2从+读写分离
  4. 灾备层 :跨地域异步复制

五、避坑指南

脑裂问题:最危险的故障模式

发生场景:

picture.image

解决方案:

  
# 1. 增加哨兵节点数(至少3个)    
sentinel monitor mymaster 192.168.1.10 6379 2    
  
# 2. 设置主节点最小从节点数    
min-replicas-to-write 1    

缓存雪崩预防

  
// 缓存穿透+雪崩防护代码示例    
public String getProductInfo(String id) {    
    // 1. 查询缓存    
    String cacheKey = "product:" + id;    
    String value = jedis.get(cacheKey);    
  
    // 2. 缓存穿透:空值缓存    
    if ("NULL\_OBJ".equals(value)) returnnull;    
  
    // 3. 缓存未命中    
    if (value == null) {    
        // 4. 互斥锁防止雪崩    
        if (jedis.setnx("lock:"+id, "1") == 1) {    
            jedis.expire("lock:"+id, 3); // 避免死锁    
            try {    
                // 5. 数据库查询    
                value = db.query("SELECT...");    
                // 6. 空结果防穿透    
                jedis.setex(cacheKey, 300, value == null ? "NULL\_OBJ" : value);    
            } finally {    
                jedis.del("lock:"+id);    
            }    
        } else {    
            // 7. 其他线程等待重试    
            Thread.sleep(100);    
            return getProductInfo(id);    
        }    
    }    
    return value;    
}    

六、监控体系:高可用的生命线

告警规则示例:

  
# 复制延迟 > 5秒    
repl\_delay{instance="*"} > 5    
  
# 内存使用 > 90%    
memory\_used\_percentage > 0.9    
  
# 连接数 > 80%上限    
connected\_clients / maxclients > 0.8    

总结

三级防御体系:

picture.image

五个核心原则:

  1. 冗余设计 :最少1主2从,跨机架部署
  2. 自动故障转移 :哨兵quorum数 = 节点数/2 + 1
  3. 容量规划 :内存使用率控制在70%以下
  4. 性能隔离 :业务集群物理隔离
  5. 混沌工程 :定期模拟节点宕机、网络分区

高可用的本质不是避免故障,而是在故障发生时系统仍能持续提供服务。

通过主从复制、哨兵机制、Cluster集群的三级防御,配合严谨的监控和容量规划,才能构建真正弹性的Redis架构。

最后欢迎加入苏三的星球,你将获得:100万QPS短链系统、复杂的商城微服务系统、苏三AI项目、刷题吧小程序、秒杀系统、商城系统、秒杀系统、代码生成工具等8个项目的源代码、开发教程和技术答疑。

系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1免费修改简历、技术答疑、职业规划、送书活动、技术交流。

目前星球已经更新了5800+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有1800+小伙伴加入学习。

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 NoSQL 的实践与探索
随着 NoSQL 的蓬勃发展越来越多的数据存储在了 NoSQL 系统中,并且 NoSQL 和 RDBMS 的界限越来越模糊,各种不同的专用 NoSQL 系统不停涌现,各具特色,形态不一。本次主要分享字节跳动内部和火山引擎 NoSQL 的实践,希望能够给大家一定的启发。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论