场景
有一个变量v,分布在N个进程中,每个进程都尝试修改自身v的值,它们的企图可能各不相同,例如进程A尝试另v=a,进程B尝试另v=b,但最终所有的进程会对v就某个值达成一致,即上述例子中如果v=a是v达成一致时的值,那么B上,最终v也会为a。
需要注意的是某个时刻达成一致并不等价于该时刻所有进程的本地的v值都相同,有一个原因是进程可能挂掉,你不能要求挂掉的进程任何事;
更像是最终所有存活的进程本地v的值都会相同。
一致性的三个要求
- v达成一致时的值是由某个进程提出的。这是为了防止像这样的作弊方式:无论如何,最终都令每个进程的v为同一个预先设置好的值,例如都令v=2,那么这样的一致也太容易了,也没有任何实际意义。
- 一旦v就某个值达成了一致,那么v不能对另一个值再次达成一致。这个要求称为安全性。
- 一致总是能够达成,即v总会被决定为某个值。这是因为不想无休止的等待,这个要求也称为活性。
Paxos和分布式存储系统
Paxos用来确定一个不可变变量的取值
- 取值可以是任意二进制数据
- 一旦确定将不再更改,并且可以被获取到(不可变性 & 可读性)
在分布式存储系统中应用Paxos
- 数据本身可变,采用多副本进行存储
- 需要确保多个副本的更新操作序列[Op1, Op2, …, Opn]是相同的 & 不变的
- 用Paxos依次来确定不可变变量Opi的取值(即第i个操作时什么)
- 每确定完Opi之后,让每个数据副本执行Opi,依次类推
Google的Chubby & Megastore & Spanner都采用了Paxos来对数据副本的更新序列达成一致
Paxos希望解决的一致性问题
设计一个系统,来存储名称为var的变量
- 系统内部由多个Acceptor组成,负责存储和管理var变量。
- 外部有多个proposer机器任意并发调用API,向系统提交不同的var取值
- var的取值可以时任意二进制数据
- 系统对外的API库接口为:
propose(var, V) => <ok, f> or <error>
系统需要保证var的取值满足一致性
- 如果var的取值没有确定,则var的取值为null
- 一旦var的取值被