17

“一致性”是镜花水月

 4 years ago
source link: http://www.ideawu.net/blog/archives/1108.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

分布式系统要达到强一致性(一致性), 所有的实现算法最终都是基于 W+R > N , 例如将 W 和 R 设置成多数派(后面按这个设置讨论), 即 N/2+1 . 具体是指:

1. 尝试写全部节点, 如果写了 W 个节点就算是写成功.

2. 同样, 读的时候读全部节点, 如果 R 个节点达到一致(注意, 不是读多数派, 而是多数派达成共识).

3. 最后, 也是最重要的, 如果无法满足前面两个条件, 必须强制将系统设置为"不可用"状态.

最后一项条件非常重要, 如果不强制将系统设置为不可用, 将违反一致性原则.

工程实践上极度厌恶"不可用", 追求的是"高可用", 所以, 最后一项很少有人能完全坚持. 这也是各种分布式系统优化的基础. 大部分的工程都是对读操作的优化, 不要求读操作达到多数派, 从而避免去执行第 3 项.

例如, 系统可以只读取唯一个节点, 返回该节点的数据即可. 这样做有工程上的价值. 如果某个节点故障, 换另一个节点继续尝试(例如一致性 hash).

更进一步(更接近强一致性, 但仍然不是)的做法, 可以读取多数节点, 但不要求多数节点达成共识, 只返回多数节点之中最新版本的数据.

这些对于读操作的优化, 都只能达到数据本身的"最终一致性", 从用户的观察角度看, 系统的状态在某个时间段是飘忽不定的(不一致). 无论你是否愿意承认, 只要你违反了 3 项原则中的任何一项, 你的系统就不是强一致性的. 不管你借鉴了 Paxos 还是 Raft. Raft 比较特殊一点, 把 Leader 当作存储共识的单点, 只需要查询 Leader 就能知道是否达成共识, 写或者读.

强一致性既然那么难, 所以工程不太可能会去实现强一致性的系统. 正如前面所说, 大部分都对读操作进行了简化(优化). 那么, 写操作还是强一致的吗? 答案是否定的. 一旦读不是强一致性的, 写便不再是强一致性的. 一致性是对整个系统而言.

那么, 很多借鉴了 Paxos 或者 Raft 的写流程的系统, 它们在做什么? 其实, 大部分只是利用了多数派顺序写特性. 多数派(多副本)是为了达到高可靠性, 顺序写是为了最终一致. 例如 Paxos 的 prepare 阶段就像是在申请全局递增的序号, 而 accept 阶段是拷贝多副本.

是的, 大部分系统最终实现的是高可靠, 高可用, 和最终一致性.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK