架构师训练营 第 5 周总结
本周学习重点知识点:
分布式缓存架构
缓存和缓冲的区别
缓存:把常用的数据存储到可以快速获取的区域(缓存区),以备重复读取,提高效率。例如,将业务数据缓存在应用程序或者 Redis 等缓存服务中,避免每次都查询数据库,从而提高访问性能,降低对数据库的查询压力。
缓冲:在数据流转过程中,不同层次数据速度不一致时,利用缓冲区来缓解上下层之间的速度问题。例如,将数据从内存写入到磁盘时,先写入缓冲区,磁盘则直接从缓冲区中读取写入,减少 IO 次数,增加速度,降低对磁盘的损耗。
使用缓存的位置
CPU 缓存
操作系统缓存
数据库缓存
JVM 编译缓存
CDN 缓存
代理与反向代理缓存
应用程序缓存
分布式对象缓存
缓存的关键指标
缓存命中率(及受影响的主要指标)
缓存键集合大小
缓存可使用内存空间
缓存对象生存时间
缓存方式
通读缓存(read-through)
旁路缓存(cache-aside)
缓存集群的2个核心问题(适用于各种集群)
集群路由
hash + 取模(对伸缩不友好,扩容时大量缓存会失效,可能导致缓存雪崩和系统崩溃)
一致性 hash(只有很小部分缓存会失效,推荐使用)
集群伸缩
消息队列与异步架构
异步调用
有回调的异步调用
多次异步调用,不阻塞应用线程
消息队列构建异步调用架构
消息生产者
消息队列
消息消费者
架构模型
点对点
发布订阅
消息队列的好处
实现异步处理,提升处理性能
更好的伸缩性
削峰填谷
失败隔离和自我修复
解耦
负载均衡架构
负载均衡的种类
HTTP 重定向负载均衡
缺点
性能问题(2次请求)
安全问题,直接暴露了应用服务器
只支持 Get 请求
DNS 负载均衡
反向代理负载均衡
IP 负载均衡(三层协议)
数据链路层负载均衡(二层协议)
负载均衡算法
轮询
加权轮询
随机
最少连接
源地址散列
应用服务器的 Session 管理
Session 复制
Session 绑定(无法满足业务发展需要,因为服务器扩容,或者重启都会导致 Session 丢失)
利用 Cookie 记录 Session
Session 服务器
分布式数据库
MySQL 复制
主从复制
一主多从复制
分摊负载
专机专用
便于冷备
高可用
主主复制
一些学习感悟:
关于集群伸缩
hash(key) + 按节点数取模 的方式对集群伸缩不友好,以集群节点100个为例,增加一个新节点会导致99%的缓存数据失效。
这种方式在极端情况下,会导致其它服务器压力大增,引起缓存雪崩,最后使整个系统崩溃。而且在访问高峰期间,系统很难重新恢复,刚重启,数据库就可能瞬间被打爆。这时候要让系统恢复,可以通过 Nginx 阻断限流,慢慢放流量,才可能在高峰期恢复系统。
一致性哈希 + 虚拟节点,在以集群节点100个为例时,增加一个新节点只会导致1%的缓存数据失效。
一致性哈希算法可以将数据尽可能平均的存储到N台缓存服务器上,提高系统的负载均衡,并且当有缓存服务器加入或退出集群时,尽可能少的影响现有缓存服务器的命中率,减少数据对后台服务的大量冲击。
关于缓存的使用
缓存一般不需要更新,在数据发生变化时,通常只要把缓存清除就可以了,不需要同步更新。
缓存集群扩容时导致小部分数据访问不到没关系(比如通过一致性哈希只有很小一部分数据失效),只要不出现大面积数据失效就没太大问题(比如hash(key)取模的方式)。
缓存强大就是因为它简单,缓存就应该有缓存的样子,最纯粹地使用缓存,它简单、耐用、时效。不要把缓存的数据搞得完美同步,那样反而会增加不必要的复杂度。
一条数据从Redis缓存读取和从数据库查询(带索引)的性能会相差100倍左右(从Redis中读取大约是0.5毫秒,从数据库查询大约是十几到50毫秒)。
负载均衡
负载均衡的高并发
第一级通过DNS负载均衡到多个反向代理负载均衡服务器(DNS解析会在客户端有缓存,更新一次DNS负载均衡不会立马生效,架构中应考虑这一点)
第二级反向代理负载均衡服务器再分发到具体的后台服务器上
如果第二级还是不够用,那么可以增加DNS负载均衡的反向代理服务器(DNS改动会有延迟,因为客户端的缓存),或者通过F5之类的硬件负载均衡服务器(走更底层的协议,如数据链路层)来转发到多个反向代理负载均衡服务器
负载均衡服务器的高可用
可以通过类似 LVS + Keepalived 实现
LVS、Nginx 一般可以支持数万至十万级的并发
硬件负载均衡可以用在百万级的并发
阿里的 SLB 七层、四层、二层都有
分布式数据库
一般方案
主主+多从,以实现高可用(主主)和高性能(主从,读写分离)
双主的方案可能导致数据的不一致和冲突,比如主1宕机时,有数据未同步到主2,那么主2的自增id的数据会和主1有冲突,此类问题没有太好的解决办法,一般需要额外的工作来追回数据,或者就直接放弃掉那部分数据(如果不重要的话)
如果需要做DDL的话,因为DDL可能会导致所表,使数据暂时无法插入,所以在更新主上的表结构时候,同时手动更新从上的表结构(而不是等待同步自动更新),因为此时从是最好的更新时机,因为如果主的表锁住,也不会有数据进入主,那么从可以趁这个时段同时更新表结构。
版权声明: 本文为 InfoQ 作者【Lingjun】的原创文章。
原文链接:【http://xie.infoq.cn/article/f3ac07a58fda7ff05765e3e05】。文章转载请联系作者。
评论