专栏首页微观技术如何用好缓存?全面梳理(第二篇)

如何用好缓存?全面梳理(第二篇)

既然本地缓存有这么多的不足,那能不能把缓存独立出来呢?统一化管理。分布式缓存借助分布式的理念,采用集群化部署,突破单机的容量限制,理论上支持无限扩容。如果数据更新了,只需要调整对应的数据节点分片,不像本地缓存那样,要同时维护很多套副本数据,数据的一致性维护成本比较低。并且容易配备很多服务治理工具,提升系统的高可用、稳定性。支持独立运维。做到专业的人做专业的事。

任何事情都有其两面性,将缓存从应用服务器中剥离出来。需要跨服务器走网络传输。所以分布式缓存的不足:网络传输带来的性能损耗

网络传输的损耗 ~1ms。比起优点,这点损耗微不足道。

旁路缓存策略。可能存在极低概率并发问题!一种场景。

两个线程并发写:A、B线程。变更数据库和变更缓存是两个独立的操作,而我们并没有对操作做任何的并发控制。那么当两个线程并发更新它们的时候,就会因为写入顺序的不同造成数据的不一致。解决:更新数据时不更新缓存,而是删除缓存中的数据。在读取数据时,来触发预热填充。

可以采用类似于juc中的ReadWriteLock,读写锁来控制并发,但是性能会比较差。最好的方式还是设置缓存的过期时间。

Cache Aside 策略是我们日常开发中最经常使用的缓存策略,不过我们在使用时也要根据实际场景,灵活应变。

Cache Aside 维护两套数据存储:缓存、数据库。需要上层控制一致性。

我们经常使用的分布式缓存组件, Memcached 、 Redis 都不提供写入数据库,或者自动加载数据库中的数据的功能。

本地缓存,大量使用这种策略,如:Guava Cache 中的 Loading Cache,预留扩展接口,我们只需要实现CacheLoader接口,如果缓冲没有该数据kv对,则自动调用接口方法获取。

Write Through 策略中写数据库是同步的,对于性能有比较大的开销。

操作系统层面的page cache就是采用这种思想。就是操作系统在内存中给磁盘上的文件建立的缓存。在调用系统的 API 读写文件的时候,并不会直接去读写磁盘上的文件,应用程序实际操作的都是 PageCache,也就是文件在内存中缓存的副本。

Kafka 的吞吐量很高,具体原因?

  • 使用批量消息提升服务端处理能力
  • 使用顺序读写提升磁盘 IO 性能
  • ZeroCopy:零拷贝技术
  • 就是利用了 PageCache 的特性。一般来说,消息刚刚写入到MQ server端就会被消费,按照 LRU 的“优先清除最近最少使用的页”这种策略,消费端拉取消息时,对于这种刚刚写入的 PageCache,命中的几率会非常高。也就是说,大部分情况下,consumer端拉取消息都会命中 PageCache,带来的好处有两个:一个是读取的速度会非常快,另外一个是,给写入消息让出磁盘的 IO 资源,间接也提升了写入的性能。

业务:计数器、扣减库存,也可以考虑使用这种策略,多次请求合并。

有 Cache 的地方就必然存在失效问题。保证数据的一致性。

单一的缓存节点受到机器内存、网卡带宽和单节点请求量的限制,不能承担比较高的并发,因此我们考虑将数据分片,每个节点上存储部分数据。客户端按一定的路由策略将请求打到不同的数据节点上。

1、余数hash分片。对缓存的key做哈希计算,然后对总的缓存节点数取余,得到目标分片节点。属于最常规的路由策略。缺点:如果缓存空间不足,要扩容或者缩容,会造成大量的缓存key失效。

2、一致性哈希算法。将整个 Hash 值空间组织成一个虚拟的圆环,然后将缓存节点的 IP 地址或者主机名做 Hash 取值后,放置在这个圆环上。当我们要计算某一个 Key 需要路由到哪个节点上的时候,先对这个 Key 做同样的 Hash 取值,确定在环上的位置,然后按照顺时针方向在环上查找,遇到的第一个缓存节点就是要访问的节点。在增加和删除节点时,只有少量的 Key 会“漂移”到其它节点上,大部分的 Key 命中的节点还是会保持不变。可以有效解决因扩容问题带来的大量的缓存失效。

缺点:缓存节点在圆环上分布不平均,会造成部分缓存节点的压力较大;当某个节点故障时,这个节点所要承担的所有访问都会被顺移到另一个节点上,会对后面这个节点造成压力,如果流量水位较高时,很容易压垮,进而引发连锁反应,集群挂掉。

3、一致性哈希改进。它将一个缓存节点计算多个 Hash 值分散到圆环的不同位置,这样实现了数据的平均,而且当某一个节点故障或者退出的时候,它原先承担的 Key 将以更加平均的方式分配到其他节点上。

4、区间算法。Redis cluster,哈希槽,16384,3个节点,(0, 5500)(5501, 11000)(11001,16383),HASH_SLOT = CRC16(key) mod 16384

缓存适用的业务场景非常多,这里简单罗列了一些。

全文共三篇,未完待续。。。

本文分享自微信公众号 - 微观技术(weiguanjishu),作者:TomGE

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何用好缓存?全面梳理(第一篇)

    我们做为研发同学,经常会接到各种需求或项目,除了保证业务功能实现外,还会关注一个重要的指标,就是系统性能。如果一个系统发布上线后,扛不住一定的流量,很难得到客户...

    用户7676729
  • 如何用好缓存?全面梳理(第三篇)

    讲了这么多,那我们在使用缓存有没有要注意的问题,有没有什么潜在的坑。我们来看几个问题案例。

    用户7676729
  • 使用缓存必须注意的事项

    关系型数据库在TPS上的瓶颈往往会比其他瓶颈更容易暴露出来,尤其对于大型web系统,由于每天大量的并发访问,对数据库的读写性能要求非常高;而传统的关系型数据库的...

    用户7676729
  • Django实现内容缓存实例方法

    在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.

    砸漏
  • Redis6 最重要的新功能「客户端缓存」是个什么鬼?

    应用缓存通常分两种,本地缓存和远程缓存。本地缓存就是内存缓存 LocalCache,远程缓存就是分布式共享缓存比如 Redis。本地缓存在访问性能上远胜过远程缓...

    老钱
  • ASP.NET 缓存(3)

    有2种方式来实现缓存部分页。 片段缓存:这种情况下,你把确定要缓存的内容,包裹在一个专用的用户控件里,然后只需要对这个控件做输出缓存就行。 post-c...

    py3study
  • ASP.NET MVC编程——缓存

    Web缓存分为服务端缓存和客户端缓存。 1 服务端缓存 1.1请求域内的缓存:HttpContext.Items 类型: HttpContext.Items的类...

    甜橙很酸
  • 细说shiro之七:缓存

    Shiro作为一个开源的权限框架,其组件化的设计思想使得开发者可以根据具体业务场景灵活地实现权限管理方案,权限粒度的控制非常方便。 首先,我们来看看Shiro...

    2Simple
  • 性能设计 - 缓存

    基本上来说,在分布式系统中最耗性能的地方就是最后端的数据库了。一般来说,只要小心维护好,数据库四种操作(select、update、insert 和 delet...

    JAVA日知录
  • 你不知道的小程序缓存?

    说起小程序缓存,大家是不是都清楚怎么使用缓存?今天连胜老师给大家分享一下小程序缓存的知识~

    连胜

扫码关注云+社区

领取腾讯云代金券