Kfaka的 原理 架构 搭建 ISR机制 JavaAPI 读写数据快

纵然是瞬间 提交于 2019-12-17 05:54:42

实现原理

观察者模式

即 → 订阅者模式

例子:
1. 微博博主给粉丝发送动态

2. 每次狼出门之前先给人打个电话,通知人们自己要去吃羊.

生产者和消费者(消息)

传统模式

-生产者直接将消息传递给指定的消费者

-耦合性特别高,当生产者或者消费者发生变化,都需要重写业务逻辑

新型模式

-生产者和消费者之间建立一个共享的缓冲区

-生产者负责向里面添加数据

-消费者负责从里面取出数据

-一般遵循先进先出的原则

缓冲区

-一个工作组只能对某一条消息消费一次

-缓冲区的消息可以被多个工作组消费

-内部肯定有一定的机制来管理或者维护不同的数
据
-缓冲区的数据需要放在多个节点上,让更多的节点参与到计算

-每个节点持有消息的一个分区,属于数据的一部分

-当生产者产生消息之后,需要先计算对应的分区


架构图

Broker – 代理

-集群的节点,用于处理数据

Topic – 主题

-不同的数据消息交给不同的Topic管理

-类似于Table或者Type

-存储数据可以去指定的主题去操作

producer – 生产者

-往broker中某个topic里面生产数据

consumer – 消费者

-从broker中某个topic获取数据

Partition – 分区

-一个Topic下可以有多个分区,数据真实存放的位置

-当生产者产生数据的时候,根据分配策略(Hash取模),选择分区

-然后将消息追加到指定的分区的末尾(队列)

-每条消息都会有一个自增的编号
	-标识顺序
	-用于标识消息的偏移量,有专门的索引信息

offset - 偏移量

-可以唯一的标识一条消息

-消费者消费消息的时候就是通过偏移量来决定下次读取哪条消息

-消息被消费之后,并不被马上删除,这样多个业务就可以重复使用kafka的消息

-我们某一个业务也可以通过修改偏移量达到重新读取消息的目的,偏移量由用户控制

-消息最终还是会被删除的,默认生命周期为1周(7*24)

-偏移量决定读取数据的位置,不会有线程安全的问题

replication - 数据备份

-数据会存放到topic的分区中,但是有可能分区会损坏

-我们需要对分区的数据进行备份(备份多少取决于你对数据的重视程度)

-我们将分区的分为Leader(1)和Follower(N-1)
	-Leader负责写入和读取数据
	-Follower只负责备份
	-保证了数据的一致性
	
-备份数设置为N,表示主+备=N

Consumer Group – 消费者组

	将多个消费者集中到一起去处理某一个Topic的数据
	可以更快的提高数据的消费能力
	整个消费者组共享一组偏移量(防止数据被重复读取),因为一个Topic有多个分区


Kafka环境搭建

需要先搭建Zookeeper环境
Kafka要基于Zookeeper搭建

配置Kafka

--解压kafka的tgz包:
tar -zxvf kafka_2.11-0.8.2.1.tgz
--移动解压后目录:
mv kafka_2.11-0.8.2.1 /opt/sxt/
--进入软件安装目录并修改目录名:
cd /opt/sxt/
mv kafka_2.11-0.8.2.1/ kafka_2.11

```powershell
--修改配置文件
cd /opt/sxt/kafka_2.11/config/
vim server.properties

配置文件修改项 :

行数20 broker.id=0
行数25 port=9092
行数58 log.dirs=/var/sxt/kafka-logs
行数118 zookeeper.connect=bd1301:2181,bd1302:2181,bd1303:2181


--将kafka文件目录拷贝到其他主机:
scp -r kafka_2.11/ root@bd1302:/opt/sxt/
scp -r kafka_2.11/ root@bd1303:/opt/sxt/
--修改其他机器上的配置文件
vim server.properties

这里只需修改broker.id

主机2
20行 broker.id=1


主机3
20行 broker.id=2

--添加环境变量
vim /etc/profile
--拷贝复制环境变量到其他主机
scp /etc/profile root@bd1302:/etc/profile
scp /etc/profile root@bd1303:/etc/profile
--加载环境变量
source /etc/profile

启动集群

--启动zookeeper集群(所有)
zkServer.sh start
--启动ksfka集群(所有)
kafka-server-start.sh /opt/sxt/kafka_2.11/config/server.properties

常见命令代码示例:

  • //创建主题
--在非集群启动的主机1上输入代码

kafka-topics.sh --zookeeper bd1301:2181,bd1302:2181,bd1303:2181 --create --replication-factor 2 --partitions 3 --topic xxxxxgy
  • //查看所有主题
--在非集群启动的主机1上输入代码

kafka-topics.sh --zookeeper bd1301:2181,bd1302:2181,bd1303:2181 --list
  • //查看主题
--在非集群启动的主机1上输入代码

kafka-topics.sh --zookeeper bd1301:2181,bd1302:2181,bd1303:2181 --describe --topic xxxxxgy
  • //创建生产者
    –在非集群启动的主机1上输入代码

kafka-console-producer.sh --broker-list bd1301:9092,bd1302:9092,bd1303:9092 --topic xxxxxgy
之后自由输入数据

  • //创建消费者

--再新启动另一主机1进行测试

kafka-console-consumer.sh --zookeeper bd1301:2181,bd1302:2181,bd1303:2181 --from-beginning --topic xxxxxgy


ISR机制

我们备份数据就是防止数据丢失,当主节点挂掉时,可以启用备份节点

主备节点的数据一致性

-acks :默认为1
	-0 : 生产者只负责产生消息,具体是否存放完成不关心
	-1:Leader存放到本地,但是从节点是否同步不关心
	-all:不但主节点存放,而且从节点已经同步完成
-我们写数据只写到leader中,Follower如何同步数据?
	-Leader → push 
	-Follower → pull
	-Follower每间隔一定时间去Leader拉取数据,来保证数据的同步
-ISR(in-syncReplica)
	-当主节点挂点,并不是去Follower选择主,而是从ISR中选择主
	-判断标准
		-超过10秒钟没有同步数据
			-replica.lag.time.max.ms=10000
		-主副节点差4000条数据
			-rerplica.lag.max.messages=4000 
	-脏节点选举
		-kafka采用一种降级措施来处理:
		-选举第一个恢复的node作为leader提供服务,以它的数据为基准,这个措施被称为脏leader选举


JavaAPI

生产者

创建一线程重复的向kafka输入数据

  • 配置配置信息
  • 开启线程写入数据
//封装消息对象
KeyedMessage<String, String> message = new KeyedMessage<>(topic, key, value);
//将消息发送到Kafka
producerForKafka.send(message);

消费者

创建一线程重复的向kafka消费数据

  • 配置配置信息
  • 开启线程消费数据
//声明一个Map存放 主题与线程数的对应关系
Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
// 描述读取哪个topic,需要几个线程读
topicCountMap.put(topic, 1);
// 获取主题 与 读取流的映射关系 sxtlog 1   sxtteacher 3
Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap =                                              consumer.createMessageStreams(topicCountMap);
// 每个线程对应于一个KafkaStream
List<KafkaStream<byte[], byte[]>> list = consumerMap.get(topic);
// 获取kafkastream流
KafkaStream stream0 = list.get(0);
//获取消息的迭代器,一次性读取一条消息
ConsumerIterator<byte[], byte[]> it = stream0.iterator();

重复消费和数据的丢失

有可能一个消费者取出了一条数据(offset=88),但是还没有处理完成,但是消费者被关闭了

  • 如果下次还能从88重新处理就属于完美情况
  • 如果下次数据从86开始,就属于数据的重复消费
  • 如果下次数据从89开始,就是与数据的丢失
//消费者自动提交偏移量的时间间隔
props.put("auto.commit.interval.ms", "1010");

提交间隔》单条执行时间 (重复)
提交间隔《单条执行时间 (丢失)

Kafka读写数据快

写入数据

-写入数据往内存去写
	-基于操作系统的页缓存来实现文件写入的
	-操作系统自己管理的缓存
-磁盘读数据
	-寻道时间
		-机械硬盘顺序读取速度要超过固态硬盘的好多倍
	-磁盘转速

读取数据

-读取数据时
	-首先去内存区查看有没有这个偏移量的数据
	-如果没有这个数据再去数据文件中读取数据,为了节约中间在内存中拷贝数据的时间
	-在读数据的时候是引入零拷贝技术
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!