In this guide, we’ll walk through the steps to configure and set up a Zookeeper ensemble using Ansible. We will cover how to partition, format, and mount disks, update configurations, install Zookeeper, and set up logging.
Zookeeper Configuration (zoo.cfg
)
The Zookeeper configuration file zoo.cfg
defines various parameters for Zookeeper. Below is an example configuration:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial synchronization phase can take
initLimit=10
# The number of ticks that can pass between sending a request and getting an acknowledgement
syncLimit=5
# The directory where the snapshot is stored
dataDir=/tmp/data1/zookeeper
# The port at which the clients will connect
clientPort=2181
# The maximum number of client connections
maxClientCnxns=1000
server.1=192.168.33.20:2888:3888
server.2=192.168.33.30:2888:3888
server.3=192.168.33.40:2888:3888
Explanation:
tickTime
: Basic time unit in milliseconds.initLimit
: Time Zookeeper allows followers to connect and sync with the leader.syncLimit
: Time to allow followers to sync with the leader.dataDir
: Directory where Zookeeper stores snapshots.clientPort
: Port for client connections.maxClientCnxns
: Maximum number of client connections.server.X
: List of Zookeeper ensemble servers.
Creating Necessary Directories
Create the directory for Zookeeper data storage.
mkdir -p /tmp/data1/zookeeper
Create the directory for Zookeeper logs.
mkdir -p /var/log/zookeeper
Logging Configuration (log4j.properties
)
The log4j.properties
file configures logging for Zookeeper. Below is an example configuration:
# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=/var/log/zookeeper
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=DEBUG
zookeeper.tracelog.dir=.
zookeeper.tracelog.file=zookeeper_trace.log
# ZooKeeper Logging Configuration
log4j.rootLogger=${zookeeper.root.logger}
# Log INFO level and above messages to the console
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
# Log DEBUG level and above messages to a rolling log file
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=10MB
# Uncomment the next line to limit the number of backup files
# log4j.appender.ROLLINGFILE.MaxBackupIndex=10
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
# Log TRACE level messages to a trace file
log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
log4j.appender.TRACEFILE.Threshold=TRACE
log4j.appender.TRACEFILE.File=${zookeeper.tracelog.dir}/${zookeeper.tracelog.file}
log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n
Ansible Playbook for Zookeeper Setup
The Ansible playbook below sets up a Zookeeper ensemble by adding users, downloading Zookeeper, configuring it, and creating necessary directories.
- hosts: ensemble
vars:
ZOOKEEPER_VERSION: 3.4.12
tags: ['ensemble', 'install', 'zoo_upgrade']
tasks:
- name: Add user zookeeper
user:
name: zookeeper
- name: Download and Unarchive Zookeeper
unarchive:
src: http://www-us.apache.org/dist/zookeeper/zookeeper-3.4.12.tar.gz
dest: /opt
remote_src: yes
owner: zookeeper
group: zookeeper
mode: 0755
- name: Create softlink for Zookeeper base dir
file:
src: /opt/zookeeper-3.4.12
path: /opt/zookeeper
state: link
owner: zookeeper
group: zookeeper
- name: Copy zoo.cfg and log4j.properties
synchronize:
src: "{{ base_dir }}/files/opt/zookeeper/conf"
dest: /opt/zookeeper
- name: Create data and log directories
file:
path: "{{ item }}"
state: directory
owner: zookeeper
group: zookeeper
mode: 0755
loop:
- /data1/zookeeper
- /var/log/zookeeper
Running the Playbook
Run the playbook with the following command:
ansible-playbook kafka.yml -i hosts --extra-vars "base_dir=/" --tags ensemble --become
Setting up Zookeeper Service Script
Create a script to manage the Zookeeper service.
mkdir -p scripts
touch scripts/zookeeper-service.sh
Content of zookeeper-service.sh
:
export ZOO_LOG_DIR=/var/log/zookeeper
/opt/zookeeper/bin/zkServer.sh $1
Adding myid
Files
Each Zookeeper server needs a unique myid
file. Run the following commands on each server:
ssh vagrant@192.168.33.20 "sudo -u zookeeper sh -c 'echo 1 > /tmp/data1/zookeeper/myid'"
ssh vagrant@192.168.33.30 "sudo -u zookeeper sh -c 'echo 2 > /tmp/data1/zookeeper/myid'"
ssh vagrant@192.168.33.40 "sudo -u zookeeper sh -c 'echo 3 > /tmp/data1/zookeeper/myid'"