1主要的设计元素

Kafka之所以和其它绝大多数信息系统不同,是因为下面这几个为数不多的比较重要的设计决策:

  1. Kafka在设计之时为就将持久化消息作为通常的使用情况进行了考虑。
  2. 主要的设计约束是吞吐量而不是功能。
  3. 有关哪些数据已经被使用了的状态信息保存为数据使用者(consumer)的一部分,而不是保存在服务器之上。
  4. Kafka是一种显式的分布式系统。它假设,数据生产者(producer)、代理(brokers)和数据使用者(consumer)分散于多台机器之上。

1.1.消息持久化(Message Persistence)及其缓存

  • 在一个由6个7200rpm的SATA硬盘组成的RAID-5磁盘阵列上,线性写入(linear write)的速度大约是300MB/秒,但随即写入却只有50k/秒,其中的差别接近10000倍(在新的kafka集群里面,RAID-5,Kafka的磁盘写入速度,可以稳定在600M/s)。
  • 消息系统元数据的持久化数据结构往往采用BTree,Btree运算的时间复杂度为O(log N)。

1.2.传输效率的最大化

导致低效率的原因常见的有两个:过多的网络请求和大量的字节拷贝操作。

为了将数据从页面缓存直接传送给socket,在Linux中这是通过sendfile这个系统调用实现的。通过Java中的API,FileChannel.transferTo,由它来简洁的调用上述的系统调用。

为了理解sendfile所带来的效果,重要的是要理解将数据从文件传输到socket的数据路径(4次拷贝,2次系统调用):

  1. OS将数据从Disk中读取到内核空间里的页面缓存
  2. 应用程序将数据从内核空间读入到用户空间的缓冲区
  3. 应用程序将读到的数据写回内核空间并放入socke的缓冲区
  4. 操作系统将数据从socket的缓冲区拷贝到NIC(网络借口卡,即网卡)的缓冲区,到此数据才能通过网络发送出去

Kafka只有2步,第①和④步,数据只需拷贝到页面缓存中一次,然后让OS直接将数据从页面缓存发送到网络NIC的缓冲区。目的是让消息使用的速度就能接近网络连接的极限。

1.3.端到端的批量压缩

Kafka支持GZIP和Snappy压缩协议。

1.4.消息传递语义(Message delivery semantics)

Producer:①至少一次 ②最多一次
Consumer: 至少一次

2.生产者

2.1 生产者自动负载均衡 -- TODO:需要详细看一下

生产者在其内部为每一个代理维护了一个弹性的连接(同代理建立的连接)池。通过使用zookeeper监视器的回调函数(callback),该连接池在建立/保持同所有在线代理的连接时都要进行更新。当生产者要求进入某特定话题时,由分区者(partitioner)选择一个代理分区(参加语义分区小结)。从连接池中找出可用的生产者连接,并通过它将数据发送到刚才所选的代理分区。

2.2异步发送

对于可伸缩的消息系统而言,异步非阻塞式操作是不可或缺的。在Kafka中,生产者有个选项(producer.type=async)可用指定使用异步分发出产请求(produce request)。这样就允许用一个内存队列(in-memory queue)把生产请求放入缓冲区,然后再以某个时间间隔或者事先配置好的批量大小将数据批量发送出去。因为一般来说数据会从一组以不同的数据速度生产数据的异构的机器中发布出,所以对于代理而言,这种异步缓冲的方式有助于产生均匀一致的流量,因而会有更佳的网络利用率和更高的吞吐量。

2.3生产者 APIs

生产者 API 是给两个底层生产者的再封装

  • kafka.producer.SyncProducerandkafka.producer.async.AsyncProducer.

生产者可以

  • 对多个生产者请求进行排队/缓冲并异步发送批量数据 —— kafka.producer.Producer提供了在将多个生产请求序列化并发送给适当的Kafka代理分区之前,对这些生产请求进行批量处理的能力(producer.type=async)。批量的大小可以通过一些配置参数进行控制。当事件进入队列时会先放入队列进行缓冲,直到时间到了queue.time或者批量大小到达batch.size为止,后台线程(kafka.producer.async.ProducerSendThread)会将这批数据从队列中取出,交给kafka.producer.EventHandler进行序列化并发送给适当的kafka代理分区。通过event.handler这个配置参数,可以在系统中插入一个自定义的事件处理器。在该生产者队列管道中的各个不同阶段,为了插入自定义的日志/跟踪代码或者自定义的监视逻辑,如能注入回调函数会非常有用。通过实现kafka.producer.asyn.CallbackHandler接口并将配置参数callback.handler设置为实现类就能够实现注入。
  • 提供基于zookeeper的代理自动发现功能 —— 通过使用zk.connect配置参数指定zookeeper的连接url,就能够使用基于zookeeper的代理发现和负载均衡功能。在有些应用场合,可能不太适合于依赖zookeeper。在这种情况下,生产者可以从broker.list这个配置参数中获得一个代理的静态列表,每个生产请求会被随即的分配给各代理分区。如果相应的代理宕机,那么生产请求就会失败。
  • 通过使用一个可选性的、由用户指定的Partitioner,提供由软件实现的负载均衡功能 —— 数据发送路径选择决策受kafka.producer.Partitioner的影响。

2.4 消费者API

该API的中心是一个由KafkaStream这个类实现的迭代器(iterator)。每个KafkaStream都代表着一个从一个或多个分区到一个或多个服务器的消息流。每个流都是使用单个线程进行处理的,每个分区只会把数据发送给一个流中。

3.网络层

网络层就是一个特别直截了当的NIO服务器。sendfile是通过给MessageSet接口添加了一个writeTo方法实现的。这样就可以让基于文件的消息更加高效地利用transferTo实现,而不是使用线程内缓冲区读写方式。线程模型用的是一个单个的接收器(acceptor)线程和每个可以处理固定数量网络连接的N个处理器线程。

3.1 写操作

日志可以顺序添加,添加的内容总是保存到最后一个文件。当大小超过配置中指定的大小(比如说1G)后,该文件就会换成另外一个新文件。

有关日志的配置参数有两个,

  • 一个是M,用于指出写入多少条消息之后就要强制OS将文件刷新到磁盘;
  • 另一个是S,用来指定过多少秒就要强制进行一次刷新。这样就可以保证一旦发生系统崩溃,最多会有M条消息丢失,或者最长会有S秒的数据丢失,

3.2 读操作

可以通过给出消息的64位逻辑偏移量和S字节的数据块最大的字节数对日志文件进行读取。读取操作返回的是这S个字节中包含的消息的迭代器。S应该要比最长的单条消息的字节数大,但在出现特别长的消息情况下,可以重复进行多次读取,每次的缓冲区大小都加倍,直到能成功读取出这样长的一条消息。也可以指定一个最大的消息和缓冲区大小并让服务器拒绝接收比这个大小大一些的消息,这样也能给客户端一个能够读取一条完整消息所需缓冲区的大小的上限。很有可能会出现读取缓冲区以一个不完整的消息结尾的情况,这个情况用大小界定(size delimiting)很容易就能探知。

3.3 删除

一次只能删除一个日志Segment的数据。 LogManager允许通过可加载的删除策略设定删除的文件。 当前策略删除修改事件超过 N 天以上的文件,也可以选择保留最后 N GB 的数据。 为了避免删除时的读取锁定冲突,我们可以使用副本写入模式,以便在进行删除的同时对日志段的一个不变的静态快照进行二进制搜索。

3.4 数据正确性保证

在系统启动时会运行一个日志恢复过程,对最新的日志段内所有消息进行迭代,以对每条消息项的有效性进行验证。一条消息项是合法的,仅当其大小加偏移量小于文件的大小并且该消息中有效载荷的CRC32值同该消息中存储的CRC值相等。在探测出有数据损坏的情况下,就要将文件按照最后一个有效的偏移量进行截断。

3.5 Consumer

有一个Rebalance的触发时机以及对应的算法。

Kafka 0.8翻译官网精华.md的更多相关文章

  1. AngularJS系列-翻译官网

    公司之前一直用的Web前台框架是Knockout,我们通常直接叫ko,有看过汤姆大叔的KO系列,也有在用,发现有时候用得不太顺手.本人是会WPF的,所以MVVM也是比较熟悉的,学ko也是很快就把汤姆大 ...

  2. 【转】MyEclipse 9.0正式版官网下载(附Win+Llinux激活方法、汉化包)

    MyEclipse 9.0 经过 M1,M2,终于出了正式版(MyEclipse For Spring 还是 8.6.1).该版本集成了 Eclipse 3.6.1,支持 HTML5 和 JavaEE ...

  3. 1.1 Introduction中 Kafka for Stream Processing官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Kafka for Stream Processing kafka的流处理 It i ...

  4. MinGW和MSYS项目是在一起的(翻译官网)

    翻译MinGW官网的首页,首页描述了MinGW和MSYS的基本情况. Home of the MinGW and MSYS Projects(我才知道,MinGW和MSYS项目是在一起的 -_-!) ...

  5. (0)资料官网【从零开始学Spring Boot】

    Spring Boot官网:http://projects.spring.io/spring-boot/ Eclipse官网:http://www.eclipse.org/ Maven官网:http: ...

  6. React翻译官网文档之JSX

    什么是JSX? 看下面的代码它被称为JSX,它既不是字符串也不是HTML,而是一种facebook公司对javascript语法的拓展.虽然写法很奇怪最终仍会会被编译为javascript代码 con ...

  7. 【原】Zookeeper 概述 + 官网 Overview 翻译

    分布式应用 分布式应用 distributed application可以在给定时间(同时)在网络中的多个系统上运行,通过协调它们以快速有效的方式完成特定任务. (a), (b): a distrib ...

  8. scala spark-streaming整合kafka (spark 2.3 kafka 0.10)

    Maven组件如下: ) { System.err.println() } StreamingExamples.setStreamingLogLevels() )) ) { System.) } )) ...

  9. Protrator 官网和下载工具稍慢 , 但能使用. Angular CLI 内置 官方推荐 TS的 demo 不明显 , 而且依赖无法安装

    npm uninstall -g protractor  && cnpm install -g protractor && protractor --version 复 ...

随机推荐

  1. CS50.5

    函数,全局变量,参数,返回值. 1,类型转换. 各种数据类型进行转换 2,API函数 应用程序编程接口. application programming interface 写写随笔吧,先说计算机.. ...

  2. CS50.1

    1,GUI,graphical user interface,图形用户界面 2.VB,visual basic,微软开发的一种程序语言 3,BIT,binary digit 比特 4,byte 5,8 ...

  3. 使用DOS工具修复数据库

    当SQL Server 实例出现异常,无法远程链接时,数据库管理员需要登陆到SQL Server实例机器上,通过命令行工具,修复异常. 一,使用net命令行启动数据库 通过net start 命令启动 ...

  4. effective c++ 笔记 (45-48)

    //#45   运用成员函数模版接受所有兼容类型 { /*  1:当你使用智能指针的时候,会发生一个问题,想把一个子类的对象赋给基类的指针变得不可能了, 因为智能指针指定了的是基类的类型,而赋给它的是 ...

  5. 快速定位iOS线上BUG在哪个控制器崩溃

    快速定位iOS线上App崩溃在哪个控制器里面,需要和后台配合使用 下载本SDK并手动添加到项目里 新建所有的页面都继承于YZViewController 在AppDelegate的didFinishL ...

  6. eclipse中设置项目的编码方式

    1.windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Workspace,右侧Text file encoding ...

  7. 一个http请求发送到后端的详细过程

    我们来看当我们在浏览器输入http://www.mycompany.com:8080/mydir/index.html,幕后所发生的一切. 首先http是一个应用层的协议,在这个层的协议,只是一种通讯 ...

  8. SE Springer小组《Spring音乐播放器》软件需求说明之四

    4 运行环境规定 4.1设备 我们计划完成的音乐软件较小巧,功能并不复杂,在普通笔记本电脑中即可运行,并无特殊硬设备要求. 4.2支持软件 需要用到windows操作系统,用VS编写C/C++代码,还 ...

  9. Studying GIT

    Studying git Shopping list: GIT的功能 接触一个新的软件或者网站,最重要的就是认识它的功能:Git 是用于 Linux内核开发的版本控制工具.与常用的版本控制工具 CVS ...

  10. 剑指offer:从上往下打印二叉树

    题目描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 解题思路: 实际就是二叉树的中序遍历问题.之前在leetcode刷过类似题目. 利用队列完成即可. 代码: /* struct Tr ...