第五周总结
分布式缓存架构
缓存的关键指标是缓存命中率。
影响缓存命中率的主要指标为:
缓存键集合大小(一定要想办法减少可能的缓存键数量,键数越少,缓存效率越高)
缓存可使用内存空间(物理上能缓存的对象越多,缓存命中率就越高)
缓存对象生存时间(TTL,对象缓存的时间越长,缓存对象被重用的可能性就越高)
通读缓存(read-through):Ngnix 的反向代理缓存以及 CDN 就属于通读缓存。
旁路缓存(cache-aside):我们通常使用的 Redis 就是一种旁路缓存
带虚拟节点的一致性 Hash 算法
该算法将所有的存储节点排列在首尾相接的 Hash 环上,每个 key 在计算 Hash 后会顺时针找到相邻的第一个节点存放,目的就是为了在节点数目发生改变时尽可能少的迁移数据。而当有节点加入或退出时,仅影响该节点在 Hash 环上顺时针相邻的后续节点之间的数据。在虚拟节点加入的情况下也改善了 Hash 环偏斜的情况。
关于一致性哈希的实践在另一篇有详细描述:用一致性 Hash 算法的实现负载均衡
缓存是系统性能优化的大杀器:技术简单,性能提升显著,应用场景多
这点很同意,最开始我们的分销系统没有使用缓存,每次做活动访问量打的时候就会导致反应特别慢,后来通过加 Redis 缓存解决了问题。
但是也要合理使用缓存,避免出现以下一些问题:
缓存穿透:将不纯在的数据也缓存起来,并设立焦段的时效时间。
缓存雪崩:增加更新锁机制与后台更新机制。
缓存没有热点: 遵循 28 原则。
数据不一致与脏读:数据更新时通知缓存失效。
消息队列与异步架构
在如今互联网时代的大背景下,Web 应用通常要面对高并发、海量数据的挑战,性能从来都是必须要考量的核心因素。阻塞便是性能杀手之一
要解决这个问题一般有两种解决思路:
并行化:使用更多的线程和硬件资源。
异步化:基于现有的资源来提高执行效率。
使用并行化,高并发环境下,多线程的切换会消耗 CPU 资源,更多的线程意味着更多的内存占用。
所以异步非阻塞的架构解决这个问题是个很好的方案。
异步调用架构可以使用消息队列来实现,当前多使用发布订阅模型,好处有:
实现异步处理,提升处理性能
更好的伸缩性
削峰填谷
失败隔离和自我修复
解耦
还有一种是基于基于 JVM 的数据流异步模型,比如 Rxjava, Reactor, 在中小型应用中可以减少一个消息中间件的维护。
负债均衡架构
负责均衡架构主要有以下几种方式:
HTTP 重定向负载均衡。
DNS 负载均衡。
方向代理负载均衡。
IP 负责均衡。
数据链路负载均衡。
负载均衡的算法:轮询、加权轮询、随机、最少连接、源地址散列。
在负载均衡集群环境中,Session 管理主要的的手段:
Session 复制:已淘汰,少量的服务器可以,大量的服务器 Session 同步会耗费大量的网络资源。
Session 绑定:已淘汰,服务器退出重启时,会导致 Session 失效。
Cookie 记录 Session:每次请求都需要带上 Cookie 对网络开销有影响,有的终端会禁用 Cookie。
Session 服务器:目前最常用的方案。
分布式数据库
MySQL 复制的方式有:
主从复制
一主多从复制:分摊负责,专机专用,便于冷备,高可用。
之前我们一个系统新增了数据分析业务,用的还是主数据库,结果导致了数据负载很高甚至业务中断,就是通过主从专机专用的方式进行解决。
主主复制
MySQL 复制的注意事项:
主主复制的两个数据库不能并发写入(但是如果能保证数据绝对不冲突,或者在一些临时性、可丢失、可覆盖的数据场景也是可以的😁)。
复制只是增加了数据的读并发处理能力,没有增加写并发能力和存储能力。
更新表结构会导致巨大的同步延迟。(在处理 DDL 脚本的时候,最好在停机维护时每个数据库手动执行。)
评论