Kafka

目录

Kafka是什么

Kafka的特性

Kafka系统架构

topic

partition

broker

[consumer group](#consumer group)

offset

zookeeper

部署安装kafka


假设一个程序员在维护两个服务器,一个是A另一个是B,A每秒发出200个消息,B每秒只能处理100个消息,此时B是接收不过来的,常规情况下要么"开源"要么"节流",减少A发出的消息数量,或者增加B的处理速度,最简单直接的就是再增设一台C服务器用来帮助B进行负载均衡,但这样做成本太高,有什么办法可以让B独自处理来自A的消息而且不会导致自身因为超出负荷而瘫痪呢?

没有什么是增加中间层解决不了的,我们在两个服务器之间添加一个消息队列,A发送的消息首先进入消息队列,然后由消息队列发送至B服务器,常用的消息队列就是Kafka

Kafka是什么

Kafka就是一个消息队列,所以如果问kafka是什么,就相当于问消息队列是什么,消息队列就是通过将消息放在内存中的队列中,可以保护消息不被丢失。但是,这会带来性能问题,因此可以将队列挪到一个单独的进程中,从而解决性能问题。此外,还可以通过分区、分片、添加副本来扩展消息队列,提高性能和可用性。

Kafka的特性

高吞吐量、低延迟

可扩展性,kafka集群支持热扩展

持久化、可靠性,消息呗持久化到本地磁盘,并且支持数据备份防止数据丢失

容错性,允许集群中的某个或某系节点下线的情况存在

高并发,支持数千个客户端同时读写

Kafka系统架构

Kafka通过将消息放入队列中,减轻了消息处理端的负载,将消息放入消息队列的一端称为生产者,处理消息的一段称为消费者。但是话又说回来,消息队列说到底也只是一个缓冲区,只能作为缓兵之计,如果生产的消息在很长一段时间甚至几年内都处于居高不下的状态,那该花钱还是得花钱,为了提升性能和扩展性,可以增加消费者和生产者的数量,并通过分区和副本来保证高可用性。

topic

随着生产者和消费者的增多,慢慢的消息队列开始变得拥堵,就会出现多个生产者或消费者争抢一个消息队列的情况,这时候该如何做呢?面多加水,水多加面呗,我们再增加一条消息队列不就可以了?不多再多增一条未免有些麻烦了,在消息队列内部就直接进行分类,每一类是一个topic,然后根据topic新增队列的数量, 生产者根据 topic 主题的不同,将消息投递到不同的队列中,消费者根据订阅的消息的类型,从相应的队列中读取消息。

partition

每个topic代表不同类型或主题的消息,自然有多有少,像系统进程允许之类的日志,消息是非常多的,就导致这个topic 处理的请求也过多,来不及处理,此时可将 topic 拆分成好几段,每段就是一个partition分区,每个消费者负责一个partition,这样每个消费者负责一个partition分区,大大降低了消息队列堵塞的可能性

每个 partition 有多个副本(Replica),其中有且仅有一个作为 Leader,Leader 是当前负责数据的读写的 partition。Follower 跟随 Leader,所有写请求都通过 Leader 路由,数据变更会广播给所有 Follower, Follower 与 Leader 保持数据同步。Follower 只负责备份,不负责数据的读写。 如果 Leader 故障,则从 Follower 中选举出一个新的 Leader。 当 Follower 挂掉、卡住或者同步太慢,Leader 会把这个 Follower 从 ISR(Leader 维护的一个和 Leader 保持同步的 Follower 集合) 列表中删除,重新创建一个 Follower。

broker

当然,如此多的partition分布在一台机器上,肯定会造成机器负载,将partition分布在不同的机器上,可以大大减少这方面问题,每台机器就是一个broker,一个broker 中有多个topic,每个topic被划分为不同的partition

当 broker 存储 topic 的数据时,如果某 topic 有 N 个 partition,集群有 N 个 broker,那么每个 broker 存储该 topic 的一个 partition;如果某 topic 有 N 个 partition,集群有 (N+M) 个 broker,那么其中有 N 个 broker 存储 topic 的 一个 partition, 剩下的 M 个 broker 不存储该 topic 的 partition 数据;如果某 topic 有 N 个 partition,集群中 broker 数目少于 N 个,那么一个 broker 存储该 topic 的 一个或多个 partition,实际情况中,避免broker数少于partition,这种情况容易导致 Kafka 集群数据不均衡

consumer group

消费者组,由多个 consumer 组成,消费者组内的消费者共同消费一个或多个topic,消费者组之间互不干扰

offset

消息队列如是工作,假如有一天broker挂了,那岂不是数据全部都丢失了?所以,不能仅仅将数据放在内存中,还要将其持久化到磁盘中,这样数据的安全性便有了保障,但是新的问题出现了,如果broker挂了,之后进行了数据恢复,消费者再次去拉取消息,应该从何处开始。这里就引入了一个新的概念 offset(偏移量),记录消费者读取数据的位置,以便下次直接读取。当然,还有一个问题,这样一直持久化下去,磁盘空间会越来越少,所以要对这部分持久化的数据进行定期清理,默认周期时 7*24小时

zookeeper

到这里,整个体系已经由原来的AB两台机器中间的消息队列,扩展到相当多的组件了,而且每个组件都有自己的数据和状态,所以,就需要有一个组件来统一维护和管理这些组件的状态信息,zookeeper就是扮演着这个角色,掌握kafka的状态信息

部署安装kafka

在官网中下载kafka压缩包或者安装包 放在/opt下

cd /opt

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 #21行,broker的全局唯一编号,不重复,因此其他机器上不能为0

listeners=PLAINTEXT://172.16.233.105:9092 #31行,指定坚挺的ip和端口号

num.network.threads=3 #42行,broker 处理网络请求的线程数量

num.io.threads=8 #45行,用来处理磁盘IO的线程数量,数值应该大于硬盘数

socket.send.buffer.bytes=102400 #48行,发送套接字的缓冲区大小

socket.receive.buffer.bytes=102400 #51行,接收套接字的缓冲区大小

socket.request.max.bytes=104857600 #54行,请求套接字的缓冲区大小

log.dirs=/usr/local/kafka/logs #60行,kafka运行日志存放的路径,也是数据存放的路径

num.partitions=1 #65行,topic在当前broker上的默认分区数,topic创建时指定参数会覆盖

num.recovery.threads.per.data.dir=1 #69行,用来恢复和清理data下数据的线程数量

log.retention.hours=168 #103行,segment 文件保留的最长时间,单位h,默认7天删除

log.segment.bytes=1073741824 #110行,一个segment文件最大的大小,默认为1G

zookeeper.connect=172.16.233.105:2181,172.16.233.106:2181,172.16.233.107:2181

#123行,配置连接zookeeper集群地址

保存退出

修改环境变量

vim /etc/profile

export KAFKA_HOME=/usr/local/kafka

export PATH=PATH:KAFKA_HOME/bin

source /etc/profile

配置 zookeeper 启动脚本

vim /etc/init.d/kafka

#!/bin/bash

#chkconfig:2345 22 88

#description:kafka Service Control Script

KAFKA_HOME='/usr/local/kafka'

case $1 in

start)

echo "-------------- kafka 启 动 -------------------"

${KAFKA_HOME}/bin/kafka-server-start.sh -daemon

${KAFKA_HOME}/config/server.properties

;;

stop)

echo "-------------- kafka 停 止 -------------------"

${KAFKA_HOME}/bin/kafka-server-stop.sh

;;

restart)

$0 stop

$0 start

;;

status)

echo "-------------- kafka 状 态 -------------------"

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

启动kafka

service kafka start

kafka已经安装部署完成

下面是kafka操作命令

创建topic

kafka-topics.sh --create --zookeeper

172.16.233.105:2181,172.16.233.106:2181,172.16.233.107:2181 --replication-factor 2 --partitions 3 --topic test

查看当前服务器中的所有 topic

172.16.233.105:2181,172.16.233.106:2181,172.16.233.107:2181

相关推荐
一只编程菜鸟1 小时前
SpringCloud Alibaba之Seata处理分布式事务
分布式·spring·spring cloud
陈吉俊2 小时前
spark 广播和累加器
大数据·分布式·spark
喻师傅2 小时前
Hadoop FileSystem Shell 常用操作命令
大数据·hadoop·分布式·shell命令
pblh1232 小时前
2023_Spark_实验十一:RDD基础算子操作
大数据·分布式·spark
月夜星辉雪4 小时前
【RabbitMQ 项目】客户端:消费者模块
c++·分布式·rabbitmq
longlongqin4 小时前
Kafka 面试题
kafka
happycao1234 小时前
kafka 消费者线程安全问题详细探讨
分布式·中间件·kafka·消息队列
神一样的老师7 小时前
物联网网络中集中式与分布式SDN环境的比较分析
网络·分布式·物联网
月夜星辉雪8 小时前
【RabbitMQ 项目】服务端:服务器模块
服务器·分布式·rabbitmq