Week5 学习总结
分布式缓存架构
什么是缓存Cache
缓存
存储在计算机上的一个原始数据复制表,以便于访问
缓存是介于数据访问者和数据源之间的一种高速存储,当数据需要多次读取的时候,用于加快读取的速度。
缓存Cache和缓冲Buffer的分别?
缓存主要用于读多写少的场景
缓冲读写场景下都可用,主要用于网络、磁盘读写的场景下
无处不在的缓存
CPU缓存
操作系统缓存
数据库缓存
JVM编译缓存
CDN缓存
代理与反向代理缓存
应用程序缓存
分布式对象缓存
缓存数据存储(Hash表)
缓存的关键指标
缓存命中率
缓存是否有效依赖于能多少次重用同一个缓存响应业务请求,这个度量指标被称作缓存命中率。
如果查询一个缓存,十次查询九次能够得到正确结果,那么它的命中率是90%
影响缓存命中率的主要指标
缓存键集合大小
缓存中每个对象使用缓存键进行识别,定位一个对象的唯一方式就是对缓存执行精确匹配
商品ID作缓存键,缓存空间是应用能够生成的所有键的数量
从统计数字上看,应用生成的唯一键越多,重用的机会越小
一定要想办法减少可能的缓存键数量
键数量越少,缓存的效率越高
缓存可使用内存空间
直接决定了缓存对象的平均大小和缓存对象数量
因为缓存通常存储在内存中,缓存对象可用空间受到严格限制且相对昂贵。
如果想缓存更多的对象,就需要先删除老的对象,再添加新的对象。老的对象被删除后,将来的请求无法命中它,这就会降低命中率
物理上能缓存的对象越多,缓存命中率就越高。
缓存对象生存时间
缓存对象生存时间称为TTL
缓存天气预报数据15min没问题,则可设置TTL为15min
根据应用场景灵活设置TTL
对象的缓存时间越长,缓存对象被重用的可能性就越高
代理缓存
反向代理缓存
多层反向代理缓存
内容分发网络CDN
CDN同时配置静态文件和动态内容
通读缓存read-through
代理缓存,反向代理缓存,CDN缓存都是通读缓存
通读缓存给客户端返回缓存资源,并在请求未命中时获取实际数据
客户端连接的是通读缓存而不是生成响应的原始服务器
旁路缓存cache-aside
对象缓存是一种旁路缓存,旁路缓存通常是一个独立的键值对存储
应用代码通常会询问对象缓存需要的对象是否存在,如果存在,它会获取并使用缓存的对象,如果不存在或已过期,应用会连接主数据源来组装对象,并将其保存回对象缓存中以便将来使用
浏览器对象缓存
本地对象缓存
对象直接缓存在应用程序内存中
对象存储在共享内存,同一台机器的多个进程可以访问它们
缓存服务器作为独立应用和应用程序部署在同一台服务器上
本地缓存对象构件分布式集群
远程分布式对象缓存
Memcached分布式对象缓存
Memcached分布式缓存访问模型
分布式对象缓存的一致性hash算法
基于虚拟节点的一致性hash算法
各介质数据访问延迟
技术栈各个层次的缓存
缓存为什么能显著提升性能?
缓存数据通常来自内存,比磁盘上的数据有更快的访问速度
缓存数据的最终结果形态,不需要中间计算,减少CPU资源消耗
缓存降低数据库、磁盘、网络的负载压力,使这些I/O设备获得更好的响应特性
缓存是系统性能优化的大杀器
技术简单
性能显著提升
应用场景多
合理使用缓存
过分依赖缓存、不合适的数据访问特性反而会拖慢系统。
频繁修改的数据
这种数据如果缓存起来,由于频繁修改,应用还来不及读取就已经失效或更新,徒增系统负担。
一般来说,数据的读写比在2:1以上,才具有缓存意义
没有热点的访问
缓存使用内存作为存储,内存资源宝贵而有限,不能将所有数据都缓存起来
大部分数据访问不是集中在小部分数据上,那么缓存就没有意义
数据不一致与脏读
一般会对缓存的数据设置失效时间,一旦超过失效时间,就要从数据库中重新加载
数据更新时立即更新缓存
会带来更多的系统开销和事务一致性的问题
数据更新时通知缓存失效
删除该缓存数据,是一种更加稳妥的做法
缓存雪崩
随着业务的发展,缓存会承担大部分的数据访问压力,数据库已经习惯了有缓存的日子
当缓存服务崩溃的时候,数据库会因为完全不能承受如此大的压力而宕机,进而导致整个网站不可用
发生这种故障,甚至不能简单的重启缓存服务器和数据库服务器来恢复网站访问
缓存预热
缓存中存放的是热点数据(遵循二八原则规律中的二占了八的访问量),热点数据又是缓存系统利用LRU(最近最久未用)算法对不断访问的数据筛选淘汰出来的,这个过程需要花费较长时间
在这段时间,系统的性能和数据库负载都不太好,那么最好在缓存系统启动的时候就把热点数据加载好,这个缓存预加载手段就是缓存预热(warm up)
例:对于一些元数据如城市地名列表、类目信息,可以启动时加载数据库中全部数据到缓存进行预热
缓存穿透
如果不恰当的业务、或者恶意攻击持续高并发的请求某个不存在的数据,因为缓存没有保存该数据,所有的请求都会落到数据库上,会对数据库造成很大的压力,甚至崩溃
一个简答的对策是将不存在的数据也缓存起来(其value值为null),并设定一个较短的失效时间
Redis VS Memcached
Redis支持复杂的数据结构
Redis支持多路复用异步I/O高性能
Redis支持主从复制高可用
Redis原生集群与share nothing集群模式
Redis集群
Redis集群预分好16384个桶,当需要再Redis集群中防止一个K-V时,根据CRC16(key)mod 16384的值,决定将一个key放到哪个桶中
Redis-cluster把所有的物理节点映射到【0-16383】slot上(不一定是平均分配),cluster负责维护slot与服务器的映射关系
客户端与Redis节点直连,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
所有的Redis节点彼此互连
消息队列与异步架构
同步调用VS异步调用
同步调用
多次同步调用
阻塞应用线程
异步调用
多次异步调用
不阻塞应用线程
消息队列构件异步调用架构
角色
消息生产者
消息队列
消息消费者
模型
点对点模型
发布订阅模型
消息队列的好处
实现异步处理,提升处理性能
更好的伸缩性
削峰填谷
失败隔离和自我修复
因为发布者不直接依赖消费者,所以消息系统可以将消费者系统错误与生产者系统组件隔离
生产者和消费者互相不受对方失败影响
这意味着任何时刻,我们可以对后端服务器执行维护和发布操作。我们可以重启、添加或删除服务而不影响生产者可用性,这样简化了部署和服务器管理的难度。
解耦
事件驱动架构EDA
主要MQ产品比较
RabbitMQ主要特点是性能好,社区活跃,但是RabbitMQ用Erlang开发,对不熟悉Erlang的同学而言不便于二次开发和维护。(49M)
ActiveMQ影响比较广泛,可以跨平台,使用Java开发,对Java比较友好。(27M)
RocketMQ是阿里推出的一个开源产品,也是使用Java开发,性能比较友好,可靠性也比较高。(35M)
Kafka,LinkedIn出品,Scala开发,专门针对分布式场景进行了优化,因此分布式的伸缩性会比较好。(63M)
负载均衡架构
HTTP重定向负载均衡
DNS负载均衡
反向代理负载均衡
IP负载均衡
负载均衡服务器(网关服务器)
数据链路层负载均衡
负载均衡算法
轮询
所有请求依次分发到每一台服务器上,适合所有硬件配置都相同的场景
加权轮询
在轮询基础上,按照配置权重分配请求
例如高性能服务器设置权重大一些,分配更多请求
随机
最少连接
新请求分发到最少连接请求的服务器上
源地址散列
将来源的IP地址进行Hash计算得到应用服务器
session会话粘滞使用
应用服务器集群的Session管理
Session复制
Session绑定
利用Cookie记录Session
Session服务器(集群)单独保存
评论