ZooKeeper version: 3.6.0

The installation

This example is performed under CentOS Linux Release 8.1.1911 (Core)

Ensure that the current machine has a Java environment. For details about how to install Java, see the following section

1. Download

First go to Apache Download to find the appropriate version, in this case 3.6.0, to Download

Wget HTTP: / / https://downloads.apache.org/zookeeper/current/apache-zookeeper-3.6.0-bin.tar.gzCopy the code

2. Unzip

Tar XVF - apache - they are - 3.6.0 - bin. Tar. GzCopy the code

3. Start the standalone version

As shown in the figure, after decompressing, I renamed the long directory name to Zk1 and cp zk2 and zk3, cp zoo_sample. CFG to zoo.cfg

#Modify the nameMv apache - they are - 3.6.0 - bin zk1#Cp two copies to prepare for the pseudo-cluster construction
cp -r zk1 zk2 
cp -r zk1 zk3
#Added zoo. CFG configuration
cd zk1 &&  cp conf/zoo_sample.cfg zoo.cfg
Copy the code

I didn’t change anything here, just start

./bin/zkServer.sh start /usr/bin/java ZooKeeper JMX enabled by default Using config: /home/dylan/tmp/zookeeper/zk1/bin/.. /conf/zoo.cfg Starting zookeeper ... STARTEDCopy the code

As you can see, Zk1 has started. Let’s verify:

./bin/zkServer.sh status /usr/bin/java ZooKeeper JMX enabled by default Using config: /home/dylan/tmp/zookeeper/zk1/bin/.. /conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: standaloneCopy the code

Zkserver. sh status shows that zK has started normally. The Mode is standalone. When the ensemble is configured, the Mode changes to Leader/Follower/Observer

4. Single machine pseudo cluster version

/ TMP /zk1 = / TMP /zk1 = / TMP /zk1 = / TMP /zk1 = / TMP /zk1 = / TMP /zk1 echo 1 > /tmp/zk1/myid

4.1 The four configurations are as follows:

The configuration items are as follows:

  • TickTime: tickTime(milliseconds) : tickTime(default)

  • InitLimit: maximum duration for connecting the Follower/Observer (server) to the Leader during ensemble initialization. If the connection fails after this duration, the connection fails. For followers, it is the time to connect and synchronize to the Leader. If the ZooKeeper cluster manages a large amount of data, increase the value as required

  • SyncLimit: Synchronizes time. If the Follower does not complete synchronization within the syncLimit time, the Follower is discarded by the Leader

  • DataDir: the place where zk is used to store data, and where myID files are also stored. Zk officially recommends that this directory be a directory specifically for ZK transaction logs:

To get low latencies on updates it is important to have a dedicated transaction log directory. By default transaction logs are put in the same directory as the data snapshots and myid file. The dataLogDir parameters indicates a different directory to use for the transaction logs.

  • ClientPort: port used to listen on client connections. If your client is not using this port, you need to change this. This is a different port because it’s on the same machine

  • PeerType: The server with peerType= Observer configured will become an Observer. In this example, ZK4 will become an observer

  • ObserverMasterPort: By default, the Observer obtains a new proposal from the Leader. After this configuration is enabled, the Observer obtains the proposal from the followers. Followers will listen on the port. The advantage of this is that it can reduce the pressure on the Leader. The value I configured above is different because I am on a single machine. If the configuration is the same, there will be port conflict. In fact, it should be the same port.

By default, Observers connect to the Leader of the quorum along its quorum port and this is how they learn of all new proposals on the ensemble. There are benefits to allowing Observers to connect to the Followers instead as a means of plugging into the commit stream in place of connecting to the Leader. It shifts the burden of supporting Observers off the Leader and allow it to focus on coordinating the commit of writes. This means better performance when the Leader is under high load, particularly high network load such as can happen after a leader election when many Learners need to sync. It reduces the total network connections maintained on the Leader when there are a high number of observers. Activating Followers to support Observers allow the overall number of Observers to scale into the hundreds. On the other end, Observer availability is improved since it will take shorter time for a high number of Observers to finish syncing and start serving client traffic.

  • Server. 1 = 127.0.0.1:2284-3884: the observer: for the convenience of introduction so we have to rewrite it into the following form:
    • For server myid = net: port1, port2: the observer, then
    • Myid: specifies the myID, which needs to be specified under the server dataDirmyidThe values in the file remain the same (this file needs to be created manually)
    • Net: host of the server
    • Port1: used for TCP communication from peer to peer. Peer is a ZK server. And communication with the Leader. This port, in fact, will be listened on only after the server becomes the Leader. Although the documentation says peer to peer, a careful look at the source code and practice shows that this port is really used by the Leader to communicate with each server
    • Port2: TCP communication port between servers during the election, that is, the election port
    • Observer: Indicates that the server is an observer
    • In version 3.6.0, you can use multiple addresses with the following structure
    • Server. Myid = net1: port1, port2 | net2: port1, port2, namely through the separator (|) to segment different address
  • leaderServes: Whether the Leader can connect to the client. The default value is true. If it is false, it indicates that the Leader only needs to focus on coordination. If the write request is much higher than the read request, you can set it to false.
  • For more configuration, see here, here, and here
4.2 start

Execute separately (note the execution directory)

./zk1/bin/zkServer.sh start
Copy the code

There is no change log location above, so it can be found under./zk1/logs

When only Zk1 is started, as shown in the log above, it will continue to fail when it tries to communicate with ZK2 and ZK3. When we start ZK2 and ZK3, the whole cluster will stabilize.

Due to the problem of the standalone version, here ZK4, namely the observerMasterPort of the Observer, is configured as 2481, namely Zk1. Therefore, if ZK1 is elected as the Leader, ZK4 will frantically flush logs. [refused] [refused]

As can be seen from this figure, ZK1 is successfully elected leader, and its monitored ports are as follows:

  • 3881: Port used for elections, listening at any time
  • 2281: Port used to communicate with other servers, namely, port1
  • 2481: As the leader, it doesn’t need to listen on the observerMasterPort anymore, so we can’t see it here
  • 2181: The port used to communicate with the client is not configuredleaderServes=false, so the leader also needs to respond to the client

The following ports are monitored by the Follower (ZK2 is used as an example) :

  • 3882: Election port, always keep listening, in case the leader fails, choose me to be the leader!
  • 2482: observerMasterPort, the TCP port responsible for communicating with the Observer
  • 2182: TCP port for communicating with clients
4.3 Simple Use
# do not add the content in [], connect to port 2181 by default
./zk1/bin/zkCli.sh [-server localhost:2182]

Type help to print the command
Create [-s] [-e] [-c] [-t TTL] path [data] [acl]
Create a node where data is "zk_test_data" and acl is not set
create /zk_test "zk_test_data"

The node has been created through ls /
ls /

The -s parameter will print the entire node information such as zxID
get -s /zk_test

# More commands please baidu /Google
# End of use
Copy the code

ACL

The official documentation on ACLs can be found here

Access Control Lists. In ZK, used to control access to zNodes.

1. The ACL

<scheme>:<id>:<perms>

// org.apache.zookeeper.data.ACL
public ACL(
    int perms,
    org.apache.zookeeper.data.Id id) {
    this.perms=perms;
    this.id=id;
}
// org.apache.zookeeper.data.Id
public Id( String scheme, String id) {
    this.scheme=scheme;
    this.id=id;
}
// org.apache.zookeeper.ZooDefs.Perms 
public interface Perms {
    int READ = 1 << 0;
    int WRITE = 1 << 1;
    int CREATE = 1 << 2;
    int DELETE = 1 << 3;
    int ADMIN = 1 << 4;
    int ALL = READ | WRITE | CREATE | DELETE | ADMIN;
}
Copy the code

ACL = Id + perms, and Id = Scheme + Id

2. Perms

Also from the source can see that perMS mainly contains the following types:

  • read
  • write
  • create
  • delete
  • Admin: You can set Permissions
  • “All” : indicates all permissions

3. Built-in permission scheme

Zookeeper provides the following built-in schemes:

  • World: anyone can have the permissions you set, <world>:<anyone><perms>

  • Digest :< digets>:<username:password>:<perms>, where password refers to the base64 encoded SHA1 password digest, fill in the ACL. For example, if username is Dylan and password is 123456, perform the following operations:

    echo -n dylan:123456 | openssl dgst -binary -sha1 | openssl base64
    Copy the code

    The final scheme should look like this:

    digest:dylan:7i6SL+m6GkW2OYpURnpkay0UdBc=:crwda

  • IP: use the IP address of the client host as the ACL ID. The ACL expression is in the form of ADDR/bits, where the most significant bit of ADDR matches the most significant bit of the client host IP address. For example: IP :127.0.0.1/16:crwda the document states that the most significant bit of the client host IP address must match the most significant bit of the client host IP address.

  • Auth: no ID, open to all authenticated users. This is like auth::crwda, where id is ignored!

  • X509: The X509 certificate is used for client authentication. To use this scheme, you need to configure the following options in the configuration file. For details, see here

    zookeeper.ssl.keyStore.location

    zookeeper.ssl.trustStore.location

    zookeeper.ssl.keyStore.password

    zookeeper.ssl.trustStore.password

In fact, there is sasL, which you can configure in zoo.cfg:

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider

And super!!

Watch

Please refer to the official documents related to Watch here

Zk’s Watch mechanism is also one of the guarantees of many applications mentioned in this article. Only because ZK’s Watch mechanism provides these guarantees can we say that it is ok to do so.

So what exactly is zK’s Watch mechanic? What kind of guarantees are offered?

Zk Watch Event: When the watch data changes, the Watch event will be triggered once and sent to the client with the Watch Event set.

  • Time-trigger: When the set Watch event is punished, it will be triggered only once. When this object changes again, it will not fire again unless the Watch event is set again (3.6 has added a permanent, permanent recursive watch).
  • Send to the client: Watch events will be asynchronously sent to clients. Due to network delay and other problems, each client will receive the event at a different time. Zk guarantees that a client will never observe data changes before the arrival of the Watch event. The client can detect data changes only after it listens to events
  • The data for which the watch was set: here refers to zK different watch events, which will produce different effects. This will be described below

1. watch event type

We in the org. Apache. Zookeeper. Watcher. Event. EventType can see, version 3.6, there are several kinds of watch Event as follows:

  • None: no watch
  • NodeCreated: added via exists(), emits a watch event when this node is created
  • NodeDeleted: Added using exists, getData, and getChildren
  • NodeDataChanged: exists and getData are added
  • NodeChildrenChanged: getChildren added
  • DataWatchRemoved: Exists and getData added
  • ChildWatchRemoved: getChildren added
  • PersistentWatchRemoved: Persistent watch added to the zK client. AddWatch is a method that specifies the Watcher type.
    • PERSISTENT: Watch, data change and children change are triggered
    • PERSISTENT_RECURSIVE: a persistent recursive watch that will watch the children of a given path

2. zookeeper guarantees about watches

  • Zk (zK Client, to be exact) ensures that the distribution of Watch events is orderly
  • The ZK client can see the new data of the ZNode only after receiving the Watch event from the ZNode
  • The order of watch events in ZK is consistent with the order of updates seen by ZK. That is, the watch event sequence in ZK corresponds to the update sequence of ZK

Based on the characteristics of Watch Event, special attention should be paid to two aspects:

  • If you use a one-time Watch event, you need to be prepared to miss multiple changes to the ZNode when you watch it again. The ZNode may have been changed several times by the time you add the Watch event again.
  • A Watch event is a one time trigger, that is, if you set a watch event through both EXISTS and getData, you will only get one Watch event in the end.

To Be Continue

  1. FastLeaderElection
  2. Zab protocol details
  3. Partial source code parsing
  4. Watch source code

The original link