许式伟的架构课
许式伟
七牛云 CEO
84945 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 89 讲
许式伟的架构课
15
15
1.0x
00:00/00:00
登录|注册

39 | 存储与缓存

扩容
缓存命中率
集群构成
键值存储
更短的路径
更高速硬件
重试的友好性
持久性问题
定位
一致性问题解决
值不可修改
引入group概念
应对雪崩
雪崩现象
缓存允许数据丢失
缓存是一种存储
memcached
数据结构
加速原理
搜索引擎(Search Engine)
消息队列(MQ)
对象存储(Object Storage)
数据库(Database)
键值存储(KV Storage)
结语
Redis
groupcache
缓存 vs 存储
缓存(Cache)
存储中间件
存储与缓存

该思维导图由 AI 生成,仅供参考

你好,我是七牛云许式伟。
前面接连三讲我们介绍了存储中间件的由来,以及最为常见的存储中间件,如:键值存储(KV Storage)、数据库(Database)、对象存储(Object Storage)。
当然,它们并不是全部。常见的存储中间件还有很多,比如消息队列(MQ)、搜索引擎(Search Engine)等等。
限于篇幅,我们不能一一对它们进行分析。今天,我们聊一聊缓存(Cache)。

memcached

缓存(Cache)是什么?
简单说,缓存是存储(Storage)的加速器。加速的原理通常是这样几种方法:
最常见的是用更高速的硬件来加速。比如,用 SSD 缓存加速 SATA 存储,用内存缓存加速基于外存的存储。
还有一种常见的方法是用更短的路径。比如,假设某个计算 y = F(x) 非常复杂,中间涉及很多步骤,发生了一系列的存储访问请求,但是这个计算经常会被用到,那么我们就可以用一个 x => y 的内存缓存来加速。
可见,缓存的数据结构从实现上来讲只需要是一个键值存储。所以它的接口可以非常简单:
type Cache {
...
}
func (cache *Cache) Get(key []byte) (val []byte, err error)
func (cache *Cache) Set(key, val []byte) (err error)
func (cache *Cache) Delete(key []byte) (err error)
第一个被广泛应用的内存缓存是 memcached。通常,我们会使用多个 memcached 实例构成一个集群,通过 Hash 分片或者 Range 分片将缓存数据分布到这些实例上。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了存储与缓存之间的关系,以及三种不同模型的缓存系统:memcached、groupcache和Redis。缓存被描述为存储系统性能的补丁,虽然并不完美。文章首先介绍了groupcache,它引入了group的概念,允许创建独立的内存缓存集群,解决了memcached存在的一致性缺陷。然后,文章提到Redis,指出它在定位上特别奇怪,既可以作为内存缓存,也可以作为存储。然而,如果将Redis视为存储,就需要考虑持久性和重试的友好性等重要问题。最后,总结指出缓存是存储系统的补丁,虽然不完美,但对服务器性能有所改善。整体而言,本文通过介绍不同的缓存系统,展示了它们在解决存储系统性能问题上的特点和局限性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《许式伟的架构课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(19)

  • 最新
  • 精选
  • Geek_88604f
    对于一个确定的 x 值,如果 F(x) 永远不变,这就没问题。但如果 F(x) 值是不确定的,那就有可能会出现并发的两个 F(x) 请求得到的结果不同,从而导致缓存中的值和存储中的值不一致。 这段描述我是这么理解的,老师的意思是不是两个线程同时去get同一个key,发现key不在缓存中,此时两个线程都会去计算key对应的value,当线程A拿到x完成计算后准备将计算结果刷到缓存(但还未刷新到缓存),线程B拿到了已经改变过的x(如果x表示select某个数据表的返回值,线程c有可能在线程B计算之前改变了x)也计算了值并先于线程A将值刷新到缓存,然后线程A才缓过劲来将它的计算结果刷新到缓存,这样导致的最终结果是缓存和存储中的值不一致。         对于这种情况我觉得可以考虑以下几个方案去改进或规避:(1)考虑缓存的key为空的情况毕竟占少数,因此可以考虑当读取到缓存为空时随机等待几个毫秒的延迟后再次读取,如果key还为空则计算y=f(x)。(2)缓存更新序列化,将y=f(x)的计算从fastf(x)中移除,当缓存没有命中时向消息队列发起异步更新消息,消费者从消息队列中取消息计算f(x)并刷新缓存(如果短时间内有大量的更新消息,可以考虑只处理最新的消息),当然业务侧要做读取缓存的重试。(3)将y=f(x)的计算从fastf(x)中移除,设置缓存不老化,fastf(x)只负责读取数据,当缓存没有命中的时候从存储中读取。由x的变化发起者或者定时任务来计算f(x),当x发生变化的时候完成计算并刷新缓存。

    作者回复: 你的理解是对的,当存在并行的Set请求,自然存在时序问题,导致存储和缓存数据不一致。解决方案来说: 1、sleep不能解决多任务协同问题,所以这个方案不可行。 2、是可行的思路,把 F(x) 和 Set 一起串行执行。不过这会导致在缓存未命中时 F(x) 执行两遍。你说的缓存未命中从存储读,本质上是执行 F(x) 的意思。 3、存储中 x 对应的数据发生变化时,我们通常的做法是把 x 从缓存中清除(Delete),而不是执行 F(x) 和 Set。原因是缓存空间是有限的,所以要给 Get 次数比较多的数据缓存,而不是一发生变更就缓存,这样非常可能反而降低了缓存命中率。

    2019-09-07
    2
    17
  • Dean
    如何理解groupcache值不可变就解决了一致性问题,此时如果存储的值变了,缓存中的相应的计算结果如果不变的话,不是也不一致么?

    作者回复: 你可以这么理解:以键值存储为例,它存储的是 key => (value, ver),而 groupcache 存储的是 (key, ver) => value。这样就可以做到存储的值改变而 groupcache 值不变。只不过怎么用,这个需要好好考虑一下。

    2019-09-16
    2
    9
  • Tachyon
    缓存雪崩并不是说缓存大量宕机,而是大量key几乎同时过期导致请求直接打到后端存储上。

    作者回复: 成因可以多样化,同时过期的效果和宕机显然类似。

    2019-09-20
    6
  • Charles
    所以许老师怎么去评估一个系统是否应该上缓存,假设目前存储都可以顶住负载?谢谢

    作者回复: 要分析清楚压力和和效率瓶颈。压力大了,可以考虑加缓存,当然也可以考虑存储扩容。效率瓶颈,通常只能用缓存解决。

    2019-09-08
    6
  • ecareyu
    讲述人对于专业名词的英文读的我一脸懵逼啊?memcache要是我不看文档都不知道是啥

    作者回复: 嗯,之前讲述人是非科技领域的。我们在重新录音频。

    2020-07-15
  • Geek_88604f
    func FastF(x TypeX) (y TypeY) { key := toBytes(x) hash := hashOf(key) i := hash % countOf(memcaches) val, err := memcaches[i].Get(key) if err != nil { y = F(x) val = toBytes(y) memcaches[i].Set(key, val) } else { y = fromBytes(val) } return } 这段代码第六行判断条件是=还是≠,没太明白整个逻辑。

    作者回复: err != nil 表示失败

    2019-09-06
  • 诗泽
    如果 F(x) 值是不确定的,这种情况下放缓存里也就没意义了吧?

    作者回复: 这里说的不确定不是太准确,正确应该说会改变,有多个版本

    2019-09-06
  • 风清扬
    许老师,缓存血崩的原因是命中率降低,大量请求直达后端,后端性能极速下降导致,解决办法是抛弃过多的请求。想到的一个是应用层既网关层限流。能详细讲解下吗?

    作者回复: 后面还会细聊这些问题

    2019-09-06
  • mickey
    祝许老师以及极客全体老师教师节快乐,工作顺利,身体健康!
    2019-09-10
    4
  • dovefi
    个人总结一下: 缓存的用途: 1、数据缓存 2、计算缓存(还是第一次听到)用户缓存复杂的计算结果
    2020-06-21
    2
收起评论
显示
设置
留言
19
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部