zookeeper
介绍
zookeeper:为分布式框架提供协调服务,文件系统+通知机制
-
工作机制
基于观察者模式设计的分布式服务管理框架,负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应
-
特点
1)、Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
2)、集群中有半数以上节点存活,集群就能正常服务。所以Zookeeper适合安装奇数台服务器。
3)、全局数据一致:每个Server保存一份相同的数据副本,Client连接到任何Server,数据都是一致的。
4)、更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行。
5)、数据更新原子性,一次数据更新要么成功,要么失败。
6)、实时性,在一定时间范围内,Client能读到最新数据。 -
数据结构
ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识。
-
应用场景
提供的服务包括:统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。
1)、统一命名服务
2)、统一配置管理
3)、统一集群管理
4)、服务器节点动态上下线
5)、软负载均衡
-
选举机制
第一次启动
1)服务器1启动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以 上(3 票),选举无法完成,服务器1状态保持为LOOKING;
2)服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务 器1发现服务器2的myid比自己目前投票推举的(服务器1)大,更改选票为推举服务器 2。此时服务器1票数0票,服务器2票数2票,没有半数以上结果,选举无法完成,服 务器1,2状态保持LOOKING
3)服务器3启动,发起一次选举。此时服务器1和2都会更改选票为服务器3。此次投票结果: 服务器1为0票,服务器2为0票,服务器3为3票。此时服务器3的票数已经超过半数, 服务器3当选Leader。服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING;
4)服务器4启动,发起一次选举。此时服务器1,2,3已经不是LOOKING状态,不会更改选票 信息。交换选票信息结果:服务器3为3票,服务器4为 1票。此时服务器4服从多数, 更改选票信息为服务器3,并更改状态为FOLLOWING;
5)服务器5启动,同4一样当小弟。非第一次启动
1)当ZooKeeper集群中的一台服务器出现以下两种情况之一时,就会开始进入Leader选举
• 服务器初始化启动。
• 服务器运行期间无法和Leader保持连接。2)而当一台机器进入Leader选举流程时,当前集群也可能会处于以下两种状态:
• 集群中本来就已经存在一个Leader。
已经存在Leader的情况,机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连接,并进行状态同步即可。• 集群中确实不存在Leader。
假设ZooKeeper由5台服务器组成,
SID分别为1、2、3、4、5,
ZXID分别为8、8、8、7、7,
并且此时SID为3的服务器是Leader。
某一时刻,3和5服务器出现故障,因此开始进行Leader选举。
SID为1、2、4的机器投票情况: (1,8,1) (1,8,2) (1,7,4)
(EPOCH,ZXID,SID )
选举Leader规则:
①EPOCH大的直接胜出
②EPOCH相同,事务id大的胜出
③事务id相同,服务器id大的胜出 -
监听器原理
1)首先要有一个main()线程
2)在main线程中创建Zookeeper客户端,这时就会创建两个线程,
一个负责网络连接通信(connet),
一个负责监听(listener)
3)通过connect线程将注册的监听事件发送给Zookeeper。
4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
5)Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。
6)listener线程内部调用了process()方法。 -
流程角色
Leader:接受所有的Follower请求并统一协调发起投票;负责所有follower内部数据交换,所有写相关 操作
Follower:为客户端服务,参加提案的投票,与Leader数据交换,读操作与响应leader提议
Observer:不参提案的加投票;与Leader数据交换,接收客户端请求,并把写请求转发给leader,但是 leader不会要求Obserber参加投票
部署
#默认3节点开始、安装在3台node节点
-
所有zookeeper节点机器安装
for i in 54 55 56; do scp apache-zookeeper-3.6.3-bin.tar.gz root@192.168.10.$i:/data/; done tar -xvf /data/apache-zookeeper-3.6.3-bin.tar.gz -C /data/ mv /data/apache-zookeeper-3.6.3-bin/ /data/zookeeper-3.6.3/
-
所有zookeeper节点机器添加环境变量
vim /etc/profile.d/my_env.sh #添加ZK_HOME export ZK_HOME=/data/zookeeper-3.6.3 export PATH=$PATH:$ZK_HOME/bin source /etc/profile
-
所有zookeeper节点机器修改配置文件
cd /data/zookeeper-3.6.3/conf/ cp -p zoo_sample.cfg zoo.cfg vim zoo.cfg # 响应毫秒数 tickTime=2000 # 初始同步需要的连接数 initLimit=10 #传输同步需要的连接数 syncLimit=5 #存储快照的目录 dataDir=/data/zookeeper-3.6.3/data/tmp #客户端将连接的端口 clientPort=2181 #客户端连接数 #maxClientCnxns=60 #保留在dataDir中的快照数 #autopurge.snapRetainCount=3 #清除任务间隔h,设置为“0”可禁用自动清除功能 #autopurge.purgeInterval=1 #最后添加 server.1=1节点主机ip:2888:3888 server.2=2节点主机ip:2888:3888 server.3=3节点主机ip:2888:3888
vim /data/zookeeper-3.6.3/bin/zkEnv.sh #首行增加 JAVA_HOME=/opt/jdk1.8.0_212
-
创建存储文件夹
mkdir -p /data/zookeeper-3.6.3/data/tmp
-
#创建 myid 文件,id 必须与配置文件里主机名对应的server.(id)一致
1节点主机上执行 echo 1 > /data/zookeeper-3.6.3/data/tmp/myid 2节点主机上执行 echo 2 > /data/zookeeper-3.6.3/data/tmp/myid 3节点主机上执行 echo 3 > /data/zookeeper-3.6.3/data/tmp/myid
-
所有zookeeper节点机器启动服务
#命令单独启动 #启动 /data/zookeeper-3.6.3/bin/zkServer.sh start #查看状态 /data/zookeeper-3.6.3/bin/zkServer.sh status #停止 /data/zookeeper-3.6.3/bin/zkServer.sh stop
#配置启动服务 vim /usr/lib/systemd/system/zookeeper.service [Unit] Description=zookeeper After=network.target ConditionPathExists=/data/zookeeper-3.6.3/conf/zoo.cfg [Service] Type=forking Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/jdk1.8.0_212/bin" ExecStart=/data/zookeeper-3.6.3/bin/zkServer.sh start ExecReload=/data/zookeeper-3.6.3/bin/zkServer.sh restart ExecStop=/data/zookeeper-3.6.3/bin/zkServer.sh stop User=root Group=root [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl start zookeeper.service systemctl status zookeeper.service systemctl enable zookeeper.service
-
连接:
/data/zookeeper-3.6.3/bin/zkCli.sh
使用
-
连接
/data/zookeeper-3.4.13/bin/zkCli.sh -server hadoop102:2181
-
监听
#监听节点数据的变化 get -w /sanguo #监听子节点增减的变化 ls -w /sanguo
-
历史服务
history
-
创建节点
create [-s -e] /sanguo/weiguo/zhangliao "zhangliao" -s 含有序列 -e 临时(客户端连接断开,节点删除)
-
删除
#删除节点 delete [-v] path #删除一个路径上多个节点 deleteall path
-
修改设置节点的具体值
set /sanguo/weiguo "simayi"
-
查看
#获得节点的值 get -s /sanguo #所包含的内容 ls / #当前节点详细数据 ls -s / #czxid:创建节点的事务 zxid #ctime:znode 被创建的毫秒数(从 1970 年开始) #mzxid:znode 最后更新的事务 zxid #mtime:znode 最后修改的毫秒数(从 1970 年开始) #pZxid:znode 最后更新的子节点 zxid #cversion:znode 子节点变化号,znode 子节点修改次数 #dataversion:znode 数据变化号 #aclVersion:znode 访问控制列表的变化号 #ephemeralOwner:如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点则是 0。 #dataLength:znode 的数据长度 #numChildren:znode 子节点数量
kafka
介绍
-
优点
1)、解耦:允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2)、冗余:消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。 许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处 理系统明确 的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
3)、扩展性:因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另 外增加处理过程即可。
4)、灵活性 & 峰值处理能力:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发 流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。 使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩 溃。
5)、可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所 以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
6)、顺序保证:在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且 能保证数据会按照特定的顺序来处理。(Kafka保证一个Partition内的消息的有序性)
7)、缓冲:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情 况。
8)、异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户 把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的 时候再去处理它们。 -
消费模式
1)、点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不 是将消息推送到客户端。这个模型的特点是发送到队列的消息被一个且只有一个接收者接 收处理,即使有多个消息监听者也是如此。
2)、发布/订阅模式(一对多,数据生产后,推送给所有订阅者)
发布订阅模型则是一个基于推送的消息传送模型。发布订阅模型可以有多种不同的订阅者,临 时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即使当 前订阅者不可用,处于离线状态。 -
架构与角色
角色
Producer :消息生产者,就是向kafka broker发消息的客户端;Consumer :消息消费者,向kafka broker取消息的客户端;
Consumer Group (CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播 (发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的 复制,是概念上的)到所有的CG,但每个partion只会把消息发给该CG中的一个consumer。如 果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的 consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同 的topic;
Broker :一台服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic
Topic :可以理解为一个队列;
Partition:相当于topic扩展性负载,一个非常大的topic可以分布到多个broker(即服务器)上,一个 topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分 配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保 证一个topic的整体(多个partition间)的顺序;
Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想 找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就00000000000.kafka。
部署
-
安装包(在slave1,slave2,slave3上)
for i in 54 55 56; do scp kafka_2.12-2.7.0.tgz root@192.168.10.$i:/data/; done tar -xvf /data/kafka_2.12-2.7.0.tgz -C /data/ mv /data/kafka_2.12-2.7.0 /data/kafka
-
添加环境变量(在slave1,slave2,slave3上)
vim /etc/profile.d/my_env.sh #添加KAFKA_HOME export KAFKA_HOME=/data/kafka export PATH=$PATH:$KAFKA_HOME/bin source /etc/profile
-
修改配置文件(在slave1,slave2,slave3上)
vim /data/kafka/config/server.properties #代理的id broker.id=主机ip尾号 #日志路径 log.dirs=/data/kafka/logs #zookeeper集群地址 zookeeper.connect=slave1-zookeeperIp:2181,slave2-zookeeperIp:2181,slave3-zookeeperIp:2181 #允许删除topic delete.topic.enable=true
-
启动(在slave1,slave2,slave3上)
#配置启动服务 vim /usr/lib/systemd/system/kafka.service [Unit] Description=kafka After=network.target [Service] Type=forking Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/jdk1.8.0_212/bin" WorkingDirectory=/data/kafka ExecStart=/data/kafka/bin/kafka-server-start.sh -daemon /data/kafka/config/server.properties ExecStop=/data/kafka/bin/kafka-server-stop.sh -daemon /data/kafka/config/server.properties User=root Group=root [Install] WantedBy=multi-user.target systemctl daemon-reload systemctl start kafka.service systemctl status kafka.service systemctl enable kafka.service
-
查看角色(在slave1,slave2,slave3上)
jps
-
验证(在slave1上操作即可)
#创建一个 topic cd /data/kafka_2.12-2.6.2/ ./bin/kafka-topics.sh --create --partitions 1 --replication-factor 1 --zookeeper slave3:2181 --topic aa #模拟生产者,发布消息 cd /data/kafka_2.12-2.6.2/ ./bin/kafka-console-producer.sh --broker-list slave2:9092 --topic aa #模拟消费者,接收消息 cd /data/kafka_2.12-2.6.2/ ./bin/kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic aa
使用
-
创建topic
bin/kafka-topics.sh --zookeeper hadoop102:2181 --create --replication-factor 3 --partitions 1 --topic first #选项说明: --topic 定义topic名 --replication-factor 定义副本数 --partitions 定义分区数
-
删除topic
bin/kafka-topics.sh --zookeeper hadoop102:2181 --delete --topic first #需要server.properties中设置delete.topic.enable=true否则只是标记删除或者直接重启。
-
发送消息
bin/kafka-console-producer.sh --broker-list hadoop102:9092 --topic first >hello world >atguigu atguigu
-
消费消息
bin/kafka-console-consumer.sh --zookeeper hadoop102:2181 --from-beginning --topic first #--from-beginning:会把first主题中以往所有的数据都读取出来。根据业务场景选择是否增加该配置。
-
查看
#查看当前服务器中的所有topic bin/kafka-topics.sh --zookeeper hadoop102:2181 --list #查看某个Topic的详情 bin/kafka-topics.sh --zookeeper hadoop102:2181 --describe --topic first
EFAk监控安装
监控安装(随便一个节点安装)
-
解压到本地
tar -zxvf kafka-eagle-bin-2.0.8.tar.gz -C /data/ cd /data/kafka-eagle-bin-2.0.8 tar -xvf efak-web-2.0.8-bin.tar.gz -C /data/ mv /data/efak-web-2.0.8/ /data/efak-web rm -rf /data/kafka-eagle-bin-2.0.8
-
添加环境变量
vim /etc/profile.d/my_env.sh #添加KE_HOME export KE_HOME=/data/efak-web export PATH=$PATH:$KE_HOME/bin source /etc/profile
-
修改配置文件
vim /data/efak-web/conf/system-config.properties #监控多套集群 efak.zk.cluster.alias=cluster1,cluster2 cluster1.zk.list=zookeeper1IP:2181,zookeeper2IP:2181,zookeeper3IP:2181 #cluster2.zk.list=xdn10:2181,xdn11:2181,xdn12:2181 #web界面访问端口 efak.webui.port=8048 # kafka offset存储位置 cluster1.efak.offset.storage=kafka #cluster2.efak.offset.storage=zk # kafka图标监控, 15 days by default efak.metrics.charts=true efak.metrics.retain=15 #kafka源数据信息sqlite 存储 #efak.driver=org.sqlite.JDBC #efak.url=jdbc:sqlite:/hadoop/kafka-eagle/db/ke.db #efak.username=root #efak.password=www.kafka-eagle.org # kafka sasl authenticate cluster1.efak.sasl.enable=false cluster1.efak.sasl.protocol=SASL_PLAINTEXT cluster1.efak.sasl.mechanism=SCRAM-SHA-256 cluster1.efak.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="kafka" password="kafka-eagle"; cluster1.efak.sasl.client.id= cluster1.efak.blacklist.topics= cluster1.efak.sasl.cgroup.enable=false cluster1.efak.sasl.cgroup.topics= #cluster2.efak.sasl.enable=false #cluster2.efak.sasl.protocol=SASL_PLAINTEXT #cluster2.efak.sasl.mechanism=PLAIN #cluster2.efak.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="kafka" password="kafka-eagle"; #cluster2.efak.sasl.client.id= #cluster2.efak.blacklist.topics= #cluster2.efak.sasl.cgroup.enable=false #cluster2.efak.sasl.cgroup.topics= # kafka ssl authenticate #cluster3.efak.ssl.enable=false #cluster3.efak.ssl.protocol=SSL #cluster3.efak.ssl.truststore.location= #cluster3.efak.ssl.truststore.password= #cluster3.efak.ssl.keystore.location= #cluster3.efak.ssl.keystore.password= #cluster3.efak.ssl.key.password= #cluster3.efak.ssl.endpoint.identification.algorithm=https #cluster3.efak.blacklist.topics= #cluster3.efak.ssl.cgroup.enable=false #cluster3.efak.ssl.cgroup.topics= #kafka源数据信息mysql存储 efak.driver=com.mysql.cj.jdbc.Driver efak.url=jdbc:mysql://127.0.0.1:3306/efakweb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull efak.username=efakweb efak.password=efakweb
-
启动
/data/efak-web/bin/ke.sh start /data/efak-web/bin/ke.sh stop
-
访问
http://192.168.9.102:8048/ke
admin/123456
喜欢的亲可以关注点赞评论哦!以后每天都会更新的哦!本文为小编原创文章; 文章中用到的文件、安装包等可以加小编联系方式获得;
欢迎来交流小编联系方式VX:CXKLittleBrother 进入运维交流群