实战并发-使用分布式缓存和有限状态机

简介: 实战并发-使用分布式缓存和有限状态机

简介    


这里的并发不是高并发,只是将正式环境的一小段流量同时打到我的自测环境。一个请求同时多次发送,真正意义上并发处理同一个数据,主要需求是保证数据幂等性和正确性。

主要技术是用分布式缓存做多次相同请求的幂等处理和用有限状态机来解决MQ消息的不保证有序。

 

场景


k8s集群可以进行事件监听,静儿这次使用了一个美团内网线下的小集群。把这个小集群的对node节点和pod节点的监听事件发送到MQ,3台服务器在同时工作。也就是说一个事件会被重复收到三次。其中两台机器事件发送基本上是同时的,剩下一台是我自己的电脑。因为在家里,连着vpn,连接公司内网大概有2.5ms的延时。


在MQ事件的接收端,美团内部监控系统CAT上看到数据如下:


1112728-20190313123821463-1346205467.png


问题



当一个请求被重复在并发和有延迟的情况下会被重复收到。k8s自身也会短时间发送一些相同的请求。这些重复的请求在不考虑重复执行的副作用前提下,每次都同样的方式执行,后端的压力也会非常大。如果考虑重复执行的副作用,就是说重复的请求不幂等,数据不准确了,整个服务就非常糟糕了。


另外,不管是MQ还是k8s事件,接收处理事件的服务都不能保证先收到的事件是先产生的。多台机器的情况下,就算是先产生的,也会因为不同机器的处理速度不一样,导致后产生的事件先被执行。

 

解决


如果下面解决方法中的概念不是很清楚,可以先看5W,再回来看方法。


使用分布式缓存解决请求去重的问题


首先考虑对请求处理的维度。比如静儿举例的场景中,对node节点的watch事件,可以用node作为缓存的key,用node需要处理的关键字段作为value。如果请求中的信息与缓存中的一致,则直接返回不处理。不一致则先更新缓存为最新值,再进行处理。

注意,因为保证消息不会被并发处理。刚才的缓存值获取get和重设put操作都是用分布式锁进行了加锁的。


使用有限状态机解决乱序的问题


之所以有「乱序」这个定义,说明系统本身是消息的顺序是有要求的。顺着这个思路来考虑,可以顺理成章的得到解决方案:设定好原本的一个介绍顺序。如果收到事件A则执行事件B。如果收到事件B则执行事件C。如果没收到事件A先收到了事件B,则把MQ消息打回去重发。在打回去的阶段事件A收到处理完了,这时候再收到事件B就可以继续执行了。


刚才说的这种执行顺序的方法就是有限状态机。有限状态机在程序里的实现主要有两种。一种是通过switch case的方法。就是如果A则B的最容易理解的实现。通常被称为“可执行代码”方式。


另外一种方式是:如果每种状态要做的处理比较复杂。用switch case比较难看。就可以将处理方法抽象成一个类。将这些类的实例放到映射表里。这种实现通常被称为“被动数据”方式。

 

5W


Q:为什么MQ消息不保证有序?


A:因为MQ消息在服务器上是分区存储的,每个分区自己是有序的。分区被接收端消费的时候。一般也是多个接收端一起消费。中间的每个环节都是只能保证局部有序。如果想全局有序。就需要分区只有一个,并且接收端服务器是单点,而且一次只处理一个请求。


Q:MQ的使用上还有什么关键注意点?


A:一般情况下MQ除了不保证消息有序还不保证消息不重复。因为在「网络不可达」的情况下,MQ不能确认消息接收方收到了消息必然会重试。重试除了本文讲的幂等处理外,还可以采用每个消息有唯一的ID+去重表实现。


Q:什么是分布式缓存?


A:分布式缓存有时候也叫「集中式缓存」。是相对于「本地缓存」而言的。因为在目前的多服务器部署(分布式)时代。「本地缓存」这种将信息存储于当前服务器上,其他服务器无法感知。这时候采用一个专门的缓存服务器就可以解决这个问题。这就是分布式缓存了。


Q:什么是有限状态机?


A:有限状态机也称为FSM(Finite State Machine),是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM可以把模型的多状态、多状态建的转换条件解耦。可以使维护变得容易,代码也更加具有可读性。

 

总结


并发问题对系统的影响


系统压力造成的可用性问题、多个请求同时对同一个数据产生作用产生的数据准确性问题。


解决方案


可用性问题可以从设计上在业务逻辑层之前对数据去重,例如可以使用分布式锁,让真正耗时的业务逻辑对相同的多个请求只执行一次。


数据准确性问题可以通过有限状态机保证不论收到请求顺序如何,都按照正确的逻辑来执行。

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
6天前
|
人工智能 数据管理 大数据
探索分布式系统中的数据一致性与并发控制
【2月更文挑战第8天】在当今互联网时代,分布式系统的概念越来越广泛应用于各种应用场景中。本文将深入探讨分布式系统中数据一致性与并发控制的重要性和挑战,介绍常见的解决方案以及未来发展趋势。
|
6天前
|
SQL 算法
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
基于若依的ruoyi-nbcio流程管理系统修改代码生成的sql菜单id修改成递增id(谨慎修改,大并发分布式有弊端)
16 1
|
6天前
|
消息中间件 算法 Java
三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法
年末离职,年初为面试也筹备挺长一段时间,找了不少复习资料,刷了很多题在网上投了很多简历最终面试了有赞,还有幸拿到offer!
|
7月前
|
NoSQL 算法 Redis
Redis学习笔记-并发控制&分布式锁
Redis学习笔记-并发控制&分布式锁
53 0
|
9月前
|
消息中间件 算法 Java
三面“有赞”Java岗斩获offer:Spring+JVM+并发锁+分布式+算法
年末离职,年初为面试也筹备挺长一段时间,找了不少复习资料,刷了很多题在网上投了很多简历最终面试了有赞,还有幸拿到offer!
|
11月前
|
消息中间件 开发框架 NoSQL
【工作中问题解决实践 二】分布式消息并发同步处理方案
【工作中问题解决实践 二】分布式消息并发同步处理方案
86 0
并发场景下的幂等问题——分布式锁详解-附录
并发场景下的幂等问题——分布式锁详解
|
存储 缓存 NoSQL
并发场景下的幂等问题——分布式锁详解
并发场景下的幂等问题——分布式锁详解
121 0
|
Java
ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁
在了解了加锁和锁重入之后,最需要了解的还是在分布式场景下或者多线程并发加锁是如何处理的?
114 0
|
SQL 监控 程序员
学会用数据说话-分布式锁究竟可以多少并发?
学会用数据说话-分布式锁究竟可以多少并发?
学会用数据说话-分布式锁究竟可以多少并发?