大数据分布式发布订阅系统Kafka(一)

大数据分布式发布订阅系统Kafka

第一章 Kafka背景介绍

Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。
Kafka主要用于处理活跃的流式数据,如果看过我的其他博客的话,就会对流式数据有大致的印象;活跃的流式数据在Web网站应用中很是常见,这些数据包括网站的PV、UV的统计、用户点击的内容或者浏览的什么商品等等,通过web的埋点手段加上后台日志的设计,将每条日志记录下来,之后将记录下来的日志整理、数据清洗、数据分析等一系列技术手段,进而将潜在的数据价值直观的展现出来。
其中kafka的特性主要有以下几个方面:

  1. 通过O(1)时间复杂度的磁盘数据结构Zero-Copy技术提供消息的持久化机制,TB级别甚至PB级别数据也能够长时间的稳定存储
  2. 即使是最普通的硬件搭建kafka环境,也可以支持达到每秒百万的消息传递
  3. 支持Hadoop并行加载数据
  4. 支持通过Kafka服务器和消费机集群来分区消息

了解了kafka相关的背景以及特性之后,更加深我们对于这门技术的学习与理解,下面我们需要仔细阅读每句话,不管是平时学习或者是项目中都会有至关重要的帮助。

官网大图镇贴~~:在这里插入图片描述

第二章 Kafka架构与设计

首先在我们步入学习正轨之前需要先了解下kafka的内置角色;在整个kafka的架构设计中包含了三个角色:

  1. 生产者(Producer): 消息和数据的产生者
  2. 消费者 (Consumer) : 消息和数据的处理者
  3. 代理 (Broker) : 缓存代理者,kafka的核心角色

kafka的整体架构设计相信在了解过其他大数据相关的组件之后会发现其实并不是很复杂,那么下面我会基于上述三个角色给出整体架构流程图以及相关的功能介绍,使大家有更加清晰的思路:

kafka架构设计图(该图片由百度亲情提供~~感谢度娘^^) :

在这里插入图片描述
kafka给Producer和Consumer提供注册的接口,数据从Producer发送到Broker中,其中Broker承担一个缓存和分发的作用,负责分发数据到注册到系统中的Consumer.
另外上图中画出了Zookeeper,如果有对ZK并不是很熟悉的同学,目前可以先不用着急学习,关于ZK和kafka以及Hadoop相关的知识会在以后统一为大家讲解,目前可以先放置一边,先从最基本的架构设计和整体数据传输流程搞起。

下面深入kafka底层为同学们介绍下:

  • kafka设计要点

首先通过上述第一章的介绍,各位同学们可能心里都认为kafka是十分高效的一款数据中间件(就算认为一般或者丝毫不感兴趣的各位同学,先且认为是十分高效,请耐心听我娓娓道来~)
下面从以下两个方面为大家介绍:
1.数据层面:直接采用的是Linux文件系统的Cache来高效缓存数据(走内存的形式)
2.传输层面:采用Linux Zero-Copy技术来提高数据发送性能;目前我们所知道的是传统的数据在文件系统中的发送是通过4次上下文的切换,极大的消耗了数据磁盘IO的性能;而kafka却是采用SendFile系统调用后,数据直接在内核态进行交换只需要2次上下文的切换,根据可靠的测试得知大约可提高60%的数据传输性能,并且数据在磁盘上的时间复杂度为O(1)
ps:关于Linux Zero-Copy 技术相关知识:https://www.jianshu.com/p/8b8cd0e1090d
传输数据嗖嗖的~

ps:一言不合就上图

在这里插入图片描述

从上图可以看出:kafka是以Topic(主题)来进行数据管理,每个Topic中包含着多个Partition(分区),每个分区对应着一个Log文件,该文件又由多个Segment(文件段)组成。每个文件段中存储着多个消息,其中消息的ID由其逻辑位置决定(即从消息ID可直接定位到消息的存储位置),另外在每个分区也同样对应着一个.index文件,记录每个文件段中的第一条消息的偏移量(数据的位置)
如下图所示:
在这里插入图片描述
数据存储流程:数据由Producer发送到Broker时,由Broker决定(随机或者用户指定的回调函数发送)当前数据发送到某个Topic的哪个Partition(分区)中,确定下来之后会直接在这个分区的最后一个Segment(文件段)中添加该消息;当一个Segment写满时(一个Segment达到阈值)会进行flush操作,将该Segment中的数据刷新到磁盘上,同学们需要注意的:消费者只能消费已经刷新到磁盘上的数据,Segment一旦出发flush机制就不会再继续写入同时Broker会重新创建Segment;一旦Broker创建出新的Segment后,会在.index文件中将新创建的Segment的头数据写入,从而标记出数据的存储具体在哪个Segment文件中。

  • kafka消息存储方式

通过第一小节的学习,相信同学们已经对kafka的数据存储方式已经有了大致的印象,不过难免有些同学对该数据存储模型还是些许生疏,接下来还会继续的深入底层,为大家探究kafka的消息存储方式
kafka中大家需要详细的学习下Topic的概念,以及Topic的内置模型。Topic中文翻译为:主题、类别;其实本质上Topic的意义也不过如此:需要将一个类别的消息发送到同一个Topic中,这样做的目的和好处不言而喻,使得我们不需要对同一个Topic中的数据再基于业务层面进行数据上的划分。
另外,需要同学们知道的是:对于每个Topic(主题),kafka集群都会维护该Topic下每个Partition(分区)的Log,这就不难想象出来对于每个分区来说数据存储必然是有序的,不可变的消息队列。
ps : 同学们心中必然是存在疑问,为何可以判断出来?如何证明?
哈哈哈,其实从上一小节中提出了index索引文件和Segment的概念后,大家就不难想象,如果数据在每个Partition中存储是无序、可变的情况下,就不会在每个Segment写满经过flush操作,Broker生成新的Segment文件后将新的Segment文件的第一条数据记录到index文件中,如果我们需要只记录第一条数据的情况,那么必然数据是依此有序,只有有序列表才可以通过顺序查找到指定的offset的数据。
ps:需要同学们思考一个问题:一个分区内部数据是有序的,但是多个分区之间可以保证其数据是顺序的嘛? 欢迎大家踊跃在评论区留言!

上图喽~ :
在这里插入图片描述

另外,在上面最后一句话中提到了offset(偏移量)的概念,现在我们知道了Topic中的每个分区数据是有序、不可变的队列,那么每个分区中的数据所指代的一个序列号就称之为offset(偏移量)。当然了,每个分区中的偏移量都是唯一的,增长是按照单调递增发展。
对于消费者来说,能获取的唯一元数据就是这个offset,根据每个分区的offset到Log文件下的Segment文件中获取到对应具体的订阅数据信息;当然了,不难想象出消费者是可以手动控制其偏移量,通过修改offset,可以达到重复消费数据的目的,有时候在解决具体生产问题时恰恰需要手动修改其偏移量来定位和修复问题。

在本小节结束的时候最后跟各位同学讨论下:为何kafka要设计成多个分区的模式? 这样设计到底有何好处?

  1. 从消费者角度来说:如果有接触过Spark集成kafka的项目的同学,这点其实不难理解为何要如此设计;在最开始讲解kafka特点的时候就说过支持Hadoop的并行处理,那么如何支持?如何达到并行处理的要求?我们都知道一旦并行度提高了,那么我们消费者从kafka中并行的从不同partition拉取的数据量就会提高(可以想象:3个分区和5个分区分别对应着3个task和5个task每秒从kafka拉取的数据量)。其实在这里正好就对应起来,在创建Topic指定其分区数的时候,就对应了kafka消费者的最大并行度是多少,相应的如果我们提高我们的kafka某个topic的分区数,那么也就是提高了我们的处理的最大并行度。
  2. 从生产者角度来说:可以处理更多的消息,而不受单台服务器的限制,Topic拥有更多分区,意味着可以并行处理更多的数据
  • kafka底层是如何通过offset找到message

例如:通过offset = 39997 查找到该偏移量对应的数据信息

  1. 查找Segment File
    第一步查找Segment文件,例如0000000000000.index是第一个所以文件,这个‘0000000000000’表示的就是当前index文件对应log数据文件中的第一个offset数据物理偏移量地址,那么下个index文件对应的log文件的第一个offset的物理偏移量地址就是上个index文件的最后一个offset地址 + 1,不难想象出来该题目中:通过offset=39997查找到对应的message,可以利用”二分查找法“通过O(logn)的时间复杂度快速定位offset=39997的数据所在哪个log文件中记录。
  2. 通过Segment File 查找数据
    通过第一步从index文件定位到对应的log文件的物理偏移地址后,最后在该log文件中通过”顺序查找“的方式就可以直接定位到offset=39997对应的数据信息

第三章 Kafka集群搭建

搭建三个节点 :

节点名称节点IP节点服务名
mydata01192.168.111.109QuorumPeerMain、Kafka
mydata02192.168.111.110QuorumPeerMain、Kafka
mydata03192.168.111.111QuorumPeerMain、Kafka
  • 前提
  • 修改主机名
[root@mydata01 | mydata02 | mydata03 ] hostnamectl set-hostname xxx
[root@mydata01 | mydata02 | mydata03 ] reboot
  • 配置hosts文件
[root@mydata01 | mydata02 | mydata03 ] vi /etc/hosts
192.168.111.109  mydata01
192.168.111.110  mydata02
192.168.111.111  mydata03
  • 全部关闭并且禁用防火墙
#查看防火墙状态
[root@mydata01 | mydata02 | mydata03 ] systemctl status firewalld 
#关闭防火墙
[root@mydata01 | mydata02 | mydata03 ] systemctl stop firewalld
#禁止开机自启
[root@mydata01 | mydata02 | mydata03 ] systemctl disable firewalld
  • 三个节点配置免密登录
 [root@mydata01 | mydata02 | mydata03 ] ssh-keygen -t rsa
 [root@mydata01 | mydata02 | mydata03 ] cat id_rsa.pub >> authorized_keys
 [root@mydata01 | mydata02 | mydata03 ] scp ~/.ssh/authorized_keys mydata01:~/.ssh/
 [root@mydata01 | mydata02 | mydata03 ] scp ~/.ssh/authorized_keys mydata02:~/.ssh/
 [root@mydata01 | mydata02 | mydata03 ] scp ~/.ssh/authorized_keys mydata03:~/.ssh/
  • 集群时间同步
[root@mydata01 | mydata02 | mydata03 ] yum –y install ntp
[root@mydata01 | mydata02 | mydata03 ] restrict 节点IP nomodify notrap nopeer noquery
[root@mydata01 | mydata02 | mydata03 ] restrict 节点网关 mask 子网掩码 nomodify notrap
# 选择一个ntp主节点:mydata01
[root@mydata01] vi /etc/ntp.conf
server 192.168.111.109
Fudge 192.168.111.109 stratum 10
#并注释掉server 0 ~ n
# 选择除主节点外其余节点:mydata02、mydata03
[root@mydata02 | mydata03 ]  vi /etc/ntp.conf
Fudge 192.168.111.109 stratum 10
server 192.168.111.109
#并注释掉server 0 ~ n
#启动所有节点的ntp服务
[root@mydata01 | mydata02 | mydata03 ]  systemctl start ntpd
  • 搭建Kafka服务 (ps:默认已经搭建好zookeeper服务)
# 三个节点将下载好的包解压至自定义目录中
[root@mydata01 | mydata02 | mydata03 ] tar -zxvf kafka_2.12-2.6.0.tgz -C /home/
# 修改三个节点解压好的目录,这一步看个人习惯
[root@mydata01 | mydata02 | mydata03 ] mv kafka_2.12-2.6.0 kafka/
#修改三个节点环境变量
[root@mydata01 | mydata02 | mydata03 ] vi /etc/profile
export KAFKA_HOME=/home/kafka
export PATH=$KAFKA_HOME/bin:$PATH
[root@mydata01 | mydata02 | mydata03 ] source /etc/profile #使环境变量生效
# 修改kafka server的配置文件
[root@mydata01 | mydata02 | mydata03 ] vi /home/kafka/config/server.properties
broker.id=0 #三台节点,每个节点的id都不允许一致,否则启动会报错
port=9092 #kafka 端口
host.name=mydata01 #主机IP或者域名都可以
delete.topic.enable=true #配置kafka Topic是否可以删除
log.retention.hours=168
message.max.byte=5242880
default.replication.factor=2
replica.fetch.max.bytes=5242880
zookeeper.connect=mydata01:2181,mydata02:2181,mydata03:2181 #zookeeper服务的IP加端口
# 启动三台kafka服务
[root@mydata01 | mydata02 | mydata03 ] cd /home/kafka/bin #如果配置环境变量后无需执行该步骤
[root@mydata01 | mydata02 | mydata03 ] ./kafka-server-start.sh -daemon ../config/server.properties & #将kafka服务置为后台启动
# jps查看每个节点上的服务是否正常启动
[root@mydata01 | mydata02 | mydata03 ] jps
1044 QuorumPeerMain  #zookeeper进程
9012 Kafka  #kafka进程

其实在整个大数据组件中,kafka集群搭建其实不是很复杂,但是也需要各位同学用心搭建,否则难免会出现问题,如果各位同学在搭建环境过程中出现任何问题,欢迎留言回复,楼楼万分期待~

  • kafka常用命令
# 创建topic
[root@mydata01 | mydata02 | mydata03 ] ./kafka-topic.sh --create --topic 主题名称 --zookeeper mydata01:2181,mydata02:2181,mydata03:2181 --partitions 分区数 --replication-factor 副本数
# 查看topic列表
[root@mydata01 | mydata02 | mydata03 ] ./kafka-topic.sh --list --zookeeper mydata01:2181,mydata02:2181,mydata03:2181
# 查看指定topic描述信息
[root@mydata01 | mydata02 | mydata03 ] ./kafka-topic.sh --describe --zookeeper mydata01:2181,mydata02:2181,mydata03:2181 --topic 主题名称
# 删除topic 
[root@mydata01 | mydata02 | mydata03 ] ./kafka-run-class.sh kafka.admin.DeleteTopicCommand --zookeeper mydata01:2181,mydata02:2181,mydata03:2181 --topic 主题名称  
# 使用过程中需要在kafka的config配置文件中将 delete.topic.enable=true
# 另外需要注意的是:该命令只会删除存储在zookeeper中的元数据信息,持久化到磁盘中的数据文件则必须自己手动删除,项目生产中谨慎使用该命令,另外建议在实际项目中将delete.topic.enable=false从而避免引发不可挽回的后果
# 修改topic
[root@mydata01 | mydata02 | mydata03 ] ./kafka-topics.sh --alter --topic 主题名称 --zookeeper mydata01:2181,mydata02:2181,mydata03:2181 --partitions 5  
# 将topic的分区数由1改为5
# 产看topic的生产数据的偏移量
[root@mydata01 | mydata02 | mydata03 ] ./kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list mydata01:9092 --topic 主题名称 --time -1

以上就是kafka常用的一些命令,当然了,还有很多命令还都没有说到,比如像kafka关于生产者和消费的常用命令等,请各位同学勿着急,鄙人也会抽空为各位同学完善该博客。

  • 最后
    终于到最后了,经历了四个小时的敲打终于搞定了!本章节博客只是给大家介绍了关于kafka的背景、基本原理、架构设计、框架搭建、常用命令等基本知识,后面还会有更为高阶的知识点例如:kafka的生产者和消费者原理、源码、架构设计等等~

由于博主也是抱着一颗学习的心态写下了这篇博客,所以文章中难免会出现一些问题,如果有问题希望我们一起讨论,同时欢迎各位同学指出不足,您的宝贵建议更是我向上发展的动力,感谢~
最后,希望各位大佬们点赞、关注、留言~~感谢
ps : 永远是学习道路上的小白,无知无识,无名无相,无知无求!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值