BYTECODES

Zookeeper解析

Zookeeper是优秀的分布式框架之一,值得学习和研究。核心内容可以分以下几部分探讨。

Leader选举

zk为了保证分布式数据一致性,使用ZAB协议。节点有4种状态:LOOKING, LEADING, FOLLOWING, OBSERVING。采用多轮投票,选取获得大多数票的机器id做Leader。

读写流程

读比较简单,zookeeper是可以从各个节点进行读取操作。


写的流程是和raft类似。写节点都是先写入Leader节点,然后leader向follower发起写命令,等待多数follower ACK后,发起commit,成功后返回客户端。

一致性保证

zk没有提供强一致性保证(No Linearizability),但提供了一些一致性保证

  1. 写操作是linearizable

  2. 一个客户端的读写操作是linearizable(FIFO client order),意思是客户端写的时候遵循1的规则,但如果客户端发起一系列读操作,zk能保证后续读不会读到过去的状态。如果一个客户端先发起一个写操作,然后又发起一个读操作,那么zk保证这个客户会读到刚才写入的最新值。

应用场景

可用于配置文件、TEST AND SET服务、分布式锁,或者Leader选举等场景。

  1. 配置文件:

    // client 1
    delete(f1)
    write(xxx)
    ...
    create(f1)
    
    // client 2
    exists(f1, watch=true)
    read(xxx)
    ...
  2. mini transaction

    while (true)
        x,v = GETDATA("f1") // v is version
        if SETDATA("f1", x+1, v)
            break;
  3. 分布式锁

    // version 1
    // 获取锁
    while true:
        if create(f1, ephemeral = true)
            return
        if exists(f1, watch=true)
            wait;
    
    // version 2
    create(sequential file "f", ephemeral = true)
    while true:
        list "f*" files
        if no lower number of file:
            return // 获得锁
        if exists(next number of file, watch=True):
            wait

用zookeeper实现分布式锁的问题是,客户端并不能实现原子性,当客户端和zk失去联系时,就丢失锁的保护,这种情景下需要客户端自行处理数据恢复。