文章目录
Zookeeper时一款开源的分布式的,为分布式框架提供协调服务的Apache项目。 它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
Zookeeper特点
- 一个leader,多个follower组成的集群
- zookeeper集群中只要有半数以上节点存活,zookeeper就能正常提供服务,所以zookeeper适合奇数台服务器
- 全局数据一致,每个server保存一份相同的数据副本,client无论连接哪个,数据都是一致的
- 更新请求数据执行,来自同一个client的更新请求按照发送顺序一次执行,即先进先出
- 数据更新原子性,一次数据要么成功,要么失败
- 实时性,在一定时间范围内,client能读到最新的数据
zookeeper数据结构 zookeeper数据模型的结构与linux文件系统类似,整体可看做一颗树,每个节点称作一个znode;每个znode能存储1M数据,每个znode都可以通过器其径唯一标识。
zookeeper提供的服务
统一的命名服务
在分布式环境下,经常对应用,服务进行统一命名,便于识别
统一配置管理
1.分布式环境下,配置文件同步非常常见,一般要求一个集群中,所有节点的配置信息是一致的 2.配置管理可交给zookeeper实现,将配置信息写入zookeeper上的一个znode节点,各个服务端监听这个znode,一旦被修改,zookeeper将通知各个客户端服务器
统一集群管理
1.分布式环境中,实时掌握每个节点的状态是必要的,可根据节点实时状态做出一些调整 2.zookeeper可以实现实时监控节点的状态变化,可将节点信息写入zookeeper上的一个znode,监听这个znode获取它的实时状态变化
服务器动态上下线
客户端能实时洞察到服务器的上下线变化
软负载均衡
在zookeeper中记录每台服务器的访问数量,让访问数量最少的服务器取处理最新的客户端请求
zookeeper选举机制 第一次选举: 1.服务器1启动时,发起一次选举,投自己一票,不够半数,选举无法完成,服务器保持looking 2.服务器2启动时,在发起一次选举,各自投自己一票;服务器1发现服务器2的myid比它大,更改投票给服务器2,,此时服务器1零票,服务器2两票,未到半数,选举无法完成,状态保持looking 3.服务器3启动时,再次进行选举,投票参考服务器2启动;投票完成后,发现票数已经过半,则选举服务器3为leader,服务器1,2状态改为following,服务器3更改为leading; 4.后续还有服务器启动时,仍发起选举,但其他服务器状态已经不是looking,不会改变投票结果,服务器4会将选票改为服务器3,并更改本身状态following; 5.服务器5启动同服务器4启动
非第一次启动: 集群中服务器出现以下两种情况会开始进入leader选举 服务器初始启动 服务器无法和leader保存连接
当一台服务器进入leader选举时 集群中已经存在leader
对于已经存在Leader的情况,机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连接,并进行状态同步即可。
集群中不存在leader
选举规则: 1.EPOCH大的直接胜出 2.EPOCH相同,事务ID大的胜出 3.事务ID相同,服务器ID大的胜出
SID:服务器ID。用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致 ZXID:事务ID。ZXID是一个事务ID,用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID值不一定完全一致,这和ZooKeeper服务器对于客户端"更新请求"的处理逻辑速度有关 Epoch:每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加
部署zookeeper集群
集群节点:
192.168.74.222
192.168.74.208
192.168.74.111
----------------------------------
systemctl stop firewalld
setenforce 0
java -version
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
1.安装zookeeper
cd /opt
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
tar zxvf apache-zookeeper-3.5.7-bin.tar.gz
mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper
2.修改配置文件
cp /usr/local/zookeeper/conf/zoo_sample.cfg zoo.cfg
vim /usr/local/zookeeper/conf/zoo.cfg
mkdir /usr/local/zookeeper/data
mkdir /usr/local/zookeeper/data/logs
对应节点服务上创建myid文件
echo 1 > /usr/local/zookeeper/data/myid
echo 2 > /usr/local/zookeeper/data/myid
echo 3 > /usr/local/zookeeper/data/myid
配置启动脚本
vim /etc/init.d/zookeeper
zo_home='/usr/local/zookeeper/bin/zkServer.sh'
case $1 in
start)
$zo_home start
;;
stop)
$zo_home stop
;;
restart)
$zo_home restart
;;
status)
$zo_home status
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
---------------------------
chkconfig --add zookeeper
service zookeeper start
service zookeeper status
在高并发环境下,同步请求来不及处理,容易引发阻塞;使用消息队列,通过异步处理,可缓解系统的压力。消息队列常用于异步处理,流量削峰,应用解耦,消息通讯等;
解耦
允许独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束
可恢复性
系统一部分组件失效时,不会相应整个系统,消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息让可以在系统恢复后被处理
缓冲
有助于控制和优化数据流经过系统的速度,解决生产消息的处理速度不一致的情况
削峰
在访问量剧增的情况下,应用仍需发挥作用,如果以高标准要求服务器性能,是一种浪费;使用消息队列能够使关键组件顶住突发压力,而不会因为突发的超负荷的请求而导致服务崩溃
异步通信
消息队列提供异步处理机制,允许用户将消息放入队列,但不并立即处理
消息队列的两种模式 1.点对点模式(一对一,消费者主动拉取数据,接收后消息清除): 消费生产者生产消息发送到消息队列,消息消费者从消息队列取出并消费消息。消息被消费后,消息队列不在存储,所有消费者消费的一定是未被消费过的消息。消息队列支持存在多个消费者,但一个消息,只会给一个消费者消费。
2.发布/订阅模式(一对多,又叫观察者模式,消费者消费数据后不会清除): 消息生产者将消息发布到topic中,同时有多个消费者消费该消息。和点不点不同,发布的消息会被所有订阅者消费。发布/订阅模式是定义对象间一种一对多的依赖关系,使得每当一个对象的状态发生改变,则所有依赖于它的对象都会得到通知并自动更新。
kafka是一个分布式的基于发布/订阅模式的消息队列。
Kafka特性: 高吞吐量,低时延
kafka每秒可以处理几十万条消息,它的延时最低只有几毫秒;每个topic可以分为Partition,consumer group对Partition进行消费操作,提高负载能力和消费能力
可扩展性
kafka 集群支持热扩展
持久性、可靠性
消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
容错性
允许集群中节点失败,即使只有一个节点能正常工作,也能保证服务的正常使用
高并发
支持数千个客户端同时读写
Kafka系统架构
Broker
一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic
Topic
可以理解为队列,生产者和消费者面向的都是一个topic
Partition
一个非常大的topic可以分布到多个broker上,一个topic可以分割为一个或多个partition,每个partition是一个有序队列;Kafka 只保证 partition 内的记录是有序的,而不保证 topic 中不同 partition 的顺序
Leader
每个 partition 有多个副本,其中有且仅有一个作为 Leader,Leader 是当前负责数据的读写的 partition
Follower
Follower 跟随 Leader,所有写请求都通过 Leader 路由,数据变更会广播给所有 Follower,Follower 与 Leader 保持数据同步。Follower 只负责备份,不负责数据的读写。 如果 Leader 故障,则从 Follower 中选举出一个新的 Leader。 当 Follower 挂掉、卡住或者同步太慢,Leader 会把这个 Follower 从 ISR(Leader 维护的一个和 Leader 保持同步的 Follower 集合) 列表中删除,重新创建一个 Follower
Replica
副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader 和若干个 follower
Producer
生产者即数据的发布者,该角色将消息发布到 Kafka 的 topic 中。 broker 接收到生产者发送的消息后,broker 将该消息追加到当前用于追加数据的 segment 文件中。 生产者发送的消息,存储到一个 partition 中,生产者也可以指定数据存储的 partition
Consumer
消费者可以从 broker 中读取数据。消费者可以消费多个 topic 中的数据
Consumer Group
消费者组,由多个 consumer 组成;消费者之前互不影响,将多个消费者集中到一起去处理某一个 Topic 的数据,可以更快的提高数据的消费能力;消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费,防止数据被重复读取
offset
偏移量,可以唯一的标识一条消息;偏移量决定读取数据的位置,不会有线程安全的问题,消费者通过偏移量来决定下次读取的消息; 消息被消费之后,并不被马上删除,这样多个业务就可以重复使用 Kafka 的消息。 某一个业务也可以通过修改偏移量达到重新读取消息的目的,偏移量由用户控制。 消息最终还是会被删除的,默认生命周期为 1 周
Zookeeper
Kafka 通过 Zookeeper 来存储集群的 meta 信息
部署zookeeper+kafka集群
zookeeper集群:
192.168.74.222
192.168.74.208
192.168.74.111
--------------------------------------------------
1.zookeeper集群部署
2.安装kafka
tar zxvf kafka_2.13-2.7.1.tgz
mv kafka_2.13-2.7.1 /usr/local/kafka
cd /usr/local/kafka/config/
cp server.properties{,.bak}
vim server.properties
broker.id=0
listeners=PLAINTEXT://192.168.74.208:9092
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/usr/local/kafka/logs
num.partitions=1
num.recovery.threads.per.data.dir=1
log.retention.hours=168
log.segment.bytes=1073741824
zookeeper.connect=192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181
----------------------------------------------------------------
3.修改环境变量
vim /etc/profile
export KAFKA_HOME=/usr/local/kafka
export PATH=$PATH:$KAFKA_HOME/bin
source /etc/profile
4.配置启动脚本
vim /etc/init.d/kafka
KAFKA_HOME='/usr/local/kafka'
case $1 in
start)
${KAFKA_HOME}/bin/kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties
;;
stop)
${KAFKA_HOME}/bin/kafka-server-stop.sh
;;
restart)
$0 stop
$0 start
;;
status)
count=$(ps -ef | grep kafka | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
echo "kafka is not running"
else
echo "kafka is running"
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
esac
----------------------------------------
chmod +x /etc/init.d/kafka
chkconfig --add kafka
service kafka start
kafka命令操作
1.创建topic
kafka-topics.sh --create --zookeeper 192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181 --replication-factor 2 --partitions 3 --topic chh
--zookeeper:定义 zookeeper 集群服务器地址,如果有多个 IP 地址使用逗号分割,一般使用一个 IP 即可
--replication-factor:定义分区副本数,1 代表单副本,建议为 2
--partitions:定义分区数
--topic:定义 topic 名称
2.查看当前服务器中的所有/某个topic
kafka-topics.sh --list --zookeeper 192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181
kafka-topics.sh --describe --zookeeper 192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181
3.发布消息
kafka-console-producer.sh --broker-list 192.168.74.208:9092,192.168.74.222:9092,192.168.74.111:9092 --topic chh
4.消费消息
kafka-console-consumer.sh --bootstrap-server 192.168.74.208:9092,192.168.74.222:9092,192.168.74.111:9092 --topic chh --from-beginning:会把主题中以往所有的数据都读取出来
5.修改分区数
kafka-topics.sh --zookeeper 192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181 --alter --topic chh --partitions 6
6.删除topic
kafka-topics.sh --delete --zookeeper 192.168.74.208:2181,192.168.74.222:2181,192.168.74.111:2181 --topic chh
|