写点什么

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

  • 2023-12-22
    广东
  • 本文字数:1870 字

    阅读完需:约 6 分钟

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

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


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



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

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


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



当用户更新了它的购物车之后,微服务实例 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 到当前时间,周而复始,导致消费组无法老化。举个🌰

假设消费组的老化时间为 4h,消息的老化时间为 3h,就可能会发生这样的事情。


总结


广播模式在微服务架构中起到了重要的角色,尤其是在需要在微服务实例之间同步数据的场景中,它具有显著的优势。它能够帮助维护内存数据的缓存一致性。希望本篇文章能提供您全面的广播模式的知识。


点击关注,第一时间了解华为云新鲜技术~

发布于: 刚刚阅读数: 5
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
微服务广播模式实践:维护内存数据的缓存一致性_微服务_华为云开发者联盟_InfoQ写作社区