8.6 同步操作(sync)
最后更新于
最后更新于
我们还有一个问题,是否可能基于这些保证实现合理的编程?总的来说,Zookeeper的一致性保证没有线性一致那么好。尽管它们有一些难以理解,并且需要一些额外共识,例如,读请求可能会返回旧数据,而这在一个线性一致系统不可能发生,但是,这些保证已经足够好了,好到可以用来直观解释很多基于Zookeeper的系统。接下来,我会尝试构建一些例子来解释,为什么Zookeeper不是一个坏的编程模型?
其中一个原因是,有一个弥补(非严格线性一致)的方法。
Zookeeper有一个操作类型是sync,它本质上就是一个写请求。假设我知道你最近写了一些数据,并且我想读出你写入的数据,所以现在的场景是,我想读出Zookeeper中最新的数据。这个时候,我可以发送一个sync请求,它的效果相当于一个写请求,
所以它最终会出现在所有副本的Log中,尽管我只关心与我交互的副本,因为我需要从那个副本读出数据。接下来,在发送读请求时,我(客户端)告诉副本,在看到我上一次sync请求之前,不要返回我的读请求。
如果这里把sync看成是一个写请求,这里实际上符合了FIFO客户端请求序列,因为读请求必须至少要看到同一个客户端前一个写请求对应的状态。所以,如果我发送了一个sync请求之后,又发送了一个读请求。Zookeeper必须要向我返回至少是我发送的sync请求对应的状态。
不管怎么样,如果我需要读最新的数据,我需要发送一个sync请求,之后再发送读请求。这个读请求可以保证看到sync对应的状态,所以可以合理的认为是最新的。但是同时也要认识到,这是一个代价很高的操作,因为我们现在将一个廉价的读操作转换成了一个耗费Leader时间的sync操作。所以,如果不是必须的,那还是不要这么做。