首页 > 其他分享 >面试官:如何保证本地缓存的一致性?

面试官:如何保证本地缓存的一致性?

时间:2024-01-20 22:32:01浏览次数:27  
标签:面试官 缓存 自动更新 配置 本地 一致性 数据

有人可能看到“本地缓存”这四个字就会觉得不屑,“哼,现在谁还用本地缓存?直接用分布式缓存不就完了嘛”。

然而,这就像你有一辆超级豪华的房车一样,虽然它空间很大,设备很全,但你去市中心的时候,依然会开小轿车一样,为啥?好停车啊!所以,不同的缓存类型是有不同得使用场景的。

并且,为了防止缓存雪崩问题、缓存击穿问题,我们通常会采用多级缓存的解决方案,所谓的多级缓存就是:分布式缓存(Redis 或 Memcached)+本地缓存(Guava Cache 或 Caffeine)。因为分布式缓存可能会失效、可能会挂掉,所以为了系统的稳定性,多级缓存策略使用的非常广泛。

那么,问题来了,怎么保证本地缓存的一致性?

所谓的一致性是指在同时使用缓存和数据库的场景下,要确保数据在缓存与数据库中的更新操作保持同步。也就是当对数据进行修改时,无论是先修改缓存还是先修改数据库,最终都要保证两者的数据是一样的,不会出现数据不一样的问题。

1.如何保证本地缓存的一致性?

在分布式系统中,使用本地缓存最大的问题就是一致性问题,所谓的一致性问题指的是当数据库发生数据变更时,缓存也要跟着一起变更。而分布式系统中每台机器都有自己的本地缓存,所以想要保证(本地缓存的)一致性是一个比较难的问题,但通过以下手段可以最大程度的保证本地缓存的一致性问题。

① 设置本地缓存短时间内失效

设置本地缓存短时间内失效,短的存活周期,保证了数据的时效性比较高,当数据失效之后,再次访问数据就会拉取新的数据了,这样能尽可能的保证数据的一致性。

它的特点是:代码实现简单,不需要写多余的代码;缺点是,效果不是很明显,不适合高并发的系统。

② 通过配置中心协调和同步

通过微服务中的配置中心(例如 Nacos)来协调,因为所有服务器都会连接到配置中心,所以当数据修改之后,可以修改配置中心的配置,然后配置中心再把配置变更的事件推送给各个服务,各个服务感知到配置中心的配置发生更改之后,再更新自己的本地缓存,这样就实现了本地缓存的数据一致性。

③ 本地缓存自动更新功能

使用本地缓存框架的自动更新功能,例如 Caffeine 中的 refresh 功能来自动刷新缓存,这样就可以设置很短的时间来更新最新的数据,从而也能尽可能的保证数据的一致性,如下代码所示:

// 创建 Caffeine 缓存实例
Cache<String, String> caffeineCache = Caffeine.newBuilder()
// 设置缓存项在 5s 后开始自动更新
.refreshAfterWrite(5, TimeUnit.SECONDS)
// 自定义缓存更新逻辑(即获取新值逻辑)
.build(new CacheLoader<String, String>() {
    @Override
    public void reload(String key, String oldValue) throws Exception {
        // 模拟更新缓存的操作
        updateCache(key, oldValue);
    }
});

2.实际工作中会使用哪种方案?

不同的业务系统,会采用不同的解决方案,例如以下这些场景和对应的解决方案:

  • 如果对数据一致性要求不是很高,并且程序的并发压力不大的情况下,可能使用方案 1,也就是设置本地缓存短时间内失效的解决方案,因为它的实现最简单。
  • 如果对数据的一致性要求极高,且有配置中心的情况下,可使用配置中心协调和同步本地缓存。
  • 相反,如果对一致性要求没有那么高,且为高并发的系统,那么可以采用本地缓存的自动更新功能来实现。

小结

在多级缓存中,本地缓存是不可或缺的组成部分,而想要保证本地缓存的数据一致性,可能采用:设置较短的本地缓存过期时间、通过配置中心来协调和同步本地缓存,以及使用本地缓存框架的自动更新功能保证数据的一致性等解决方案,而不同的业务场景,选择的解决方案也是不同的。

课后思考

通过以上机制,我们就能实现本地缓存的一致性了。那么问题来了,如何实现分布式缓存的数据一致性呢?欢迎评论区留言互动,点赞超过 20,更新下篇文章。


标签:面试官,缓存,自动更新,配置,本地,一致性,数据
From: https://blog.51cto.com/vipstone/9346714

相关文章

  • shiro缓存配置流程
    以前搞shiro的时候没有刻意去研究过这些配置文件,导致用shiro的时候也是迷迷糊糊,惭愧啊,要想成为人上人,读源码,懂配置是真滴重要!安全管理器配置(SecurityManager)配置项意思一setCacheManager配置缓存管理器用来缓存realm和session信息二setRealm登录时假如用的UsernamePasswordToken,......
  • dma 和 cache的一致性
    CPU写内存的时候有两种方式:1.writethrough:CPU直接写内存,不经过cache。2.writeback:CPU只写到cache中。cache的硬件使用LRU算法将cache里面的内容替换到内存。通常是这种方式。 我们假设MEM里面有一块红色的区域,并且CPU读过它,于是红色区域也进CACHE: 但是,假设现在DMA把......
  • 深入剖析MyBatis缓存机制
    第1章:引言大家好,我是小黑。今天我们要聊的是MyBatis的缓存机制。作为Java开发中经常使用的持久层框架,MyBatis以其灵活性和简便性而广受欢迎。但你知道吗,很多时候,正是因为这些特点,我们需要更深入地理解它的内部工作原理,尤其是缓存机制。这不仅能帮助我们更高效地使用MyBatis,还能......
  • 视频直播app源码,利用缓存实现连续登录失败后的时间等待
    实现步骤:1、用户在视频直播app源码中发起登录请求2、后台验证是否失败次数过多,账户没有锁定的话就进入下面的步骤;否则直接返回3、验证用户的账号+密码3.1验证成功:删除缓存3.2验证失败:统计最近10分钟时间窗口内的失败次数,如果达到5次则设置锁定缓存,返回图解实......
  • 记一次缓存失效引发的惨案!
    对于小猫来讲,最近的一段日子是不好过的,纵使听着再有节拍的音乐,也换不起他对生活的热情。由于上一次“幂等事件”躺枪,他已经有几天没有休息好了。他感觉人生到了低谷。当接手这个商城项目之后,他感觉他一直没有好过。他的内心彷徨,在工位上边写着事故报告,边嘀咕着“今年到底是犯了啥......
  • 图像采集和多缓存项目中的若干总结
    遇到的问题:1.图像滚动:原因:没有读出/写入整幅图像导致;2.图像错位:原因:在读出当前帧前,已向fifo里写入了若干数据;(合理的设置hdmi的启动可以解决这个问题);3.图像撕裂:原因:读到了写入区域;缓存多帧数可以解决这个问题;4.缓存后的图像闪动:原因:没有准确的设置启动,导致不合理的地址跳跃;5.6......
  • Redis篇-redis使用场景-缓存-缓存击穿-03
    1缓存击穿缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。1.1解决方案一:互斥锁1.2解决方案二:逻辑过期总结:缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有......
  • Redis篇-redis使用场景-缓存-缓存穿透-02
    问题一:项目中哪些场景使用了redis呢?1缓存穿透缓存穿透:查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。1.1解决方案一方案一:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存;{key:1,value:null}优点:简单;缺点:消耗内存,可能会发......
  • 【算法】【线性表】【链表】LRU 缓存
    1 题目请你设计并实现一个满足  LRU(最近最少使用)缓存 约束的数据结构。实现 LRUCache 类:LRUCache(intcapacity) 以 正整数 作为容量 capacity 初始化LRU缓存intget(intkey) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。voidput......
  • MyBatis三级缓存详解
    MyBatis作为一款优秀的持久层框架,在处理数据库操作时提供了丰富的功能,其中之一就是三级缓存。本篇博文将深入介绍MyBatis的三级缓存,通过详细的例子带你了解三级缓存的使用和原理。背景MyBatis的三级缓存是指在执行SQL语句时,可以将查询的结果缓存在三个不同的范围内,分别是LocalC......