kafka消息队列数据结构,kafka和传统消息队列的区别

  kafka消息队列数据结构,kafka和传统消息队列的区别

  

目录

Kafka消息队列原理Kafka的逻辑数据模型Kafka的分发策略Kafka的物理存储模型和搜索数据设计Kafka的持久化策略设计Kafka的数据一致性策略设计Kafka的备份和负载均衡Kafka消息队列内部实现原理

 

  00-1010最近测试了卡夫卡的读写性能,借此机会学习了一些卡夫卡的设计原理。既然是分布式系统,我们还是按照分布式的套路来分析。

  00-1010生产者向服务器发送数据时,构造ProducterRecorder,String(字符串主题,整数键,字符串值)对象并发送。从这个构造器可以看出,卡夫卡的表层逻辑数据模型是key-value。

  当然,api在发送之前会在此基础上增加一些验证信息,但这是对用户透明的。

  00-1010类似于许多分布式多备份系统。卡夫卡的基本网络结构如下:

  一个代理中有不同分区的备份,一个奇偶的多个备份保存在不同的节点上,选择一个作为leader与客户端交互,一个主题有多个奇偶。

  默认的kafka分发算法是hash(key)% n partitions,简单来说就是哈希和取模。当然,这个算法是可以定制的,只要重写相关接口即可。

  如上所示,在四台主机计算机上创建了一个包含两个备份和四个分区的主题主题。但是,当生产者需要向消息队列发送一个键值对象时,他可以访问zookeeper来获得leader partion (Broker1。分区-0,2。分区1,代理3。分区2,代理4。partition-3),然后根据分配算法计算这个对象应该发送到哪个leader partion。

  

Kafka消息队列原理

卡夫卡的物理存储模式比较简单。卡夫卡的物理持久存储中有分割的概念。每个段有两种类型的文件:索引文件***。索引和日志文件(数据文件)***.log .两者的命名规则都是基于该段第一条消息的逻辑偏移量。索引是一种稀疏索引,目的是减少索引文件的数据量。它的文件内容是键值结构。Key是消息的offset(即自增序列号),value是对应日志文件的实际物理磁盘偏移量。

 

  值得一提的是,与其他正态分布不同,kafka不支持查找给定键对应的值的功能。从某种意义上说,逻辑数据模型中的键只是用来实现分布计算的,所以使用kafka查找数据只能通过放宽指定消息的偏移量来实现。

  整个搜索过程:在搜索offset=888及后续消息时,卡夫卡首先在这个节点上找到对应的段。在这个段的索引文件中通过二分搜索法找到最接近offset=888的记录,比如886,然后找到886对应的物理磁盘偏移量999。这样连续遍历两条消息后就可以找到888的数据(每条消息的逻辑偏移量、长度、数据都保存在日志文件中)。

  

Kafka的逻辑数据模型

卡夫卡的坚持设计很有特色。与其他分布式系统不同,它并不自己维护一套缓存机制,而是直接使用操作系统的文件系统(操作系统的文件系统自带pagecache)。这具有减少一个存储器副本的消耗的优点。其他分布式系统,如cassandra,在服务器端维护一个数据缓冲内存块datacache。需要持久化时,调用操作系统的文件系统将其写入文件,这样datacache到pagecache就多了一次副本消耗。在这种情况下,kafka持久化管理的关键是管理文件系统的pagecache。

 

  因为kafka采用了这种特殊的持久化策略,所以kafka中没有其他分布式系统的重做日志。所以kafka有自己的一套故障后的数据恢复策略:首先kafka会通过配置文件来配置pagecache的定时或者定量刷机频率,保证即使发生故障,也能把丢失的数据降到最低。其次,pageche本身是由操作系统管理和维护的,与kafka自身的服务流程无关。如果kafka本身挂机,重启后仍然可以访问pageche中的数据。最后,如果不幸的是kafka的某个节点的主机挂机,那么在重启主机和kafka后,丢失的数据可以从其他备份节点重新同步。

  Kafka高性能的和持久化策略关系非常密切,这部分内

  容,也是整个kafka设计的精髓所在:

  传统的观念认为磁盘的读写是非常低效的,所以一般系统都会自己管理一块内存datacache充当磁盘的缓存,只有需要的时候才去和磁盘交互。

  但是实际上,磁盘的低效的原因不在于磁盘io,而在于磁头的随机寻址。如果数据是顺序读写的话(也就是一次磁头寻址,连续io),其实速度是非常快的((Raid-5,7200rpm):顺序 I/O: 600MB/s)。

  而在传统的设计中虽然加入了内存作为缓存,但是为了保证数据的安全性还是得提供一份重做日志(每次的修改操作都要记录在重做日志redo.log中,以保证内存丢失后能根据重做日志进行恢复),并且当datacache里面的数据达到一定容量时刷新到磁盘的data文件中。

  但是kafka并没有使用这套常规设计,并没有自己维护一套datacache而是另辟蹊径,直接使用操作系统中的文件系统,并利用文件系统原有的pagecache作为数据缓存。

  减少了datacache到pagecache的拷贝消耗。并且顺序地进行磁盘io,这样大大提高了kafka写数据时持久化的效率。

  对于kafka的读数据这块,kafka也使用了Sendfile技术来提高读的效率,传统的读方案是读取磁盘的数据到pagecache中,然后从pagecache拷贝一份到用户进程的datacache中,datacache再拷贝到内核的socket缓存区中,最后从socket缓存区拷贝数据到网卡中发送。而Sendfile技术跳过了用户进程的datacache这一环节,直接读取磁盘的数据到pagecache中,然后从pagecache拷贝一份到socket缓存区中,最后从socket缓存区拷贝数据到网卡中发送。整个过程减少了两次拷贝消耗。

  

 

  

Kafka的节点间的数据一致性策略设计

对于任何多节点多备份的分布式系统而言,数据的一致性问题都是绕不开的难点,一般的选择是要么优先考虑效率,这样可能就造成数据不一致甚至是数据丢失,要么选择保障数据一致性和数据安全性牺牲效率。在kafka的身上也存在这样的矛盾。

 

  Kafka是一种分partion,多节点多备份的分布式系统,每个partion都可以存在多份备份,每个备份在不同的节点上。多个备份中会根据zookpeer的注册信息通过算法选举出其中一份作为leader,这个leader负责和客户端的读写访问进行交互。

  其他备份不参与跟客户端的交互。而是去跟leader partion交互同步数据。这样一来就可能出现主备之间数据不一致的情况。Kafka在客户端提供了一个配置选项props.put("acks", "all");--其中all表示生产者等待确认所有的备份数据都写入pagecache后再返回。

  可以设置为0(不等待任何确认),1(leader确认)或者其他小于备份数的数字。其他备份节点会异步去同步leader partion的数据,保持一致,当然如果在同步的过程中,leader partion出现数据丢失,那么这部分数据将永远丢失。

  

 

  

Kafka的备份和负载均衡

Kafka的备份很明显,上文已经说过是通过讨论一致性问题已经交待清楚,至于Kafka的负载均衡,个人发现是严重依赖于zookeeper上的注册信息,通过一套算法来选取leader partion来实现kafka多节点的负载均衡。

 

  Zookeeper中保存了kafka几乎一切的重要信息,比如topic,每个topic下面的多个partion信息,主机节点信息(包括ip和端口),每个节点下的多个partion信息,每个partion的主备份信息,消费客户端的group_id分组信息,每个消费者信息等。

  通过这一堆信息进行算法计算最后得出负载均衡的方案,主要体现是选出让kafka效率性能达到最好的每个partion的leader。并且在zookeeper中注册监视器,一旦发现上述信息有变动则更新负载均衡方案。

  

 

  

Kafka消息队列内部实现原理

 

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • mysql复合索引和组合索引,mysql组合索引数据结构
  • mysql复合索引和组合索引,mysql组合索引数据结构,Mysql之组合索引方法详解
  • mysql复合索引和组合索引,mysql复合索引数据结构
  • mysql复合索引和组合索引,mysql复合索引数据结构,MySQL的复合索引总结
  • b+树 多路搜索树,数据结构中树的分类
  • b+树 多路搜索树,数据结构中树的分类,数据结构-树(三):多路搜索树B树、B+树
  • avl树的构造,avl树特性,数据结构之AVL树详解
  • 数据结构c语言哈夫曼树,c语言哈夫曼树的构造,使用C语言详解霍夫曼树数据结构
  • c语言数据结构算法编程库,数据结构 c语言中文网
  • c语言数据结构算法编程库,数据结构 c语言中文网,C语言编程数据结构基础详解小白篇
  • c++纸牌游戏,数据结构纸牌游戏c语言
  • c++纸牌游戏,数据结构纸牌游戏c语言,C语言实战之纸牌游戏
  • ,,c#解析jobject的数据结构
  • ,,javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
  • ,,Java 数据结构与算法系列精讲之背包问题
  • 留言与评论(共有 条评论)
       
    验证码: