最后写入胜利(丢弃并发写入)

简介: 实现最终收敛的一种方案,每个副本总存储最新值,允许覆盖并抛弃旧值。假定每个写请求都最终同步到所有副本,只要确定哪个写入是最新,则副本就能最终收敛到相同值。

实现最终收敛的一种方案,每个副本总存储最新值,允许覆盖并抛弃旧值。假定每个写请求都最终同步到所有副本,只要确定哪个写入是最新,则副本就能最终收敛到相同值。


但如何定义最新?图-12中,当客户端向数据库节点发送写入请求时,客户端都不知道另一个客户端,因此不清楚哪个先发生。争辩哪个先发生其实没有大意义, 我们说支持写入并发,也就意味着它们的顺序不确定。


即使无法确定写请求的“自然顺序”,我们也能强制任意排序。如为每个写请求附加一个时间戳,然后选择最新即最大的时间戳,丢弃较早时间戳的写入。这就是最后写入胜利(LWW, last write wins),Cassandra唯一支持的冲突解决方法。


LWW实现了最终收敛目标,但以牺牲持久性为代价:若同一K有多个并发写,即使它们都给客户端通知成功(因为完成了写入w个副本),但最好也只有一个写入能存活,其他的将被静默丢弃。LWW甚至可能删除那些非并发写。


一些场景如缓存系统,覆盖写是能接受的。若覆盖、丢失数据不可接受,则LWW不是好选择。


要确保LWW安全的唯一方法:只写入一次,然后视为不可变,避免对同一K进行并发更新。如Cassandra推荐使用UUID作为K,这样每个写操作提供一个唯一K。


Happens-before关系和并发“此前发生”的关系和并发

如何判断两个操作是否并发?


案例

如下图,两个写入非并发:A的插入先于B的增量修改,因为B递增的值是基于A插入的值。即B操作建立在A基础上,所以B后发生。B是因果依赖于A

22.png



如下图中的两个写入是并发:每个客户端启动写操作时,并不知道另一个客户端是否也在执行操作同样的K。因此,操作之间不存在因果关系

23.png



若B知道A或依赖A或以某种方式基于A构建,则称操作A在操作B之前发生。在另一个操作之前,是否发生一个操作,是定义并发的关键。也可简单说,若两个操作都不在另一个之前发生,则两个操作是并发的(即,两个操作都不知道另一个)【54】。


因此,两个操作AB,有三种可能性:A在B前发生或B在A前发生或AB并发。我们一个算法告诉我们两个操作是否并发:


若一个操作先于发生另一个操作,则后面的操作可覆盖较早的操作

若这些操作并发,则存在需要解决潜在冲突问题

目录
相关文章
|
6天前
|
前端开发 JavaScript Java
v-for比v-if优先级更高?面试官:回去等通知吧
v-for比v-if优先级更高?面试官:回去等通知吧
|
6天前
|
存储 前端开发
【源码共读】大并发量如何控制并发数
【源码共读】大并发量如何控制并发数
48 0
|
7月前
|
Cloud Native Go
如何处理面试拒绝:失败并不是终点
如何处理面试拒绝:失败并不是终点
51 0
|
10月前
|
安全 Java
面试热点详解 —— 三个线程轮流打印
面试热点详解 —— 三个线程轮流打印
163 0
|
10月前
|
API UED
推特「崩了」:不登录不让看、推文数量严格设上限,马斯克反复横跳
推特「崩了」:不登录不让看、推文数量严格设上限,马斯克反复横跳
444 0
|
测试技术
TPS、并发数与线程数,傻傻分不清楚?
TPS、并发数与线程数,傻傻分不清楚?
253 0
TPS、并发数与线程数,傻傻分不清楚?
震惊!等待时间竟然用for循环!
震惊!等待时间竟然用for循环!
51 0
|
测试技术
软件测试面试题:什么是并发?在lordrunner中,如何进行并发的测试?集合点失败了会怎么样?
软件测试面试题:什么是并发?在lordrunner中,如何进行并发的测试?集合点失败了会怎么样?
171 0
|
监控 Java 数据库
一个线程罢工的诡异事件
线上某个应用里业务逻辑没有执行,导致的结果是数据库里的某些数据没有更新。
|
XML Dubbo 应用服务中间件
我叫你不要重试,你非得重试。这下玩坏了吧? (上)
我叫你不要重试,你非得重试。这下玩坏了吧? (上)
94 0
我叫你不要重试,你非得重试。这下玩坏了吧? (上)