安装zookeeper,并配置集群
1、准备三台机器做集群
服务器 |
IP地址 |
端口 |
服务器1 |
192.168.10.140 |
2181/2881/3881 |
服务器2 |
192.168.10.141 |
2181/2881/3881 |
服务器3 |
192.168.10.142 |
2181/2881/3881 |
2、配置
2.1配置java环境
将jdk-8u141-linux-x64.tar.gz上传到三台服务器安装配置。
解压到/data/program/software/
并将文件夹重命名为java8
配置jdk全局变量。
#vi /etc/profile
export JAVA_HOME=/data/program/software/java8
export JRE_HOME=/data/program/software/java8/jre
export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
2.2 修改操作系统的/etc/hosts文件,添加IP与主机名映射:
# zookeeper cluster servers
192.168.10.140 bigdata1
192.168.10.141 bigdata2
192.168.10.142 bigdata3
2.3下载zookeeper-3.4.9.tar.gz 到/data/program/software/目录
# wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz
2.4 解压zookeeper安装包,并对节点重民名
#tar -zxvf zookeeper-3.4.9.tar.gz
服务器1:
#mv zookeeper-3.4.9 zookeeper
服务器2:
#mv zookeeper-3.4.9 zookeeper
服务器3:
#mv zookeeper-3.4.9 zookeeper
2.5 在zookeeper的各个节点下 创建数据和日志目录
#cd zookeeper
#mkdir data
#mkdir logs
2.6 重命名配置文件
将zookeeper/conf目录下的zoo_sample.cfg文件拷贝一份,命名为zoo.cfg:
#cp zoo_sample.cfg zoo.cfg
修改zoo.cfg 配置文件
clientPort=2181
dataDir=/data/program/software/zookeeper/data
dataLogDir=/data/program/software/zookeeper/logs
server.1=bigdata1:2881:3881
server.2=bigdata2:2881:3881
server.3=bigdata3:2881:3881
参数说明:
tickTime=2000
tickTime这个时间是作为Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳。
initLimit=10
initLimit这个配置项是用来配置Zookeeper接受客户端(这里所说的客户端不是用户连接Zookeeper服务器的客户端,而是Zookeeper服务器集群中连接到Leader的Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过10个心跳的时间(也就是tickTime)长度后Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是10*2000=20 秒。
syncLimit=5
syncLimit这个配置项标识Leader与Follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。
dataDir=/data/program/software/zookeeper/data
dataDir顾名思义就是Zookeeper保存数据的目录,默认情况下Zookeeper将写数据的日志文件也保存在这个目录里。
clientPort=2181
clientPort这个端口就是客户端(应用程序)连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求。
server.A=B:C:D
server.1=bigdata1:2881:3881
server.2=bigdata2:2881:3881
server.3=bigdata3:2881:3881
A是一个数字,表示这个是第几号服务器;
B是这个服务器的IP地址(或者是与IP地址做了映射的主机名);
C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的Leader服务器交换信息的端口;
D是在leader挂掉时专门用来进行选举leader所用的端口。
注意:如果是伪集群的配置方式,不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
2.8 创建myid文件
在dataDir= dataDir=/data/program/software/zookeeper/data 下创建myid文件
编辑myid文件,并在对应的IP的机器上输入对应的编号。如在1上,myid文件内容就是1, 2上就是2, 3上就是3:
#vi /myid## 值为1
#vi /myid## 值为2
#vi /myid## 值为3
2.9 启动测试zookeeper
(1)进入/bin目录下执行:
# /zkServer.sh start
# /zkServer.sh start
# /zkServer.sh start
(2)输入jps命令查看进程:
其中,QuorumPeerMain是zookeeper进程,说明启动正常
(3)查看状态:
# /zkServer.sh status
(4)查看zookeeper服务输出信息:
由于服务信息输出文件在/bin/zookeeper.out
$ tail -500 f zookeeper.out
连接客户端:
./zkClient.sh -server 192.168.10.140:2181, 192.168.10.141:2181, 192.168.10.142:2181,
3、集群角色
Leader:写操作都走leader,zk里面leader只有一个
Fllower: 帮leader处理查的请求,有投票的权利
Observer:进行指定,没有投票权利,可以处理请求
ZK的常用命令
Ls:查看那目录的所有文件
Ls2:多了一些参数,time,version等
Create:创建节点,并设置初始内容,创建的时候必须以/开始,其实是存储数据的,该数据叫znode。可以创建父子节点:create /lpf/node lpf666,数据为lpf666.
Get:获取znode的数据
Set :修改znode的数据
Delete:删除znode
Quit:退出客户端
Help:
Rmr:进行递归删除,可以删除子节点
4、Zk的核心概念:
Zk其实是做存储的。
Znode:用来存储数据的。zk操作和维护的是一个一个的数据节点,采用类似于文件系统的层级树状结构进行管理。如果znode节点包含数据则存储为字节数组,创建znode需要制定类型:
·持久:客户端创建的文件一直存在,退出后文件还会存在。默认为此。PERISTENT
·持久有序节点PERSISTENT_SEQUENTIAL:是有序的,创建出来的文件是带有序号的:Create -s /lpf lpf666
·ephemeral临时的:客户端session失效,则数据消失。
Create -e /lpf lpf666 退出后该节点没了
·Ephemeral_sequential临时有序节点:有序自增
Dubbo连接zk,用的是临时节点,因为dubbo,服务正常后才保存session,如果服务停了,zk中的数据消失,通过查看节点判断服务是否正常
5、Watcher机制:
时间监听器
当某个节点数据变化的时候,所有的客户端都会感知,从而被通知。可以实现多级缓存数据一致性问题。
6、ACL:
Zk的权限管理
getAcl /lpf 返回word
word:谁都可以访问
auth:代表已经认证通过的用户
digest:即用户名,密码方式认证,常用的方式
addauth digest lpf:lpf
create /aaa 123456
setAcl /aaa auth:lpf:lpf:cdrwa权限
用其他客户端get /aaa的时候就不行了
ip:ip地址认证
7、高性能:
Zk不适合海量数据的存储,高性能体现在读多写少的场景。因为fllower很多,leader只有一个。
客户端操作:
ZkClient是由Datameer的工程师开发的开源客户端,对Zookeeper的原生API进行了包装,实现了超时重连、Watcher反复注册等功能。
github源代码地址:https://github.com/sgroschupf/zkclient
流式接口
Zk的使用场景:
利用watcher监听节点,对并发不高的可以使用
Dubbo
Zk的原理
入口程序:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.apache.zookeeper.server.quorum;
import java.io.File;
import java.io.IOException;
import javax.management.JMException;
import org.apache.zookeeper.jmx.ManagedUtil;
import org.apache.zookeeper.server.DatadirCleanupManager;
import org.apache.zookeeper.server.ServerCnxnFactory;
import org.apache.zookeeper.server.ZKDatabase;
import org.apache.zookeeper.server.ZooKeeperServerMain;
import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class QuorumPeerMain {
private static final Logger LOG = LoggerFactory.getLogger(QuorumPeerMain.class);
private static final String USAGE = "Usage: QuorumPeerMain configfile";
protected QuorumPeer quorumPeer;
public QuorumPeerMain() {
}
public static void main(String[] args) {
QuorumPeerMain main = new QuorumPeerMain();
try {
main.initializeAndRun(args);
} catch (IllegalArgumentException var3) {
LOG.error("Invalid arguments, exiting abnormally", var3);
LOG.info("Usage: QuorumPeerMain configfile");
System.err.println("Usage: QuorumPeerMain configfile");
System.exit(2);
} catch (ConfigException var4) {
LOG.error("Invalid config, exiting abnormally", var4);
System.err.println("Invalid config, exiting abnormally");
System.exit(2);
} catch (Exception var5) {
LOG.error("Unexpected exception, exiting abnormally", var5);
System.exit(1);
}
LOG.info("Exiting normally");
System.exit(0);
}
protected void initializeAndRun(String[] args) throws ConfigException, IOException {
QuorumPeerConfig config = new QuorumPeerConfig();
if(args.length == 1) {
config.parse(args[0]);
}
DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config.getDataDir(), config.getDataLogDir(), config.getSnapRetainCount(), config.getPurgeInterval());
purgeMgr.start();
if(args.length == 1 && config.servers.size() > 0) {
this.runFromConfig(config);
} else {
LOG.warn("Either no config or no quorum defined in config, running in standalone mode");
ZooKeeperServerMain.main(args);
}
}
public void runFromConfig(QuorumPeerConfig config) throws IOException {
try {
ManagedUtil.registerLog4jMBeans();
} catch (JMException var4) {
LOG.warn("Unable to register log4j JMX control", var4);
}
LOG.info("Starting quorum peer");
try {
ServerCnxnFactory cnxnFactory = ServerCnxnFactory.createFactory();
cnxnFactory.configure(config.getClientPortAddress(), config.getMaxClientCnxns());
this.quorumPeer = new QuorumPeer();
this.quorumPeer.setClientPortAddress(config.getClientPortAddress());
this.quorumPeer.setTxnFactory(new FileTxnSnapLog(new File(config.getDataLogDir()), new File(config.getDataDir())));
this.quorumPeer.setQuorumPeers(config.getServers());
this.quorumPeer.setElectionType(config.getElectionAlg());
this.quorumPeer.setMyid(config.getServerId());
this.quorumPeer.setTickTime(config.getTickTime());
this.quorumPeer.setMinSessionTimeout(config.getMinSessionTimeout());
this.quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
this.quorumPeer.setInitLimit(config.getInitLimit());
this.quorumPeer.setSyncLimit(config.getSyncLimit());
this.quorumPeer.setQuorumVerifier(config.getQuorumVerifier());
this.quorumPeer.setCnxnFactory(cnxnFactory);
this.quorumPeer.setZKDatabase(new ZKDatabase(this.quorumPeer.getTxnFactory()));
this.quorumPeer.setLearnerType(config.getPeerType());
this.quorumPeer.setSyncEnabled(config.getSyncEnabled());
this.quorumPeer.setQuorumListenOnAllIPs(config.getQuorumListenOnAllIPs().booleanValue());
this.quorumPeer.start();
this.quorumPeer.join();
} catch (InterruptedException var3) {
LOG.warn("Quorum Peer interrupted", var3);
}
}
}
org.apache.zookeeper.server.quorum.QuorumPeerMain.main
>org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun
>org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse //解析zoo.cfg文件内容加载到内存中
>org.apache.zookeeper.server.quorum.QuorumPeerMain.runFromConfig 启动准备工作
>org.apache.zookeeper.server.quorum.QuorumPeer 创建QuorumPeer对象
>org.apache.zookeeper.server.quorum.QuorumPeer.start 1、加载数据库 2、网络建立启动 3、leader选举
1加载数据库
2、网络建立启动
org.apache.zookeeper.server.ServerCnxnFactory.start nio和netty两个factnroy
org.apache.zookeeper.server.NIOServerCnxnFactory.start
3、leader选举
> org.apache.zookeeper.server.ZooKeeperServerMain.main
单机模式:/org/apache/zookeeper/server/quorum/QuorumPeerMain.java:116