技术架构(6)-分布式缓存
什么是缓存
缓存是为了提高IO操作效率,提升数据读取命中率的一类硬件或者软件。在应用开发中,缓存通常是指将磁盘数据放在内存中的一类软件产品。
为什么需要分布式缓存
单体架构中用到的单机缓存把数据库的数据放到本地内存中,可以把数据写到HashMap,也可以写到成熟的缓存产品中。本地缓存不需要网络交互、序列化和反序列化,所以效率非常高。但它也存在一些制约。
- 数据不共享。每台服务器的缓存都是独享的,当数据源发生变化时,需要应用系统更新所有涉及到的服务器缓存,容易导致不一致。
- 缓存容量有限。本地缓存受制于分配的内存大小,没办法通过增加机器来扩展。
在这些制约因素下,随着分布式技术的发展,出现了分布式缓存。
- 数据共享。缓存独立部署,进程通过网络请求从缓存服务器读取数据。相比于直接在本地获取数据,分布式缓存会引入额外的网络开销。
- 持久化。为了提升性能,频繁更新又不是太重要的数据直接写缓存,比如浏览次数。这需要缓存具备持久化的能力,定时落盘,避免数据丢失。
- 动态扩容。缓存的数据量超出缓存集群容量时,需要在集群中增加机器。分布式缓存需要具备自动平衡数据的能力,把数据均匀分散在新增的机器上。
分布式缓存的问题
分布式缓存虽然叫分布式,实际上是一个集中的缓存,只是它支持用多台服务器来扩展性能。
双写一致性
数据的写操作同时更新数据库和缓存时,这不是一个原子操作,任何一方发生错误都会导致数据不一致。
通常的做法是,写入操作只写数据库,同时删除缓存。读取的时候,先读缓存,如果没有命中就把数据库的数据写入缓存再返回。
在写入数据时,如果写数据库成功,但删除缓存失败,也会导致不一致。这个时候,要对缓存的数据设置过期时间,失效之后再次访问时,会去数据库同步数据。
击穿
某个缓存失效了,这时候恰好有这个数据的大并发查询过来,所有请求直接打到数据库上,数据库就崩了,这个叫击穿。
- 合理设置过期时间。让缓存过期在午休、凌晨这样的非高峰时段。
- 加分布式锁。缓存没有命中时,只有抢到锁的请求才能去查询数据库更新缓存。注意这个锁也要设置一个比较短的过期时间。
穿透
搜索的数据根本不存在,就会越过缓存去查数据库,这叫穿透。如果有人恶意去频繁查询不存在的数据,会导致压力全部打到数据库上。
- 布隆过滤器。核心思想是不保存实际数据,而是在内存中创建定长的位图(bitmap),通过多次Hash,给多个对应的位打标志,用0和1来标记数据是否存在。优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。
雪崩
当多个缓存同时失效,或者缓存本身出问题了,导致大量查询请求打到数据库上,会宕机,这叫雪崩。
- 缓存分片。把数据分片存在缓存上,不会因为单个节点的失败而影响所有查询。
热点
关注度特别高的数据,即使放在缓存,它也扛不住巨大的流量,比如关于明星的吃瓜新闻,抵不住几千万人都去访问,这就是缓存热点。
- 热点数据复制。把数据复制到每个服务的内存里,直接从本地获取,通过部署大量的服务来分担压力。
这个知识点其实有大量的内容可以学习,我这里只列出了关键点,没有展开。