大数据查重去重方案及性能优化

本文探讨了解决网络抖动导致重复请求问题的四种方法:token机制通过生成唯一token保证请求幂等性;去重表利用唯一索引避免多次执行;Redis SETNX利用原子操作确保请求唯一性;状态机更新策略保证数据一致性。
摘要由CSDN通过智能技术生成

案例

我们简单的举个例子,现在有一个接口,提供了转账的功能,a要给b转账1000元,正常情况下我们接口一次性就调用成功了,但是却因为网络抖动等其它原因没有成功,于是就开始不停的重试,突然网络好了,但是这时却连续发出去了三个请求,但是这个接口没有保证幂等性,于是从结果上来看就是a给b转了3000元,这显然是程序业务逻辑上不能接受的(其实moon可以当b的)。

2 解决方案

2.1 token机制

token机制其实是比较简单的,我们先来简单的说一下流程。

首先客户端先请求服务端,服务端生成token,每次请求生成的都是一个新的token(这个token一定要设置超时时间),将token存入redis当中,然后将token返回给客户端。

客户端携带刚刚返回的token请求服务端做业务请求。

服务端收到请求,做判断。

如果token在redis中,则直接删除该token,然后继续做业务请求。

如果token不在redis中,代表已经执行过当前业务了,则不执行业务。
在这里插入图片描述
token机制实现方式还是比较简单的,但是其实对于我们某些响应速度要求很高的业务不太友好,缺点就是需要多一次请求获取token的过程。

正常来说是每次请都会生成一个新的token,如果有极限情况下,有两个请求都带着相同的token进来,会存在都走入判断是否存在的过程,可能都会同时查到存在,这样也会有问题,针对这种情况,我们可以在删除前判断下是否存在,存在就删除,为了保证原子性,这部分逻辑建议使用lua脚本完成。

2.2 去重表

去重表的机制是根据mysql唯一索引的特性来的,我们先来说下它的流程:

首先客户端先请求服务端,服务端先将这次的请求信息存入一张mysql的去重表中,这张表要根据这次请求的其中某个特殊字段建立唯一索引,或者主键索引。

判断是否插入成功

如果插入成功,则继续做后续业务请求。

如果插入失败,则代表已经执行过当前请求
在这里插入图片描述

去重表机制的问题有两点:

1.mysql容错性,也就是mysql本身如果不是高可用的那么业务可能会受到影响:

2.既然是唯一索引,自然在写表的时候就没有办法用到changbuffer,每次都要从磁盘查出来判断再写入,对于一个高并发的接口来说,这些都是需要考虑的因素。

2.3 redis 的 SETNX键值

首先客户端先请求服务端,服务端将能代表这次请求业务的唯一字段以 SETNX 的方式存入redis,并设置超时时间,超时时间可以根据业务权衡。

判断是否插入成功

如果插入成功,则继续做后续业务请求。

如果插入失败,则代表已经执行过当前请求。

这里我们是利用了redis setnx 的特性来完成的。

setnx:只在键key不存在的情况下,将键key的值设置为value。若键key已经存在,则SETNX命令不做任何动作。命令在设置成功时返回1,设置失败时返回0。
在这里插入图片描述
在这里插入图片描述

2.4 状态机幂

UPDATE … SET … version=(version+1) WHERE … AND version=version;
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值