分布式系统架构8:分布式缓存

简介: 本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。

这是小卷对分布式系统架构学习的第11篇文章,今天了解分布式缓存的理论知识以及Redis集群。

分布式缓存也是面试常见的问题,通常面试官会问为什么要用缓存,以及用的Redis是哪种模式,用的过程中遇到哪些问题这些

1. AP还是CP

Redis 集群就是典型的 AP 式,它具有高性能、高可用等特点,但它却并不保证强一致性。

而能够保证强一致性的 ZooKeeper、Doozerd、Etcd 等框架,吞吐量比不过Redis,通常不会用作“缓存框架”,而是作为通知、协调、队列、分布式锁等使用

2.透明多级缓存TMC

实际开发中,同时搭配进程内缓存和分布式缓存,来构成透明多级缓存(Transparent Multilevel Cache,TMC)

多级缓存的查询过程如下图:

分布式缓存1.png

缺点:代码侵入性大,由开发人员维护管理

一、二级缓存数据不一致问题解决:

  • 设计原则:变更以分布式缓存中的数据为准,查询以进程内缓存数据优先

3.实现方案

3.1 memcached缓存

在服务端,memcached集群环境实际就是一个个memcached服务器的堆积

cache的分布式主要是在客户端实现,通过客户端的路由处理来达到分布式解决方案的目的。客户端做路由的原理,是在每次存取某key的value时,通过一致性哈希算法把key映射到某台memcached服务器node上。

如下是memcached客户端路由过程:

分布式缓存2.png

3.2 Redis缓存

与memcached客户端支持分布式方案不同,Redis更倾向于在服务端构建分布式存储

分布式缓存3.png

分布式缓存4.png

  • 以Redis集群模式为例,它没有中心节点,具有线性可伸缩的功能。

  • 节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信

  • 在数据的放置策略上,Redis Cluster将整个key的数值域分成2的14次方16384个hash槽,每个节点上可以存储一个或多个hash槽,也就是说当前Redis Cluster支持的最大节点数就是16384
  • 总结下:数据hash分布在不同redis节点实例,主/从切换采用Sentinel
  • 写:只会写master Instance,从sentinel获取当前的master instance;
  • 读:从redis node中基于权重选取一个实例读取,失败/超时则轮询其他实例;

要想详细了解redis的面试过程中的问题,可以参考下面的思维导图自行整理:

分布式缓存5.png

4. 缓存风险

4.1 缓存穿透

缓存风险问题也是面试常考的八股文题目,这里还是简单说明下

缓存穿透:查询的数据在数据库里根本不存在,缓存里也不会有,这样的请求每次都不会命中缓存,会请求到末端数据库。这种查询不存在数据的现象就是缓存穿透

解决办法:

  • 对业务逻辑本身不能避免的缓存穿透:对返回为空的Key值进行缓存,如果数据库中对该key插入新记录,就需要主动清理缓存的key值。
  • 恶意攻击导致的缓存穿透:缓存之前设置一个布隆过滤器来解决,思路就是判断请求的数据是否存在,布隆过滤器可以判断某个元素是否在集合中

4.2 缓存击穿

概念:单个热点key失效,在失效的那一刻,同时有大量请求打到DB上,造成数据库压力剧增的情况

解决办法:

  • 设置热点key不过期定时任务更新缓存或者设置互斥锁,当请求过来时,发现缓存不存在数据时,就给当前请求加锁,后面的请求等待或者返回,当从数据库中拿出来放到缓存中时,就可以释放锁资源。

4.3 缓存雪崩

概念:多个热点key缓存失效,大量的key设置了相同的过期时间、导致缓存在同一时间全部失效,造成瞬时DB请求量大、压力剧增。

解决办法:

  • 存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
  • 启用透明多级缓存,多个服务节点因为加载一级缓存的时间不一样,也能分散过期时间

4.4 缓存污染

概念:缓存中的数据与真实数据源中的数据不一致的现象

解决办法:

使用更新缓存时遵循的设计模式,如:Cache Aside,Read/Write Through,Write Behind Caching这些

Cache Aside模式的工作方式:

  • 读数据时,先读缓存,如缓存中没有,则读数据库,再将数据写入缓存中;
  • 写数据时,先写数据库,然后失效缓存(删除缓存数据);

面试可能遇到的两个关于Cache Aside的问题:

1.更新先后顺序,为什么先更新数据库再删除缓存?

  • 假设先删除缓存再更新数据库,会有一段时间是缓存已删除,数据库未更新的情况。这时如果有请求进来,缓存中没查到,就会查数据库中旧的数据,再放到缓存里。造成问题就是:数据库已经是最新数据,缓存中还是旧的,不一致的问题;

2.为什么是删除缓存,而不是更新缓存?

  • 和上面一样,更新过程中,如果有其他更新请求进来更新数据库,缓存就会面临多次修改赋值的复杂时序问题。所以直接删除缓存就行。

总结:本文只写了一些关于分布式缓存的简单理论内容,实际面试时大多围绕redis进行提问,下次再写关于redis的相关内容

相关文章
|
10天前
|
关系型数据库 Apache 微服务
《聊聊分布式》分布式系统基石:深入理解CAP理论及其工程实践
CAP理论指出分布式系统中一致性、可用性、分区容错性三者不可兼得,必须根据业务需求进行权衡。实际应用中,不同场景选择不同策略:金融系统重一致(CP),社交应用重可用(AP),内网系统可选CA。现代架构更趋向动态调整与混合策略,灵活应对复杂需求。
|
2月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
492 3
|
3月前
|
人工智能 Kubernetes 数据可视化
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
本文回顾了一次关键词监测任务在容器集群中失效的全过程,分析了中转IP复用、调度节奏和异常处理等隐性风险,并提出通过解耦架构、动态IP分发和行为模拟优化采集策略,最终实现稳定高效的数据抓取与分析。
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
|
10天前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
8天前
|
消息中间件 运维 监控
《聊聊分布式》BASE理论 分布式系统可用性与一致性的工程平衡艺术
BASE理论是对CAP定理中可用性与分区容错性的实践延伸,通过“基本可用、软状态、最终一致性”三大核心,解决分布式系统中ACID模型的性能瓶颈。它以业务为导向,在保证系统高可用的同时,合理放宽强一致性要求,并借助补偿机制、消息队列等技术实现数据最终一致,广泛应用于电商、社交、外卖等大规模互联网场景。
|
10天前
|
算法 NoSQL 关系型数据库
《聊聊分布式》分布式系统核心概念
分布式系统由多节点协同工作,突破单机瓶颈,提升可用性与扩展性。CAP定理指出一致性、可用性、分区容错性三者不可兼得,BASE理论通过基本可用、软状态、最终一致性实现工程平衡,共识算法如Raft保障数据一致与系统可靠。
|
26天前
|
缓存 运维 监控
Redis 7.0 高性能缓存架构设计与优化
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Redis 7.0高性能缓存架构,探索函数化编程、多层缓存、集群优化与分片消息系统,用代码在二进制星河中谱写极客诗篇。
|
25天前
|
存储 NoSQL 前端开发
【赵渝强老师】MongoDB的分布式存储架构
MongoDB分片通过将数据分布到多台服务器,实现海量数据的高效存储与读写。其架构包含路由、配置服务器和分片服务器,支持水平扩展,结合复制集保障高可用性,适用于大规模生产环境。
168 1
|
1月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,