首页 > 系统相关 >微服务广播模式实践:维护内存数据的缓存一致性

微服务广播模式实践:维护内存数据的缓存一致性

时间:2023-12-22 10:45:00浏览次数:42  
标签:消费 服务 time 广播 缓存 expiration 老化 一致性 内存

本文分享自华为云社区《微服务广播模式实践》,作者:张俭 。

微服务广播模式,指的是在微服务多实例部署的场景下,将消息广播到多个微服务实例的一种模式。

p1.png

广播模式,一般用来维护微服务的内存数据,根据数据类型的不同,有助于解决两类问题。通常广播模式会使用支持发布订阅的消息中间件实现(如Redis、Kafka、Pulsar等),本文也基于消息中间件进行讨论。

利用广播模式维护一致的缓存

这应该是广播模式利用最多的一种场景,假想一个拥有海量用户的电商网站、或是一个亿级设备连接的IoT平台。势必会存在一些缓存数据,像是用户的购物车信息,或是设备的密钥缓存。如果没有广播模式,可能会存在这样的问题

p2.png

当用户更新了它的购物车之后,微服务实例1的数据发生了更新,数据库的数据也成功更新。但是微服务实例2中的缓存数据未能更新,那么如果用户的请求均衡到了实例2,就会发生意想不到的后果。

这种情况下我们可以让微服务1在广播通道中发送一个缓存的invalidate消息,将微服务实例2中该用户的缓存清零,使得微服务实例2在下一次处理该用户的请求时,从数据库中读取最新的消息。

使用该模式需要注意的点:

  • 每个微服务实例应该使用不同的消费组,可以通过微服务的IP、主机名、UUID等拼装成订阅组名称,这才称得上广播之名
  • 微服务消费消息的时候,应从Latest开始消费,避免从Earliest开始消费无用的缓存清理消息
  • 由于每一次微服务重启都会产生一个新的消费组,需要注意消费组的老化,可以通过消息中间件自带的不活跃消费组老化能力兜底,建议通过gracefulExit、监听kill信号等机制来主动删除消费组信息

为什么说消费组老化比较重要呢,因为很多监控系统都会根据消费组的积压来做告警,很容易产生误告警。

利用广播模式维护内存中的数据

这种模式相对比较少见,常见于key的基数不是很大,能够将数据完整地存储在内存中,比如电商平台的企业卖家个数、物联网平台的用户个数等,并且对数据的一致性要求不是很高(因为广播模式情况下,对于两个微服务实例来说没有一致性保障)。像Apache Pulsar设计的TableView,在我看来,就是做这个事的一个最佳实践。Pulsar内部大量使用了topic存储数据,就是采用这个方式。

使用该模式需要注意的点:

  • 同上,需要使用不同的消费组名称
  • 微服务消费消息的时候,应该从Earliest开始消费,保证所有微服务内存中的消息视图一致
  • 同上,需要注意消费组的老化

为什么需要消费组老化作为保底手段

因为在极端场景下,无论是graceful的代码,还是监听kill信号的代码,都不能保证代码百分百地被执行。需要兜底。

Kafka消费组老化

Kafka通过offsets.retention.minutes参数控制消费组中offsets保留时间,在此时间内如果没有提交offset,offsets将会被删除。Kafka判定消息组中没有在线的消费者(如empty状态),且没有offsets时,将会删除此消费组。

Pulsar消费组老化

pulsar的消费组老化策略更加灵活,可以配置到namespace级别。

bin/pulsar-admin namespaces | grep expiration
    get-subscription-expiration-time      Get subscription expiration time for 
      Usage: get-subscription-expiration-time [options] tenant/namespace
    set-subscription-expiration-time      Set subscription expiration time for 
      Usage: set-subscription-expiration-time [options] tenant/namespace
            Subscription expiration time in minutes
    remove-subscription-expiration-time      Remove subscription expiration 
      Usage: remove-subscription-expiration-time [options] tenant/namespace

这里注意要合理地配置消费组的老化时间,在pulsar的当前版本(2.11版本)下,catch up读,也就是说消费组平时积压量不大。如果将消费组的老化时间配置大于等于消息的老化时间,会出现消费组老化不了的现象。

当然,由于消费组和消息老化都是定时任务,预估时间时,要考虑一定的buffer。

这里让我们稍稍dive一下原理,消费组的老化是通过判断Cursor游标的LastActive time来判断能否老化的。如果该消费组的游标位置到达了消息老化区域,被老化掉了,消费组的游标位置就会强制更新到一个可用的位置,这个时候会更新游标的LastActive time到当前时间,周而复始,导致消费组无法老化。举个

标签:消费,服务,time,广播,缓存,expiration,老化,一致性,内存
From: https://www.cnblogs.com/huaweiyun/p/17920777.html

相关文章

  • Guava自加载缓存LoadingCache使用指南
    第1章:引言大家好,我是小黑,今天我们来聊聊缓存。在Java世界里,高效的缓存机制对于提升应用性能、降低数据库负担至关重要。想象一下,如果每次数据请求都要跑到数据库里取,那服务器岂不是要累趴了?这时候,缓存就显得尤为重要了。那么,怎么实现一个既高效又好用的缓存呢?别急,咱们今天的主......
  • JVM内存参数的学习之三
    JVM内存参数的学习之三背景研究启动性能时,顺便看到了jmap-heap1的部分信息看到:MinHeapFreeRatio、MaxHeapFreeRatio自己突然以为是Percentage的参数,恍惚了好久.才发现自己对内存的学习不够,所以想多学习一下.参数解释MinHeapFreeRatio:空闲堆空间的最小......
  • ThreadLocal的内存泄露?什么原因?如何避免?
    前言在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露、强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这样情况发生,增强系统的健壮性。内存泄露内存泄露为程序在申请内存后,无法释放已申请的内存空间,一......
  • 分布式缓存NewLife.Redis
    NewLife.Redis 是一个Redis客户端组件,以高性能处理大数据实时计算为目标。Redis协议基础实现位于Redis/RedisClient,FullRedis为扩展实现,主要增加列表结构、哈希结构、队列等高级功能。源码: https://github.com/NewLifeX/NewLife.RedisNuget:NewLife.Redis/NewLife.Extens......
  • c# 32位程序突破2G内存限制
    起因在开发过程中,由于某些COM组件只能在32位程序下运行,程序不得不在X86平台下生成。而X86的32位程序默认内存大小被限制在2G。由于程序中可能存在大数量处理,期间对象若没有及时释放或则回收,内存占用达到了1.2G左右,就会引发异常“内存溢出”。环境:VisualStudio2022问题复现 ......
  • 来领奖了,InfiniCloud网盘又能领取内存了
    1缘由今天登录自己的邮箱,整理相关的邮件的时候,突然发现有来自于infiniCloud的邮件,阅读邮件竟然发现了一个惊喜,为庆祝HappyHolidays!,用户就是能领取3GB的储存空间,有效期是一年的时间,对于免费用户来说这就很不错了。#HappyHolidays!ClickbelowforaholidaybonusfromI......
  • 《Java架构师的第一性原理》32分布式计算之分布式缓存第3篇LevelDB
    互联网业务,绝大部分场景,会使用缓存服务。但有时候,确实会使用到进程内存缓存/数据库,这个时候,LevelDB就能派上用场了。啥是LevelDB?LevelDB是Google开发的,一个速度非常块的KV存储库(storagelibrary),它支持字符串的key与字符串的value,并且这种映射关系按key排序(orderedmapping)。L......
  • 《Java架构师的第一性原理》32分布式计算之分布式缓存第1篇如何使用Redis搭建玩家排行
    今天我们用Redis搭建一个玩家的排行榜,假设一个服务器存储了10万名玩家的数据,我们想给这个区(这台服务器)上的玩家做个全区的排名,该如何用Redis实现呢?不妨一起来思考下面几个问题:MySQL是如何实现玩家排行榜的?有哪些难题需要解决?如何用Redis模拟10万名玩家数据?Redis里......
  • 如何正确使用缓存来提升系统性能
    文章目录引言什么时候适合加缓存?示例1示例2:示例3:缓存应该怎么配置?数据分布**缓存容量大小:**数据淘汰策略缓存的副作用总结引言  在上一篇文章IO密集型服务提升性能的三种方法中,我们提到了三种优化IO密集型系统的方法,其中添加缓存(cache)的方法是最常用的,而且普适性也是最强的,今......
  • SpringBoot集成Memcached实现高效缓存
    一、前言Memcached是一款高性能的分布式内存对象缓存系统,可以用来缓存SQL查询结果、API调试结果等。使用Memcached可以减少对数据库的查询次数,提高系统性能。它主要用于减轻数据库负载,提供应用系统,减少数据库压力。SpringBoot可以快速集成Memcached实现对缓存到读写操作。二、安装......