缓存、一致性哈希和负载均衡总结(训练营第五课)
缓存概要
Cache 缓存
介于数据访问者和数据源之间的一种高速存储;当数据需要多次读取时,用于加快读取的速度
核心是 辅助数据源以加快数据读取的速度;任何一种可以加速客户和数据源之间访问的存储方法、方案都可以作为缓存
关键在于 可以达到多次读取的目的
Buffer 缓冲
包括输入缓冲器和输出缓冲器
前者的作用是将外设送来的数据暂时存放,以便处理器将它取走;
后者的作用是用来暂时存放处理器送往外设的数据。
缓冲也是为了缓解 CPU 和外设之间的速度读写差异,通过专门的一块区域,并利用 大块数据少次读写替代 多次小数据读写,来达到提高和解放 CPU 的目的
关键在于 通过减少 CPU 和外设之间的 直接读写次数,达到解放 CPU 的目的
缓存数据存储 (Hash 表实现)
两步:
对 key 求 Hash,
再取余得到 hash 表索引
缓存命中率
缓存键集合大小
缓存可用内存空间
缓存对象生存时间 - TTL
广义上的缓存
CPU 缓存
操作系统缓存
数据库缓存
JVM 编译缓存
浏览器缓存
CDN 缓存
代理与反向代理缓存
应用程序缓存 - 本地对象缓存
分布式对象缓存
本地对象存储集群(数据同步)
远程分布式对象换出(数据无需同步,只保存一份) - MemCached
通读缓存和旁路缓存
Read-through: CDN, 代理,反向代理 - 客户端不直接连接 服务或存储,而是通过缓存来读取
Cache-aside:客户端自己来判断是否存在缓存,不存在则直接连接 服务或存储 来获取
缓存效率和常见问题
各种介质数据访问时间
本地内存是 SSD 的 1000 倍,只需要 0.1 us
通过网络缓存访问 比 数据库访问 快 50-100 倍数量级
数据中心内部的网络访问在 0.5 ms 数量级
从网络访问数据库的时间是 10ms 数量级
跨大洋一次请求需要 150ms
技术栈各个层次的缓存效果
不适合缓存的情况
频繁修改的数据 - 读写建议 2:1 以上
没有热点的访问
LRU 算法
缓存的数据不一致
是否可以容忍一定时间内的数据不一致
可以:通知用户等待缓存更新
短时间可以:通知缓存失效,一般不采用更新缓存数据的方法
分布式情况下,存在一定时间内(通知的时间)的数据不一致
完全不可以:需要考虑是否适用缓存?
缓存雪崩
数据库习惯了有缓存来缓解压力
缓存服务若是崩溃,数据库突发压力太大宕机,导致系统挂掉
缓存预热 - Warm Up
缓存启动时,预先加载热点数据
缓存穿透
持续高并发请求 不存在的 数据
缓存无数据,数据库压力大
对策:缓存不存在的数据 (value -> null)
一致性 Hash 算法
传统 Hash 实现
问题:
增加节点不能直接缓解 非相邻现有节点压力
减少节点会直接对相邻节点产生突发压力
虚拟节点改进
通过两层匹配来找到缓存对应的节点
对 key 求 Hash 找到对应的 虚拟节点
通过 虚拟节点 和 实际节点的 对照表,得到实际节点
当虚拟节点数量合适时(150-200),可以:
虚拟节点分布相对均匀在环上
Key 的 hash 分布也可以相对均匀到各个 虚拟节点
Redis 集群
设计思路:
类似一致性 Hash;不同点在于:
虚拟节点总数量固定,通过调整虚拟节点到实际节点的映射来达到增删节点时的数据平衡问题
消息队列
负载均衡
评论