一、zookeeper概述
zookeeper是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务,状态同步,配置中心,集群管理等。
在分布式环境下,经常需要对应用/服务进行统一命名,便于识别
命名服务:命名服务是分布式系统中比较常见的一类场景。命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等——这些我们都可以统称它们为名字(name),其中较为常见的就是一些分布式服务框架(如 rpc、rmi)中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息等。
状态同步:每个节点除了存储数据内容和 node 节点状态信息之外,还存储了已经注册的app 的状态信息,当有些节点或 app 不可用,就将当前状态同步给其他服务。
配置中心:配置管理可交由zookeeper实现。可将配置信息写入zookeeper上的一个znode。各个客户端服务器监听这个znode。一旦 znode中的数据被修改,zookeeper将通知各个客户端服务器。
集群管理:所谓集群管理,包括集群监控与集群控制两大块,前者侧重对集群运行时状态的收集,后者则是对集群进行操作与控制,在日常开发和运维过程中,我们经常会有类似于如下的需求:
分布式环境中,实时掌握每个节点的状态是必要的。可根据节点实时状态做出一些调整。
二、zookeeper特性
zookeeper = 文件系统 + 通知机制
客户端如果对 zookeeper 的一个数据节点注册 watcher 监听,那么当该数据节点的内容或是其子节点列表发生变更时,zookeeper 服务器就会向订阅的客户端发送变更通知。
对在 zookeeper 上创建的临时节点,一旦客户端与服务器之间的会话失效,那么该临时节点也就被自动清除。
watcher(事件监听器),是zookeeper中的一个很重要的特性。zookeeper允许用户在指定节点上注册一些watcher,并且在一些特定事件触发的时候,zookeeper服务端会将事件通知到感兴趣的客户端上去,该机制是zookeeper实现分布式协调服务的重要特性。
三、集群介绍
在zookeeper集群中,有各自的角色,分为领导者leader,学习者learner(跟随者follower,观察者observer)
领导者主要工作:事务请求的唯一调度和处理者,保证集群事务处理的顺序性;集群内部个服务器的调度者。
跟随者:处理客户端非事务请求,转发事务请求给leader服务器;参与事务请求proposal的投票;参与leader选举的投票。
观察者:follower和observer唯一的区别在于observer机器不参与leader的选举过程,也不参与写操作的“过半写成功”策略,因此observer机器可以在不影响写性能的情况下提升集群的读性能。
选举机制:leader
集群特性:
四、消息队列
消息队列(message queue)是为了实现各个app之间的通讯,app基于mq实现消息的发送和接收应用程序之间的通讯,这样多个应用程序可以运行在不同的主机上,通过mq就可以实现夸网络通信,因此mq实现了业务的解耦和异步机制。
mq分类:
目前主流的消息队列软件有rabbitmq,kafka,activemq,rocketmq等,还有小众的消息队列软件如zeromq,apacheqpid等。
同步处理:
异步处理:
kafka优势:
1.高吞吐量、低延迟
kafka 每秒可以处理几十万条消息,它的延迟最低只有几毫秒。每个 topic 可以分多个 partition,consumer group 对 partition 进行消费操作,提高负载均衡能力和消费能力。
2.可扩展性
kafka 集群支持热扩展
3.持久性、可靠性
允许集群中节点失败(多副本情况下,若副本数量为 n,则允许 n-1 个节点失败)kafka 通过 o(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以 tb 的消息存储也能够保持长时间的稳定性能
4.容错性
- 允许集群中节点失败(多副本情况下,若副本数量为 n,则允许 n-1 个节点失败)
高并发 支持数千个客户端同时读写
kafka角色:
broker:kafka集群包含一个或多个服务器,这种服务器被称为broker。
- topic :每条发布到 kafka 集群的消息都有一个类别,这个类别被称为 topic,(物理上不同 topic 的消息分开存储在不同的文件夹,逻辑上一个 topic 的消息虽然保存于一个或多个 broker 上但用户只需指定消息的 topic 即可生产或消费数据而不必关心数据存于何处),topic 在逻辑上对 record(记录、日志)进行分组保存,消费者需要订阅相应的 topic 才能消费 topic 中的消息。
- partition :是物理上的概念,每个 topic 包含一个或多个 partition,创建 topic 时可指定 parition 数量,每个partition对应于一个文件夹,该文件夹下存储该partition的数据和索引文件,为了实现实现数据的高可用,比如将分区 0的数据分散到不同的kafka节点,每一个分区都有一个broker作为leader 和一个 broker作为follower。
- producer:负责发布消息到 kafka broker
- consumer:消费消息,每个 consumer 属于一个特定的 consuer group(可为每个consumer 指定 group name,若不指定 group name 则属于默认的 group),使用consumer high level api 时,同一 topic 的一条消息只能被同一个 consumer group内的一个 consumer 消费,但多个 consumer group 可同时消费这一消息。
五、zookeeper与kafka
由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢复后继续消费。
kafka 0.9 版本之前,consumer 默认将 offset 保存在 zookeeper 中;从 0.9 版本开始,consumer 默认将 offset 保存在 kafka 一个内置的 topic 中,该 topic 为 __consumer_offsets。
也就是说,zookeeper的作用就是,生产者push数据到kafka集群,就必须要找到kafka集群的节点在哪里,这些都是通过zookeeper去寻找的。消费者消费哪一条数据,也需要zookeeper的支持,从zookeeper获得offset,offset记录上一次消费的数据消费到哪里,这样就可以接着下一条数据进行消费。
部署kafka需要先部署zookeeper
5.1 部署zookeeper
需要三台服务器:
前期准备:防火墙和核心防护,三台机器。
需要依赖java环境:
java版本:
[root@node1 data]#:java -version
openjdk version "1.8.0_412"
openjdk runtime environment (build 1.8.0_412-b08)
openjdk 64-bit server vm (build 25.412-b08, mixed mode)
下载安装zookeeper:
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
[root@node1 data]#:wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
#解压
[root@node1 data]#:tar xf apache-zookeeper-3.5.7-bin.tar.gz
[root@node1 data]#:ls
apache-zookeeper-3.5.7-bin apache-zookeeper-3.5.7-bin.tar.gz
#移动到/usr/local/下并改名为zookeeper
[root@node1 data]#:mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper
修改配置文件:
修改目录,和日志目录,添加集群信息
[root@node1 data]#:cd /usr/local/zookeeper/conf/
[root@node1 conf]#:ls
configuration.xsl log4j.properties zoo_sample.cfg
#先做个备份
[root@node1 conf]#:cp -a zoo_sample.cfg zoo.cfg
[root@node1 conf]#:vim zoo.cfg
......
datadir=/usr/local/zookeeper/data
datalogdir=/usr/local/zookeeper/logs
......
server.1=192.168.114.10:3188:3288
server.2=192.168.114.20:3188:3288
server.3=192.168.114.30:3188:3288
在zookeeper目录下创建两个文件夹data,logs
[root@node1 conf]#:cd ..
[root@node1 zookeeper]#:mkdir logs data
[root@node1 zookeeper]#:ls
bin conf data docs lib license.txt logs notice.txt readme.md readme_packaging.txt
在每个节点生成serverid
[root@node1 zookeeper]#:echo 1 > data/myid
将zookeeper远程传给另外两台服务器上:并修改serverid
[root@node1 zookeeper]#:cd ..
[root@node1 local]#:scp -r zookeeper 192.168.114.20:/usr/local/
[root@node1 local]#:scp -r zookeeper 192.168.114.30:/usr/local/
#修改serverid
[root@node2 zookeeper]#:echo 2 > data/myid
[root@node3 zookeeper]#:echo 3 > data/myid
启动zookeeper
把其他两台启动后,再看状态:
[root@node2 zookeeper]#:bin/zkserver.sh start
/usr/bin/java
zookeeper jmx enabled by default
using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
starting zookeeper ... started
[root@node3 zookeeper]#:bin/zkserver.sh start
/usr/bin/java
zookeeper jmx enabled by default
using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
starting zookeeper ... started
可以在node2上看到leader
5.2 部署kafka
准备kafka的安装包
[root@node1 data]#:ls
apache-zookeeper-3.5.7-bin.tar.gz kafka_2.13-2.7.1.tgz
#解压到指定路径下
[root@node1 data]#:tar xf kafka_2.13-2.7.1.tgz -c /usr/local/
[root@node1 data]#:cd /usr/local/
做个软连接
[root@node1 local]#:ln -s kafka_2.13-2.7.1/ kafka
进入配置文件
[root@node1 local]#:cd kafka/config/
修改配置文件,修改以下配置项
[root@node1 local]#:vim server.properties
......
broker.id=0
listeners=plaintext://192.168.114.10:9092
log.dirs=/usr/local/kafka/logs
zookeeper.connect=192.168.114.10:2181,192.168.114.20:2181,192.168.114.30:2181
......
其他两台服务器同理:
这里直接将node1的配置文件传过去:
对node2和node3做个修改:
[root@node2 local]#:cd /usr/local/kafka/config/
[root@node2 config]#:vim server.properties
broker.id=1
listeners=plaintext://192.168.114.20:9092
创建logs文件夹:
[root@node2 config]#:cd ..
[root@node2 kafka]#:mkdir logs
[root@node3 local]#:cd /usr/local/kafka/config/
[root@node3 config]#:vim server.properties
broker.id=2
listeners=plaintext://192.168.114.30:9092
[root@node3 config]#:cd ..
[root@node3 kafka]#:mkdir logs
启动kafka:
[root@node1 bin]#:cd /usr/local/kafka/bin/
查看三台服务器的端口,观察连接状态
node2为leader。与node1和node3连接
5.3 测试
1.创建topic:
[root@node2 bin]#:./kafka-topics.sh --create --zookeeper 192.168.114.10:2181,192.168.114.20:2181,192.168.114.30:2181 --replication-factor 2 --partitions 3 --topic test
2.查看当前服务器中所有的topic
[root@node2 bin]#:./kafka-topics.sh --list --zookeeper 192.168.114.10:2181,192.168.114.20:2181,192.168.114.30:2181
test
3.查看某个topic的详情
[root@node1 bin]#:./kafka-topics.sh --describe --zookeeper 192.168.114.10:2181,192.168.114.20:2181,192.168.114.30:2181
topic: test partitioncount: 3 replicationfactor: 2 configs:
topic: test partition: 0 leader: 1 replicas: 1,0 isr: 1,0
topic: test partition: 1 leader: 3 replicas: 3,1 isr: 3,1
topic: test partition: 2 leader: 0 replicas: 0,3 isr: 0,3
在任意一台主机上都能看到。
发布消息:
[root@node2 bin]#:./kafka-console-producer.sh --broker-list 192.168.114.10:9092,192.168.114.20:9092,192.168.114.30:9092 --topic test
>1
>2
>3
>4
消费消息:
[root@node3 bin]#:./kafka-console-consumer.sh --bootstrap-server 192.168.114.10:9092,192.168.114.20:9092,192.168.114.30:9092 --topic test --from-beginning
1
2
3
4
删除topic:
[root@node3 bin]#:./kafka-topics.sh --delete --zookeeper 192.168.114.10:2181,192.168.114.20:2181,192.168.114.30 --topic test
topic test is marked for deletion.
note: this will have no impact if delete.topic.enable is not set to true.
---end---
发表评论