Closed boringhello closed 7 months ago
这是业务需要考虑的问题,jraft本身不会区分某个请求是正常发送还是重试发送。
另外你所举例,不是共识算法讨论的线性一致性场景,这是业务上线性一致性。解释下 (1,1)的场景,是因为客户端1的重试,而重试对于共识算法来说也是一个普通的请求,对于共识算法来说,它是满足线性一致性的。
你说的情况,刨根揭底就是业务需要实现幂等,无非考虑在哪个阶段做。
在执行状态转移时做,就是你说的第一点;
在协商前做,当你收到协商超时的情况时,你应该先查询,未达成共识再考虑重试逻辑。此时的重试,一定是满足你想要的业务上的线性一致性的,因为你的查询也走了jraft。
感谢你的解答,但是这里
你应该先查询,未达成共识再考虑重试逻辑
是说Get查看是不是value等于Put的value吗,这样还是可能出现(1,1),因为Get查询的值已经Put成功, 但是被别的操作(Put x 2)修改了
不是,我说的查询是jraft提供的readIndex方法
对啊,readindex走共识,但是Put x 2已经先共识了
所以你在readIndex时,会发现Put x 2已经先共识了,那么不重试了啊。
还是不太理解,你说的是这个吗:在事先已经知道x为0, 要改为1的情况下,发现变为2是可以不用重试?但是这个可能ABA 破坏这个线性一致性。
网上文章通常有两个处理办法: 1.对于每一个请求都加上一个唯一的序列号的标识, 然后server的状态机会记录之前已经执行过序列号. 当一个请求超时的时候, 默认的client 的逻辑会重试这个逻辑, 在收到重试的逻辑以后, 由于server 的状态机记录了之前已经执行过的序列号信息, 因此不会再次执行这条指令, 而是直接返回给客户端。这个方法个人感觉效率上不是很好,要多持久化操作信息。
所以,我的问题主要是对第二点幂等是否满足线性一致性的疑惑,以及sofa-jraft对超时请求的处理策略。希望大佬能抽空解答一下