请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

bk2709 bk2744 走近Kafka-解析消费与zero-copy穿越之福来孕转

[复制链接]
查看: 920|回复: 5

304

主题

1705

帖子

2303

积分

等待验证会员

积分
2303
发表于 2017-11-26 19:04 | 显示全部楼层 |阅读模式
这是写在帖子头部的内容对于Kafka而言,界说一个Broker能否“在世”包括两个条件:

  • 一是它必须保护与ZooKeeper的session(这个经过ZooKeeper的Heartbeat机制来实现)。
  • 二是Follower必须可以实时将Leader的消息复制过来,不能“落后太多”。
Leader会跟踪与其连结同步的Replica列表,该列表称为ISR(即in-sync Replica)。假如一个Follower宕机,大概落后太多,Leader将把它从ISR中移除。这里所描写的“落后太多”指Follower复制的消息落后于Leader后的条数跨越预定值大概Follower跨越一按时候未向Leader发送fetch请求。
Kafka只处理fail/recover,一条消息只要被ISR里的一切Follower都从Leader复制曩昔才会被以为已提交。这样就避免了部分数据被写进了Leader,还没来得及被任何Follower复制就宕机了,而形成数据丧失(Consumer没法消耗这些数据)。而对于Producer而言,它可以挑选能否期待消息commit。这类机制确保了只要ISR有一个或以上的Follower,一条被commit的消息就不会丧失。
<h1>Leader选举

Leader选举本质上是一个散布式锁,有两种方式实现基于ZooKeeper的散布式锁:

  • 节点称号唯一性:多个客户端建立一个节点,只要成功建立节点的客户端才能获得锁
  • 姑且顺序节点:一切客户端在某个目录下建立自己的姑且顺序节点,只要序号最小的才获得锁
ZooKeeper内部自己就实现了少数服从大都的选举战略。kafka中对于Partition的leader副本的选举采用了第一种方式:为Partition分派副本,指定一个ZNode姑且节点,第一个成功建立节点的副本就是Leader节点,其他副本会在这个ZNode节点上注册Watcher监听器,一旦Leader宕机,对应的姑且节点就会被自动删除,这时注册在该节点上的一切Follower城市收到监听器事务,它们城市尝试建立该节点,只要建立成功的阿谁follower才会成为Leader(ZooKeeper保证对于一个节点只要一个客户端能建立成功),其他follower继续重新注册监听事务。
<h1> Kafka消息消耗

各个consumer(consumer 线程)可以组成一个组(Consumer group ),partition中的每个message只能被组(Consumer group )中的一个consumer(consumer 线程)消耗,假如一个message可以被多个consumer(consumer 线程)消耗的话,那末这些consumer必须在分歧的组。Kafka不支持一个partition中的message由两个或两个以上的同一个consumer group下的consumer thread来处置,除非再启动一个新的consumer group。所以假如想同时对一个topic做消耗的话,启动多个consumer group便可以了,可是要留意的是,这里的多个consumer的消耗都必须是顺序读取partition里面的message,新启动的consumer默许从partition行列最头端最新的地方起头阻塞的读message。它不能像AMQ那样可以多个BET作为consumer去互斥的(for update灰心锁)并发处置message,这是由于多个BET去消耗一个Queue中的数据的时辰,由于要保证不能多个线程拿同一条message,所以就需要行级别灰心所(for update),这就致使了consume的性能下降,吞吐量不够。而kafka为了保证吞吐量,只答应同一个consumer group下的一个consumer线程去拜候一个partition。假如感觉效力不高的时辰,可以加partition的数目来横向扩大,那末再加新的consumer thread去消耗。假如想多个分歧的营业都需要这个topic的数据,起多个consumer group就好了,大师都是顺序的读取message,offsite的值互不影响。这样没有锁合作,充实发挥了横向的扩大性,吞吐量极高。这也就构成了散布式消耗的概念。
当启动一个consumer group去消耗一个topic的时辰,不管topic里面有多个少个partition,不管我们consumer group里面设置了几多个consumer thread,这个consumer group下面的一切consumer thread一定会消耗全数的partition;即使这个consumer group下只要一个consumer thread,那末这个consumer thread也会去消耗一切的partition。是以,最优的设想就是,consumer group下的consumer thread的数目即是partition数目,这样效力是最高的。
同一partition的一条message只能被同一个Consumer Group内的一个Consumer消耗。不可以一个consumer group的多个consumer同时消耗一个partition。
一个consumer group下,不管有几多个consumer,这个consumer group一定回去把这个topic下一切的partition都消耗了。当consumer group里面的consumer数目小于这个topic下的partition数目的时辰,以下图groupA,groupB,就会出现一个conusmer thread消耗多个partition的情况,总之是这个topic下的partition城市被消耗。假如consumer group里面的consumer数目即是这个topic下的partition数目的时辰,
此时效力是最高的,每个partition都有一个consumer thread去消耗。当consumer group里面的consumer数目大于这个topic下的partition数目的时辰,就会有一个consumer thread余暇。是以,我们在设定consumer group的时辰,只需要指明里面有几个consumer数目即可,无需指定对应的消耗partition序号,consumer会自动停止rebalance。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


多个Consumer Group下的consumer可以消耗同一条message,可是这类消耗也是以o(1)的方式顺序的读取message去消耗,,所以一定会反复消耗这批message的,不能向AMQ那样多个BET作为consumer消耗(对message加锁,消耗的时辰不能反复消耗message)
假如producer的流量增大,当前的topic的parition数目=consumer数目,这时辰的应对方式就是很想扩大:增加topic下的partition,同时增加这个consumer group下的consumer。
作为一个消息系统,Kafka遵守了传统的方式,挑选由Producer向broker push消息并由Consumer从broker pull消息。
push形式很难顺应消耗速度分歧的消耗者,由于消息发送速度是由broker决议的。push形式的方针是尽能够以最快速度传递消息,可是这样很轻易形成Consumer来不及处置消息,典型的表示就是拒绝办事以及收集堵塞。而pull形式则可以按照Consumer的消耗才能以适当的速度消耗消息。
对于Kafka而言,pull形式更合适。pull形式可简化broker的设想,Consumer可自立控制消耗消息的速度,同时Consumer可以自己控制消耗方式——即可批量消耗也可逐条消耗,同时还能挑选分歧的提交方式从而实现分歧的传输语义。
<h1>Kafak顺序写入与数据读取

生产者(producer)是负责向Kafka提交数据的,Kafka会把收到的消息都写入到硬盘中,它绝对不会丧失数据。为了优化写入速度Kafak采用了两个技术,顺序写入和MMFile。
<h1>顺序写入

由于硬盘是机械结构,每次读写城市寻址,写入,其中寻址是一个“机械行动”,它是最耗时的。所以硬盘最“厌恶”随机I/O,最喜好顺序I/O。为了进步读写硬盘的速度,Kafka就是利用顺序I/O。
每条消息都被append到该Partition中,属于顺序写磁盘,是以效力很是高。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


对于传统的message queue而言,一般会删除已经被消耗的消息,而Kafka是不会删除数据的,它会把一切的数据都保存下来,每个消耗者(Consumer)对每个Topic都有一个offset用来暗示读取到了第几条数据。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


即即是顺序写入硬盘,硬盘的拜候速度还是不成能追上内存。所以Kafka的数据并不是实时的写入硬盘,它充实操纵了现代操纵系统分页存储来操纵内存进步I/O效力。
在Linux Kernal 2.2以后出现了一种叫做“零拷贝(zero-copy)”系统挪用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存空间的间接映照,数据不再复制到“用户态缓冲区”系统高低文切换削减2次,可以提升一倍性能。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


经过mmap,进程像读写硬盘一样读写内存(固然是虚拟机内存)。利用这类方式可以获得很大的I/O提升,省去了用户空间到内核空间复制的开销(挪用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中。)
<h1>消耗者(读取数据)

试想一下,一个Web Server传送一个静态文件,若何优化?答案是zero copy。传统形式下我们从硬盘读取一个文件是这样的。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


先复制到内核空间(read是系统挪用,放到了DMA,所以用内核空间),然后复制到用户空间(1、2);从用户空间重新复制到内核空间(你用的socket是系统挪用,所以它也有自己的内核空间),最初发送给网卡(3、4)。

走近Kafka-剖析消耗与zero-copy

走近Kafka-剖析消耗与zero-copy


Zero Copy中间接从内核空间(DMA的)到内核空间(Socket的),然后发送网卡。这个技术很是普遍,Nginx也是用的这类技术。
现实上,Kafka把一切的消息都寄存在一个一个的文件中,当消耗者需要数据的时辰Kafka间接疤岚文件”发送给消耗者。当不需要把全部文件发进来的时辰,Kafka经过挪用Zero Copy的sendfile这个函数,这个函数包括:

  • out_fd作为输出(一般实时socket的句柄)
  • in_fd作为输入文件句柄
  • off_t暗示in_fd的偏移(从那里起头读。
  • size_t暗示读取几多个
(关于zero-copy摘自https://www.iteblog.com/archives/2227.html)
感激您的阅读
回复

使用道具 举报

15

主题

67

帖子

97

积分

等待验证会员

积分
97
发表于 2019-6-13 12:55 | 显示全部楼层
转发了
http://jokesaz.com/viagra-online/
回复 支持 反对

使用道具 举报

8

主题

45

帖子

63

积分

等待验证会员

积分
63
发表于 2019-6-13 12:55 | 显示全部楼层
转发了
http://sammycommunitytransport.org/imitrex/
回复 支持 反对

使用道具 举报

17

主题

74

帖子

107

积分

等待验证会员

积分
107
发表于 2019-6-13 12:55 | 显示全部楼层
转发了
http://columbia-electrochem-lab.org/accutane/
回复 支持 反对

使用道具 举报

12

主题

61

帖子

78

积分

等待验证会员

积分
78
发表于 2019-6-13 12:55 | 显示全部楼层
转发了
http://biblebaptistny.org/doxycycline/
回复 支持 反对

使用道具 举报

11

主题

69

帖子

92

积分

等待验证会员

积分
92
发表于 2019-6-13 12:55 | 显示全部楼层
转发了
http://albfoundation.org/estrace/
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 安平信息网,安平信息港,安平便民信息服务综合门户网站 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表