什么是快取 (Cache)?快取 (Cache) 的机制为何?

2023年2月5日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

什么是快取 (Cache)?

目的为了弥补 Database 在复杂业务下的不足,基本原理是将可重使用的资料存放到记忆体中,这样可以避免每一次都去 Database 读取,进而将地效能。而以 Memcache 为例,查询可达到 TPS 50,000 以上。虽然说增加 Cache 可以减轻 Database 的压力,但会让系统变得复杂,因此若 Cache 没有设计好,则有可能造成系统崩溃。

快取 (Cache) 的应用场景

  1. 需要经过复杂计算才能得到值:每一次从 MySQL 去 Count(*) 大量数据,则不管怎么优化 MySQL 都无法解决这个问题。
  2. 读多写少的资料:在 Social media 上,写的人少(insert)但读的人多(select),即使 Database 有下 index,但每一个人都去 select 也会大幅降低效能。

快取 (Cache) 设计模式

  1. Cache Aside

    Cache aside
    Cache aside

    Read:优先从 Cache 读,Cache miss 则从 Database 读资料,并写入 Cache,适合读多的情境

    Write:把资料直接写入 Database,成功后将 Cache 对应的 key 值设为失效。 (不直接写入 Cache 是为了避免并发问题。)

    注意:还是会有并发问题,一个要读、另一个要写时,Cache 很有可能因此存在脏资料。

  2. Read/Write Through

    Cache 作为 Application 与 Database 之间的桥梁,适合写少读多的情境,机制如下:

    Read Through, Write Through
    Read Through, Write Through

    Read through: 若 Cache hit 在 Cache 里则直接回传,否则从 Database 读取并同时更新 Cache。

    Write Through: 直接将资料写入 Cache 以及 Database。

  3. Write behind Cache

    Write behind
    Write behind

    写操作会直接写入 Cache,而可依据不同策略决定写回 Database 的时机,相比于 Write Through 的同步机制,这里采取非同步的机制,适合写入多的情境。但要注意若机器当机或 Thread 挂掉,则很有可能丢失资料。

快取 (Cache) 可能的问题

Cache penetration

Cache 并无作用,因此系统依旧还是要去找 Database ,具体可分为以下两种情境

  1. Database 本来就没有这笔资料:照理来说这样发生的请求量应该不大,但如果被恶意攻击,有可能拖慢整个系统,解法可以是:

    • 当搜寻的 Key 重复率较高时:把相对应个 Key 值给一个 default,这样下次再被存取时就回传空值。

    • 当搜寻的 Key 重复率较低时:利用 Bloom filter(类似 hbase 判断 key 否存在),若存在则去 Cache 或 Database 拿,反之则 return null。

  2. 缓存资料需耗费大量资源与时间:没办法把所有商品全部存到 Cache 里,因此会需要分页存,因此有可能在访问时 Cache 会失效,进而 Cache 无法起到作用。

Cache avalanche

若 Key 全部都设同一个 Expire time,则当时间到会同时全部失效,此时会全部像 Database 索取资料,Database 会瞬间压力过大,解决方法是利用一定区间的随机值当来当作 Expire time。

Cache breakdown

Cache 失效后引起系统效能急遽下降的情况。例如当 key 值过期后,需要重新和 Database 拿资料,但是在拿资料的过程需要时间,若此时同时有大量访问需求进来,全部都去 Database 拿资料就会造成问题,因此解法有两种:

  • 更新锁:保证只有一个线程可以去更新缓存,其他线程则等待,不过当采分布式集群系统时,多个机器间也会产生缓存雪崩的问题,因此需要用到分布式锁:Zookeeper

  • 后台更新:由后台线程来更新缓存而非业务线程,具体会将 key 的期限设为永久,并且由后台线程定期清扫。但是当 cache 满了时就会遇到问题,可能解法为:业务 thread 发现 cache 失效后,通过 message queue 发送一条消息通知后台 thread 更新 cache;或者后台 thread 依据对业务的了解,对于 Key 做定期清洗。

Hotspot cache

虽然 Cache 系统本身的性能比较高,但对于一些特别热点的数据,如果大部分甚至所有的业务请求都命中同一份 Cache 数据,则这份数据所在的 Cache server 的压力也很大,解决方法是,复制多份 Cache 副本到多个 Cache server ,减轻 Hotspot cache 导致的单台 Cache server 压力。

注意:不同的 Cache 副本不要设置统一的过期时间,不然同时失效后可能引发 Cache avalanche。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們