The author of this article :HelloGitHub- Lao Xun

Hi, Here is HelloGitHub To launch the HelloZooKeeper series , Free and open source 、 Interesting 、 Entry level ZooKeeper course , For beginners with programming foundation .

Project address :

I'm going to take you all in today ZooKeeper Source code internal !

One 、 The source code to debug

Teaching a man to fish is better than giving him a fish

I always believed “ It's on paper ”, In the end, readers want to really understand ZK internals , Reading the source code is essential , If you have naked eyes like me Debug The ability of , In fact, you don't have to spend a lot of time building a source code debugging environment , The direct front is hard .

But if not , hold ZK Download the source code , Using a hand scale IDE Just run , And then interrupt where you need to learn , Isn't it beautiful

1.1 Download the source code

ZooKeeper 3.6.2 Source code download page

Choose one of the links above that has a high download speed , Click to download the compressed package , After the download is completed, unzip and you will get the following directory structure

├── zookeeper-server
├── zookeeper-recipes
├── zookeeper-metrics-providers
├── zookeeper-jute
├── zookeeper-it
├── zookeeper-docs
├── zookeeper-contrib
├── zookeeper-compatibility-tests
├── zookeeper-client
├── zookeeper-assembly
├── pom.xml
├── owaspSuppressions.xml
├── excludeFindBugsFilter.xml
├── dev
├── conf
├── checkstyleSuppressions.xml
├── checkstyle-strict.xml
├── checkstyle-simple.xml
├── bin
├── NOTICE.txt
├── LICENSE.txt
├── Jenkinsfile-PreCommit
└── Jenkinsfile

There are... In the catalog pom.xml therefore ZK Need to pass through maven Compile the entire project , Make sure you have maven It's installed

$ mvn --version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: /your/maven/home/apache-maven-3.5.4
Java version: 1.8.0_181, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"

If there is such an output description maven The installation was successful , I'll skip the specific installation process here , If you have difficulties , You can leave us a message

1.2 Compile the project

Access and pom.xml And enter

$ mvn install -DskipTests=true

You'll see the project compiling , Wait until the final output BUILD SUCCESS, That means the project is compiled

[INFO] Reactor Summary:
[INFO] Apache ZooKeeper 3.6.2 ............................. SUCCESS [ 3.621 s]
[INFO] Apache ZooKeeper - Documentation ................... SUCCESS [ 2.086 s]
[INFO] Apache ZooKeeper - Jute ............................ SUCCESS [ 10.633 s]
[INFO] Apache ZooKeeper - Server .......................... SUCCESS [ 19.246 s]
[INFO] Apache ZooKeeper - Metrics Providers ............... SUCCESS [ 0.108 s]
[INFO] Apache ZooKeeper - Metrics Provider .. SUCCESS [ 1.286 s]
[INFO] Apache ZooKeeper - Client .......................... SUCCESS [ 0.083 s]
[INFO] Apache ZooKeeper - Recipes ......................... SUCCESS [ 0.092 s]
[INFO] Apache ZooKeeper - Recipes - Election .............. SUCCESS [ 0.244 s]
[INFO] Apache ZooKeeper - Recipes - Lock .................. SUCCESS [ 0.259 s]
[INFO] Apache ZooKeeper - Recipes - Queue ................. SUCCESS [ 0.295 s]
[INFO] Apache ZooKeeper - Assembly ........................ SUCCESS [ 5.425 s]
[INFO] Apache ZooKeeper - Compatibility Tests ............. SUCCESS [ 0.072 s]
[INFO] Apache ZooKeeper - Compatibility Tests - Curator 3.6.2 SUCCESS [ 0.432 s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 44.263 s
[INFO] Finished at: 2021-01-22T13:49:30+08:00
[INFO] ------------------------------------------------------------------------

1.3 Open and configure the project

Then you can go through your IDE Open this directory , What I use here is idea

Then start configuration Run/Debug Configurations

Click on + Add a new configuration

choice Application

1.3.1 Stand alone boot configuration

Then fill in or select according to the figure below

  1. Let's give this configuration a strong name first
  2. choice Modify options Open the submenu
  3. Make sure that all three sub options in the menu are selected ( There is √)

Then let's look at the specific configuration

The unzipped project path on my computer is /Users/junjiexun/Desktop/apache-zookeeper-3.6.2 Please revise it according to your own situation

  1. Choose your local jdk ( I'm a local 1.8 I don't know if other versions are OK , The lower version certainly can't , Because the source code uses 1.8 Some ways to write )
  2. choice zookeeper
  3. To configure VM options, The content is -Dlog4j.configuration=file:/Users/junjiexun/Desktop/apache-zookeeper-3.6.2/conf/, If not configured , Unable to output log
  4. Specify the startup class org.apache.zookeeper.server.ZooKeeperServerMain
  5. Stand alone startup requires command line parameters , The content is 2181 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data
  6. This should not be modified , It will be filled in automatically , Anyway, the content is /Users/junjiexun/Desktop/apache-zookeeper-3.6.2
  7. Click... In the middle + Add package path , The content is org.apache.zookeeper.server.*

And then click Apply as well as OK Finish saving .

Then click on the bug to start

2021-01-22 15:12:16,319 [myid:] - INFO [main:NIOServerCnxnFactory@674] - binding to port
2021-01-22 15:12:16,413 [myid:] - INFO [main:WatchManagerFactory@42] - Using as watch manager
2021-01-22 15:12:16,413 [myid:] - INFO [main:WatchManagerFactory@42] - Using as watch manager
2021-01-22 15:12:16,413 [myid:] - INFO [main:ZKDatabase@132] - zookeeper.snapshotSizeFactor = 0.33
2021-01-22 15:12:16,413 [myid:] - INFO [main:ZKDatabase@152] - zookeeper.commitLogCount=500
2021-01-22 15:12:16,429 [myid:] - INFO [main:SnapStream@61] - zookeeper.snapshot.compression.method = CHECKED
2021-01-22 15:12:16,432 [myid:] - INFO [main:FileSnap@85] - Reading snapshot /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.2
2021-01-22 15:12:16,444 [myid:] - INFO [main:DataTree@1737] - The digest value is empty in snapshot
2021-01-22 15:12:16,480 [myid:] - INFO [main:ZKDatabase@289] - Snapshot loaded in 67 ms, highest zxid is 0x2, digest is 1371985504
2021-01-22 15:12:16,481 [myid:] - INFO [main:FileTxnSnapLog@470] - Snapshotting: 0x2 to /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.2
2021-01-22 15:12:16,488 [myid:] - INFO [main:ZooKeeperServer@529] - Snapshot taken in 6 ms
2021-01-22 15:12:16,544 [myid:] - INFO [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@136] - PrepRequestProcessor (sid:0) started, reconfigEnabled=false
2021-01-22 15:12:16,546 [myid:] - INFO [main:RequestThrottler@74] - zookeeper.request_throttler.shutdownTimeout = 10000
2021-01-22 15:12:16,623 [myid:] - INFO [main:ContainerManager@83] - Using checkIntervalMs=60000 maxPerMinute=10000 maxNeverUsedIntervalMs=0
2021-01-22 15:12:16,628 [myid:] - INFO [main:ZKAuditProvider@42] - ZooKeeper audit is disabled.

See log output , If there is no error, it is a success !

Then we can test it with the client

ZooKeeper client = new ZooKeeper("", 3000, null);
List<String> children = client.getChildren("/", false);

Output is


The stand-alone version is done ! Let's try the cluster version next

1.3.2 Cluster version boot configuration

We sometimes need to debug the cluster version ZK There is only logic , The previous stand-alone version is not enough , And I recommend compressing the previous source code here , Unzip to two different directories , And then through IDE Open these two directories separately , To completely simulate two different nodes . The configuration of cluster version is similar to that of stand-alone version , Let's see what's different ? I'll start two nodes here myid Namely 1 and 2.

  1. First of all, the default zoo_sample.cfg Copy and rename to zoo.cfg, You can also rename it directly
  2. newly build data Catalog ( If not ), And create a new text file under it myid The text is 1

And then edit zoo.cfg

# modify 
# Add the following two lines

The specific configuration is as follows :

  1. The startup class is different , The purpose of cluster is org.apache.zookeeper.server.quorum.QuorumPeerMain
  2. The command line parameters are different , What's coming in is zoo.cfg route , My path is /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/conf/zoo.cfg

Then there is the configuration of the second node , Let me assume that the project directory of the second node is /Users/junjiexun/Desktop/apache-zookeeper-3.6.2-bak

The second node puts myid The content of the document should be changed to 2

zoo.cfg The content of is

# modify 
# modify , Because my two nodes are in one machine , So ports can't be duplicated
# Also add the following two lines

The command line arguments are /Users/junjiexun/Desktop/apache-zookeeper-3.6.2-bak/conf/zoo.cfg

Other nodes I didn't mention 1 It's the same .

Let's start two nodes and try

2021-01-22 15:44:08,461 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):WatchManagerFactory@42] - Using as watch manager
2021-01-22 15:44:08,461 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):WatchManagerFactory@42] - Using as watch manager
2021-01-22 15:44:08,471 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):Learner@677] - Learner received NEWLEADER message
2021-01-22 15:44:08,471 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@1811] - Dynamic reconfig is disabled, we don't store the last seen config.
2021-01-22 15:44:08,471 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):FileTxnSnapLog@470] - Snapshotting: 0x28100000001 to /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.28100000001
2021-01-22 15:44:08,472 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):ZooKeeperServer@529] - Snapshot taken in 1 ms
2021-01-22 15:44:08,525 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):Learner@661] - Learner received UPTODATE message
2021-01-22 15:44:08,525 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@868] - Peer state changed: following - synchronization
2021-01-22 15:44:08,537 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):CommitProcessor@476] - Configuring CommitProcessor with readBatchSize -1 commitBatchSize 1
2021-01-22 15:44:08,537 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):CommitProcessor@438] - Configuring CommitProcessor with 4 worker threads.
2021-01-22 15:44:08,544 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):RequestThrottler@74] - zookeeper.request_throttler.shutdownTimeout = 10000
2021-01-22 15:44:08,567 [myid:1] - INFO [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@863] - Peer state changed: following - broadcast

final Peer state changed The representative election is complete , The posted node 1 yes Follower, Be accomplished !

Then when you want to learn the flow of the source code , Start the server directly , Is it beautiful ~

1.4 Source code reading North

  • Server startup , colony QuorumPeerMain#main, stand-alone ZooKeeperServerMain#main
  • client ZooKeeper
  • Analysis of configuration related problems ,QuorumPeerConfig#parse
  • Memory model ( Little red book )DataTree
  • Callback notice ( Little Huang Ben )IWatchManager Look at the interface implementation
    • Default implementation WatchManager
    • Optimization plan WatchManagerOptimized
  • The election FastLeaderElection#lookForLeader
  • Server instance , Set up the pipeline setupRequestProcessors Method
    • Leader node LeaderZooKeeperServer
    • Follower node FollowerZooKeeperServer
    • Observer node ObserverZooKeeperServer
  • Every assembly line employee RequestProcessor Look at the implementation of the interface
  • Persistence log FileTxnLog,snapshot FileSnap
  • session management SessionTrackerImpl#run
  • agreement Record Look at the implementation of the interface

1.5 Source code reading experience

Reading the source code of a large project must be a time-consuming and laborious work , I'll also talk about my reading here ZK Source experience :

  • Don't pick details ! Large projects usually have more source code , If you look at every detail of logic , Will be lost in the sea of source code .
  • Usually read the source code with a purpose . for example :ZK How to do protocol conversion ,ZK How the election was held, and so on . With a purpose , Look at the relevant source code is to selectively ignore some other irrelevant details , You can use method names or comments , Let's have a perceptual understanding of the specific code block first .
  • Where I can't read , You can go to the Internet to see if anyone has written a similar blog , Standing on the shoulders of giants , It's very likely that you'll get through with someone else .
  • stay ZK In general, indirect or direct inheritance ZooKeeperThread All thread objects , The main logic can be seen run Method .
  • The important attribute of any class must be in the member field , You can roughly infer the data structure behind this class by looking at the member fields .
  • If there is a field blocking the queue in the member property , Probably the producer - The embodiment of the consumer model , You can focus on the use of the blocking queue , When to put in and take out elements .

1.6 Summary

I used some graphic space to introduce how to debug locally ZK Source code , And how to read the source code scientifically . My local environment is Mac, With IDE yes idea, If your environment or tools are different from mine , In case of difficulties , You can also leave us a message ~

Two 、ZK The design patterns applied to the design of

ZK It's a distributed application in itself , It's also an excellent open source project , I'd like to talk about the application I saw in reading the source code ZK The design pattern in this article

2.1 Producer consumer

This is ZK The most representative design pattern in is applied ,ZK Itself is C/S Architecture design , The request is the data sent by the client to the server , The response is the data sent by the server to the client , and ZK Some functions are not implemented by calling different methods in linear order , It's usually done by the producer thread , Blocking queues and consumer threads are made up of , The producer thread puts some request objects received upstream into the blocking queue , The current method returns , After that, the consumer thread gets the information from the blocking queue through the loop , And then complete the business logic . give an example :

  • PrepRequestProcessor, The blocking queue is submittedRequests
  • SyncRequestProcessor, The blocking queue is queuedRequests

2.2 Factory mode

There are some interface implementations ,ZK Itself provides the default choice , But if the user configures other implementations in the configuration ,ZK The factory will automatically create those other implementations . give an example :

  • Creating ClientCnxnSocket when , Will be based on zookeeper.clientCnxnSocket To select the client's IO Realization
  • Creating IWatchManager when , Will be based on zookeeper.watchManagerName To select the server's watch Management implementation
  • Creating ServerCnxnFactory when , Will be based on zookeeper.serverCnxnFactory To select the server's IO Factory realization

2.3 The chain of responsibility model

I've learned before ,ZK The business logic processing of the server side is through one by one XxxProcessor String together to achieve ,Processor They don't care about the call order , Just passed nextProcessor relation , Different server roles can also greatly reuse code in this way

  • In stand-alone mode :PrepRequestProcessor -> SyncRequestProcessor -> FinalRequestProcessor
  • Cluster mode Leader :LeaderRequestProcessor -> PrepRequestProcessor -> ProposalRequestProcessor -> CommitProcessor -> Leader.ToBeAppliedRequestProcessor -> FinalRequestProcessor
  • Cluster mode Follower :FollowerRequestProcessor -> CommitProcessor -> FinalRequestProcessor
  • Cluster mode Observer :ObserverRequestProcessor -> CommitProcessor -> FinalRequestProcessor

2.4 The strategy pattern

zookeeper.snapshot.compression.method It can be configured into different snapshot Compression algorithm , When you need to generate snapshot When you file , It will be executed according to different compression algorithms :

  • gzGZIPInputStream
  • snappySnappyInputStream
  • Default :BufferedInputStream

2.5 Decorator mode

Or just the compression algorithm , What is offered to the outside world is CheckedInputStream The unified processing object of , Use CheckedInputStream Package the above three compression implementations , These objects are all InputStream Subclasses of

switch ( Depending on the configuration ) {
// The embodiment of the strategic model
case GZIP:
is = new GZIPInputStream(fis);
case SNAPPY:
is = new SnappyInputStream(fis);
is = new BufferedInputStream(fis);
// It's all packaged in CheckedInputStream
// The embodiment of Decorator Pattern
return new CheckedInputStream(is, new Adler32());

3、 ... and 、 summary

Today I'm going to talk about how to go directly from ZK Source code DEBUG, Introduced some ZK The design pattern used in , If you have any questions about reading the source code , Welcome to leave me a message . This article was first published in 「HelloGitHub」 official account

The next issue introduces ZK The advanced usage of is purely practical , Look forward to it ~

Old rules , If you have any questions about the article, it can also be suggestions or right ZK Questions about the principle part , Welcome to the warehouse issue Give us , Or talk about the topic .

Address :

Hand in hand teaching you to read and debug large open source projects ZooKeeper More articles about

  1. iOS Advanced animation - Touch your hand and teach you to write Slack Of Loading Animation

    If mobile access is poor , You can visit my personal blog A few days ago, I read a blog about animation, called hand touch hand to teach you to write Slack Of Loading Animation , It's amazing , But it's the Android version , Thinking of writing a copy of iOS Version of , Here's what I did with this animation ...

  2. Touch your hand to teach you how to Python Small details and big optimization in coding

    Touch your hand to teach you how to Python Small details and big optimization in coding Count in the list """ Count in the list , Use Python Native functions count much faster , So try to use native functions to calculate . &qu ...

  3. Hand touch hands to teach you the custom components of wechat applet development

    Preface I believe that when you develop small programs, you will encounter the situation that a function is used many times , Like pop-up boxes . At this time, we first think of component development , It's encapsulating the pop-up box as a component , Then call wherever you use it , Yes , It seems that everyone has ideas , But how to achieve ...

  4. Hand to hand teaching you to let Laravel Development Api More handy 1. cause With the front and rear ends completely separated ,PHP And basically said goodbye v ...

  5. 【 turn 】 Touch your hand , With you vue Back office A series of

    Preface The good tutorial has finally come , The first article mainly talks about some preparatory work before starting to write business code , But it won't teach you webpack The basic configuration of , How to do hot update ,webpack Speed optimization and so on , Please help yourself if you need google. Catalog ...

  6. Touch the bracelet, you understand Vue Of Computed principle

    Preface computed stay Vue It is a very common property configuration in , It can change with dependency properties , It's very convenient for us . So this article will bring you a comprehensive understanding computed The internal principle and work flow of . before this , I hope you can ...

  7. Touch your hand , Study with you UiPath Studio

    Study RPA There are more pits on the road , Let's touch our hands , Went together …… Here are some lessons UiPath and RPA Resources for , You're welcome to take it ! UiPath Studio Chinese document Robot process automation is actually a good concept and technology , ...

  8. 【 turn 】 Touch your hand , With you vue Back office Series two ( Login permission )

    Preface It's a little bit more serious , It took half a month to write the second tutorial . But I am a business ape , Every day I was abused by our products , I was sick again and had a rest for a few days , I'm sorry . Get to the point , Doing background projects is different from doing other projects , Authority verification and security are very important ...

  9. 【 turn 】 Touch your hand , With you vue Back office Series three ( Actual combat )

    Preface In the previous two articles, the basic work environment has been built , It has also completed the login and permission of the background core , Now touch your hand , Let's get into practice together . Element It started last October vue Do not hesitate to choose when managing backstage Elemen, ...

  10. 【 turn 】 Touch your hand , With you vue Back office Series IV (vueAdmin A simple background basic template )

    Preface Do this vueAdmin-template The main reason is : vue-element-admin The original intention of this project is a vue Management background integration scheme of , Share some of the components or experiences you usually use with you , And it's not ...

Random recommendation

  1. [ improve Java Code ] Different lists choose different traversal methods

    One . scene : Let's take a look at a scene , Statistics of a province's college entrance examination subjects of the average score . Of course, use one of the databases SQL Statement to find the average , But this is no longer our consideration , Only pure Java To solve the problem .( Because my machine is equipped with ...

  2. Spring AOP-- be based on XML Configuration of files

    Spring AOP The configuration of can be based on annotations , It can also be based on XML file . The previous articles all use annotations . Here is how to use it XML How to configure files The test class and aspect class used are similar . Just belong to AOP You can just remove the annotation of . Here is AOP Of X ...

  3. CF- Day at the Beach

    C. Day at the Beach time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. CURL Use HTTPS Technical summary of

    Excerpt from CURL Use HTTPS Technical summary of cURL yes linux Submit from the command line HTTP(S) One of the requests is ...

  5. pku Summer camp interview

    Beijing University interview topic : One . Memory exchange Memory exchange ( exchange ) The basic idea of , Put in a waiting state ( Or in the CPU Being deprived of the right to operate under the dispatching principle ) Program moved from memory to secondary memory , Free up memory space , This process is also called swap out : Get ready to compete CPU Running programs ...

  6. [js Master's Road ]html5 canvas Animation tutorial - Boundary judgment and rebound

    remarks : The code behind this article , If loaded ball.js, So please use this article [js Master's Road ] html5 canvas Animation tutorial - Moving at a constant speed ball.js Code . The border rebounds : When the ball hits canvas Four directions of ...

  7. nyoj Look for the maximum number

    Look for the maximum number The time limit :1000 ms  |  Memory limit :65535 KB difficulty :2   describe Please enter the integer n Delete in m A digital , Make the new number of the remaining numbers in the original order the largest , For example, when n=920813467185 ...

  8. use snippet save dom to excel

    1. Open the post 2. open console Execute the following command Array.prototy ...

  9. Ubuntu 16.04 install JDK 1.8

    System environment Ubuntu 16.04; JDK 1.8 configuration setup 1. First of all, from the oracle download jdk 1.8, The version I downloaded is jdk-8u131-linux-x64.tar.gz, function tar zvxf jd ...

  10. python The basic data types of learning

    python The basic data types of are numbers . character string . list . Dictionaries . Yuan Zu . Boolean value One . Numbers 1.1. Character to number example : a=" b=int(a) print(b+) Running results : It can be used type View the data ...