延续 (Day 25)
Dynamo-style 资料库允许多个 client 同时写同一个 key 的资料,意味者资料的冲突势必会发生,虽然可以提升成 Read repair (Day 24) 和 hinted handoff (Day 25) 的问题 (也就是当节点挂掉问题来处理),但这冲突追根究底是资料在到达多个节点时的顺序不同,一个简单的例子来说如下图:
如果我们只是简单覆盖资料过去,最後在取得 X 的资料时,每个节点的资料会不一致,为了资料在每个 replica 的 eventual consistency (Day 22),你不能指望资料库像个黑盒子般的解决冲突,现在我们就来看看这其中有什麽黑科技吧!
最後写的是老大!Last write wins (LWW) 这个方法就是只保留 最近 的资料,然後覆写和舍弃旧的资料;这里最有趣的问题是什麽是 最近 ? 你可以选一个最大的 timestamp,你也可以选一个最大的资料版本号,LWW 也是 Cassandra 唯一支援的解冲突演算法。
LWW 是以资料库的耐用性为成本,如果我们有多个并行写入到同一个 key,尽管符合 w 的 quorums 量 (Day 24),但最终只会有一笔资料存活下来,其他的资料会被安静的被干掉。
另外如果遗失资料是不被同意的,LWW 是个很烂的解冲突方法,这时唯一的方法就只能确保每笔资料只会写入一次,然後另资料成为不可变,Cassandra 就使用 UUID 做它的唯一 key。
首先要了解一下什麽是 happens-before relationship 和 concurrency (并发性):
happens-before relationship
以下图为例子来说明,Client B 更新资料时是依赖於 Client A 所新增的值 (value = value + 1
),换句话说 B 的操作一定比 A 之後,也可说 B 是 因果依赖 (causally dependent) 在 A 上。
concurrency
如最上面贴过的图 5-12,Client A 和 B 的操作可视为 concurrent (并行),因为它们俩并不知道另一个 Client 是否有针对同一个 key 做操作,也就没有谁依赖谁的关系了。
一个操作是否在另一个操作之後 是判断是否为并发的关键,所以说 2 个操作 A 和 B 只会有 3 个关系:A 在 B 之前发生、B 在 A 之前发生、或者 A 和 B 为 concurrent (并发),所以我们会需要一个演算法来帮助我们若是 happend-before 关系我们需要覆写旧的值,若是并行则需要解决冲突。
我们就用一个简单化的购物车例子 (replica 只有一份) 来说明演算法怎麽工作吧,请先看下图:
图 5-13 示范了 2 个 client 同时操作购物车时之间的资料依赖关系,一开始的购物车是空的,各步骤的解释如下:
图 5-13 的资料流可以视觉化成下图,自从另一个 Client 在做并行操作後,每一个 client 都没有维持在最新资料,但旧的 version 资料最终还是会被覆写成新的,且没有资料会遗失。
这里要留意的是写入时务必要搭配 version 编号,否则不会覆写任何资料。
这个演算法虽然可以不让资料被舍弃,相对的它会造成 Client 额外的工作,Client 必须做合并的工作,写入冲突在 Day 23 时有介绍过,依不同场景能选择不同方法,最简单的方法就是上面介绍过的 LWW;图 5-13 的购物车例子是使用 union (联集) 方法。
合并的工作是很复杂且容易错误的,需要努力为其设计资料结构执行,有兴趣的可以找书看 “Automatic Conflict Resolution” on page 174 讲 Riak 怎麽为其设计一个资料型态来做合并。
图 5-13 介绍的例子是针对单一 replica,那本章的重点 leaderless replication 呢?
这时我们就需要每个 replica 中的每个 key 都会有自己的 version 编号,这个 version 的集合称为 version vetor ,这个 version vector 会让资料库区分哪些是覆写,哪些是并行来的资料,然後其他的处理概念跟单一 replica 差不多。
终於到总结啦!
Replication 这章首先在讲做分散式资料的原因:Scalability, Fault tolerance/high availability (容错 / 高可用性), Latency 。
最後在讲做 replication 的方式:
Single-leader replication (Day 21, Day 22)
Multi-leader replication (Day 23)
Leaderless replication (Day 24 ~ Day 26)
明天,就会进入了 partition 环节,如何把大的资料集切成小的。
如果用户在登入画面成功登入,则在session创建用户对象及其购物车对象。 若失败则返回登入页面,提...
今天要谈到代理模式,其实跟昨天的装饰器模式很类似。代理模式的目的在於,因应某些条件替换物件原本的行为...
我拿出手机...安装了自己做的那个『心洞年代』...小七说,它会透过API,自动更新内容,就跟现在的...
今天我们会把Route 53串接到昨天建置的ELB上。但开始之前,我们先问自己一个问题,Route ...
大家安安 晚上好~~ 今天要把专案里的StatelessWidget 更改成为 StatefulWi...