一、Zookeeper原理简介
ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。
1.1 Zookeeper设计目的
- 最终一致性:client不论连接到那个Server,展示给它的都是同一个视图。
- 可靠性:具有简单、健壮、良好的性能、如果消息m被到一台服务器接收,那么消息m将被所有服务器接收。
- 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync 接口。
- 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
- 原子性:更新只能成功或者失败,没有中间状态。
- 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
1.2 Zookeeper工作原理
1.2 1、在zookeeper的集群中,各个节点共有下面3种角色和4种状态:
-
角色:leader,follower,observer
-
状态:leading,following,observing,looking
-
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议(
ZooKeeper Atomic Broadcast protocol
)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主
)和广播模式(Broadcast同步
)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。 -
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(
zxid
)来标识事务。所有的提议(proposal
)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
1.3 每个Server在工作过程中有4种状态
- LOOKING:当前Server不知道leader是谁,正在搜寻。
- LEADING:当前Server即为选举出来的leader。
- FOLLOWING:leader已经选举出来,当前Server与之同步。
- OBSERVING:observer的行为在大多数情况下与follower完全一致,但是他们不参加选举和投票,而仅仅接受(
observing
)选举和投票的结果。
1.4 Zookeeper集群节点
- Zookeeper节点部署越多,服务的可靠性越高,建议部署奇数个节点,因为zookeeper集群是以宕机个数过半才会让整个集群宕机的。
- 需要给每个zookeeper 1G左右的内存,如果可能的话,最好有独立的磁盘,因为独立磁盘可以确保
- zookeeper是高性能的。如果你的集群负载很重,不要把zookeeper和RegionServer运行在同一台机器上面,就像DataNodes和TaskTrackers一样
二、实验环境
准备 3 台服务器做 Zookeeper 集群
主机 | IP地址 |
---|---|
linux-node1 | 192.168.10.129 |
linux-node2 | 192.168.10.134 |
linux-node3 | 192.168.10.130 |
2.1修改主机名
[root@localhost ~]# hostname node1
[root@localhost ~]# su
[root@localhost ~]# hostname node2
[root@localhost ~]# su
[root@localhost ~]# hostname node3
[root@localhost ~]# su
2.2.安装前环境准备
关闭防火墙和安全级别
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2.2安装 JDK和检查环境
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
java -version
2.3下载到opt并安装软件包
cd /opt
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
2.4安装 Zookeeper并解压
cd /opt
tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz
mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper-3.5.7
2.5修改配置文件
cd /usr/local/zookeeper-3.5.7/conf/
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
tickTime=2000 #通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒
initLimit=10 #Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量),这里表示为10*2s
syncLimit=5 #Leader和Follower之间同步通信的超时时间,这里表示如果超过5*2s,Leader认为Follwer死掉,并从服务器列表中删除Follwer
dataDir=/usr/local/zookeeper-3.5.7/data ●修改,指定保存Zookeeper中的数据的目录,目录需要单独创建
dataLogDir=/usr/local/zookeeper-3.5.7/logs ●添加,指定存放日志的目录,目录需要单独创建
clientPort=2181 #客户端连接端口
#添加集群信息
server.1=192.168.10.129:3188:3288
server.2=192.168.10.134:3188:3288
server.3=192.168.10.130:3188:3288
2.6拷贝配置好的 Zookeeper 配置文件到其他机器上
scp /usr/local/zookeeper-3.5.7/conf/zoo.cfg 192.168.10.134:/usr/local/zookeeper-3.5.7/conf/
scp /usr/local/zookeeper-3.5.7/conf/zoo.cfg 192.168.10.130:/usr/local/zookeeper-3.5.7/conf/
2.7在每个节点上创建数据目录和日志目录
mkdir /usr/local/zookeeper-3.5.7/data
mkdir /usr/local/zookeeper-3.5.7/logs
2.8在每个节点的dataDir指定的目录下创建一个 myid 的文件
echo 1 > /usr/local/zookeeper-3.5.7/data/myid
echo 2 > /usr/local/zookeeper-3.5.7/data/myid
echo 3 > /usr/local/zookeeper-3.5.7/data/myid
2.9配置 Zookeeper 启动脚本
vim /etc/init.d/zookeeper
#!/bin/bash
#chkconfig:2345 20 90
#description:Zookeeper Service Control Script
ZK_HOME='/usr/local/zookeeper-3.5.7'
case $1 in
start)
echo "---------- zookeeper 启动 ------------"
$ZK_HOME/bin/zkServer.sh start
;;
stop)
echo "---------- zookeeper 停止 ------------"
$ZK_HOME/bin/zkServer.sh stop
;;
restart)
echo "---------- zookeeper 重启 ------------"
$ZK_HOME/bin/zkServer.sh restart
;;
status)
echo "---------- zookeeper 状态 ------------"
$ZK_HOME/bin/zkServer.sh status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
- 设置开机自启
chmod +x /etc/init.d/zookeeper
chkconfig --add zookeeper
- 分别启动 Zookeeper
service zookeeper start
- 查看当前状态
service zookeeper status
---------- zookeeper 状态 ------------
/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port not found in static config file. Looking in dynamic config file.
grep: : No such file or directory
Client port not found. Terminating
三、部署 Elasticsearch 集群
3.1登录192.168.50.201 更改主机名和配置域名解析及查看Java环境
[root@node1 ~]# hostnamectl set-hostname node1
[root@node1 ~]# vi /etc/hosts
192.168.50.201 node1
192.168.50.202 node2
[root@node1 ~]# java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
3.2登录192.168.50.202 更改主机名和配置域名解析及查看Java环境
[root@node2 ~]# hostnamectl set-hostname node2
[root@node2 ~]# vi /etc/hosts
192.168.50.201 node1
192.168.50.202 node2
[root@node2 ~]# java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
3.3 两台都需要部署elasticsearch软件
登录192.168.50.201
3.3.1 安装elasticsearch—rpm包
上传elasticsearch-5.5.0.rpm到/opt目录下
[root@node1 ~]# cd /opt
[root@node1 opt]# rpm -ivh elasticsearch-5.5.0.rpm
3.3.2 加载系统服务
[root@node1 opt]# systemctl daemon-reload
[root@node1 opt]# systemctl enable elasticsearch.service
3.3.3 更改elasticsearch主配置文件 h
[root@node1 opt]# cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak
[root@node1 opt]# vim /etc/elasticsearch/elasticsearch.yml
17/ cluster.name: my-elk-cluster ####集群名字
23/ node.name: node1 ####节点名字
33/ path.data: /data/elk_data ####数据存放路径
37/ path.logs: /var/log/elasticsearch/ ####日志存放路径
43/ bootstrap.memory_lock: false ####不在启动的时候锁定内存:锁定物理内存地址,防止es内存被交换出去,也就是避免es使用swap交换分区,频繁的交换,会导致IOPS变高。
55/ network.host: 0.0.0.0 ####提供服务绑定的IP地址,0.0.0.0代表所有地址
59/ http.port: 9200 ####侦听端口为9200
68/ discovery.zen.ping.unicast.hosts: ["node1", "node2"] ####集群发现通过单播实现
3.3.4 通过验证
grep -v "^#" /etc/elasticsearch/elasticsearch.yml
3.3.5 创建数据存放路径并授权
[root@node1 opt]# mkdir -p /data/elk_data
[root@node1 opt]# chown elasticsearch:elasticsearch /data/elk_data/
3.3.6 启动elasticsearch是否成功开启
[root@node1 elasticsearch]# systemctl start elasticsearch.service
[root@node1 elasticsearch]# netstat -antp |grep 9200
tcp6 0 0 :::9200 :::* LISTEN 64463/java
3.3.7 通过查看节点信息 用真机192.168.50.1 的浏览器打开
http://192.168.50.201:9200
3.3.8 在真机浏览器192.168.50.1 打开
http://192.168.50.201:9200/_cluster/state?pretty
检查群集状态信息
四 部署elasticsearch-head插件
此处在192.168.50.202(node2)和192.168.50.201 (node1)上都需要部署安装
4.1 上传node-v8.2.1.tar.gz到/opt
yum install gcc gcc-c++ make -y
4.2编译安装node组件依赖包
##耗时比较长 47分钟
[root@localhost opt]# cd /opt
[root@node1 opt]# tar xzvf node-v8.2.1.tar.gz
[root@node1 opt]# cd node-v8.2.1/
[root@node1 node-v8.2.1]# ./configure
[root@node1 node-v8.2.1]# make -j3 (等待时间较长)
[root@node1 node-v8.2.1]# make install
4.3安装phantomjs
前端框架
上传软件包到/usr/local/src/
[root@localhost node-v8.2.1]# cd /usr/local/src/
[root@localhost src]# tar xjvf phantomjs-2.1.1-linux-x86_64.tar.bz2
[root@localhost src]# cd phantomjs-2.1.1-linux-x86_64/bin
[root@localhost bin]# cp phantomjs /usr/local/bin
4.4安装elasticsearch-head#数据可视化工具
[root@localhost bin]# cd /usr/local/src/
[root@localhost src]# tar xzvf elasticsearch-head.tar.gz
[root@localhost src]# cd elasticsearch-head/
[root@localhost elasticsearch-head]# npm install
4.5修改主配置文件
[root@localhost ~]# cd ~
[root@localhost ~]# vim /etc/elasticsearch/elasticsearch.yml ####下面配置文件,插末尾##
http.cors.enabled: true ##开启跨域访问支持,默认为false
http.cors.allow-origin: "*" ## 跨域访问允许的域名地址
[root@localhost ~]# systemctl restart elasticsearch
4.6启动elasticsearch-head 启动服务器
[root@localhost ~]# cd /usr/local/src/elasticsearch-head/
[root@localhost elasticsearch-head]# npm run start & ####切换到后台运行
[1] 114729
[root@localhost elasticsearch-head]#
> elasticsearch-head@0.0.0 start /usr/local/src/elasticsearch-head
> grunt server
4.7部署kibana分析展示
在192.168.50.201(node1)主机安装kibana
上传kibana-5.5.1-x86_64.rpm 到/usr/local/src目录
[root@node1 ~]# cd /usr/local/src/
[root@node1 src]# rpm -ivh kibana-5.5.1-x86_64.rpm
[root@node1 src]# cd /etc/kibana/
[root@node1 kibana]# cp kibana.yml kibana.yml.bak
[root@node1 kibana]# vi kibana.yml
2/ server.port: 5601 #### kibana打开的端口
7/ server.host: "0.0.0.0" ####kibana侦听的地址
21/ elasticsearch.url: "http://192.168.100.41:9200" ###和elasticsearch建立联系
30/ kibana.index: ".kibana" ####在elasticsearch中添加.kibana索引
[root@node1 kibana]# systemctl start kibana.service ###启动kibana服务
[root@node1 kibana]# systemctl enable kibana.service ###开机启动kibana服务
4.8单独给一台机器部署logstash
此处大家可以考虑使用keepalived 进行做集群
logstash是为了收集Kafka队列传输过来的数据的
1.准备服务器
192.168.50.19
上传logstash-5.5.1.rpm到/opt目录下
[root@apache ~]# cd /opt
[root@apache opt]# rpm -ivh logstash-5.5.1.rpm ##安装logstash
[root@apache opt]# systemctl start logstash.service ##启动logstash
[root@apache opt]# systemctl enable logstash.service
[root@apache opt]# ln -s /usr/share/logstash/bin/logstash /usr/local/bin/ ##建立logstash软连接
cd /etc/logstash/conf.d/
vim filebeat.conf
input {
kafka {
bootstrap_servers => "192.168.50.101:9092,192.168.50.102:9092,192.168.50.103:9092"
topics => "filebeat_test"
group_id => "test123"
auto_offset_reset => "earliest"
}
}
output {
elasticsearch {
hosts => ["192.168.50.201:9200"]
index => "filebeat-%{+YYYY.MM.dd}"
}
stdout {
codec => rubydebug
}
}
4.9启动 logstash
nohup logstash -f filebeat.conf &
客户端上部署Filebeat
-
准备服务器
192.168.50.21 -
部署 Filebeat
cd /usr/local/filebeat
vim filebeat.yml
filebeat.prospectors:
- type: log
enabled: true
paths:
- /var/log/messages
- /var/log/*.log
......
#添加输出到 Kafka 的配置
output.kafka:
enabled: true
hosts: ["192.168.50.103:9092","192.168.50.101:9092","192.168.50.102:9092"] #指定 Kafka 集群配置
topic: "filebeat_test" #指定 Kafka 的 topic
- 启动 filebeat
./filebeat -e -c filebeat.yml
- 启动 logstash
logstash -f filebeat.conf
- 浏览器访问
http://192.168.50.201:5601
登录 Kibana,单击“Create Index Pattern
”按钮添加索引“filebeat-
*”,单击 “create
” 按钮创建,单击 “Discover
” 按钮可查看图表信息及日志信息。