【转载】Kafka实现篇之消息和日志
http://blog.csdn.net/honglei915/article/details/37760631
消息格式
日志
一个叫做“my_topic”且有两个分区的的topic,它的日志有两个文件夹组成,my_topic_0和my_topic_1,每个文件夹里放着具体的数据文件,每个数据文件都是一系列的日志实体,每个日志实体有一个4个字节的整数N标注消息的长度,后边跟着N个字节的消息。每个消息都可以由一个64位的整数offset标注,offset标注了这条消息在发送到这个分区的消息流中的起始位置。每个日志文件的名称都是这个文件第一条日志的offset.所以第一个日志文件的名字就是00000000000.kafka.所以每相邻的两个文件名字的差就是一个数字S,S差不多就是配置文件中指定的日志文件的最大容量。
消息的格式都由一个统一的接口维护,所以消息可以在producer,broker和consumer之间无缝的传递。存储在硬盘上的消息格式如下所示:
- 消息长度: 4 bytes (value: 1+4+n)
- 版本号: 1 byte
- CRC校验码: 4 bytes
- 具体的消息: n bytes
写操作
消息被不断的追加到最后一个日志的末尾,当日志的大小达到一个指定的值时就会产生一个新的文件。对于写操作有两个参数,一个规定了消息的数量达到这个值时必须将数据刷新到硬盘上,另外一个规定了刷新到硬盘的时间间隔,这对数据的持久性是个保证,在系统崩溃的时候只会丢失一定数量的消息或者一个时间段的消息。
读操作
读操作需要两个参数:一个64位的offset和一个S字节的最大读取量。S通常比单个消息的大小要大,但在一些个别消息比较大的情况下,S会小于单个消息的大小。这种情况下读操作会不断重试,每次重试都会将读取量加倍,直到读取到一个完整的消息。可以配置单个消息的最大值,这样服务器就会拒绝大小超过这个值的消息。也可以给客户端指定一个尝试读取的最大上限,避免为了读到一个完整的消息而无限次的重试。
在实际执行读取操纵时,首先需要定位数据所在的日志文件,然后根据offset计算出在这个日志中的offset(前面的的offset是整个分区的offset),然后在这个offset的位置进行读取。定位操作是由二分查找法完成的,Kafka在内存中为每个文件维护了offset的范围。
下面是发送给consumer的结果的格式:
MessageSetSend (fetch result) total length : 4 bytes
error code : 2 bytes
message 1 : x bytes
...
message n : x bytes
MultiMessageSetSend (multiFetch result) total length : 4 bytes
error code : 2 bytes
messageSetSend 1
...
messageSetSend n
删除
日志管理器允许定制删除策略。目前的策略是删除修改时间在N天之前的日志(按时间删除),也可以使用另外一个策略:保留最后的N GB数据的策略(按大小删除)。为了避免在删除时阻塞读操作,采用了copy-on-write形式的实现,删除操作进行时,读取操作的二分查找功能实际是在一个静态的快照副本上进行的,这类似于Java的CopyOnWriteArrayList。
可靠性保证
日志文件有一个可配置的参数M,缓存超过这个数量的消息将被强行刷新到硬盘。一个日志矫正线程将循环检查最新的日志文件中的消息确认每个消息都是合法的。合法的标准为:所有文件的大小的和最大的offset小于日志文件的大小,并且消息的CRC32校验码与存储在消息实体中的校验码一致。如果在某个offset发现不合法的消息,从这个offset到下一个合法的offset之间的内容将被移除。
有两种情况必须考虑:1,当发生崩溃时有些数据块未能写入。2,写入了一些空白数据块。第二种情况的原因是,对于每个文件,操作系统都有一个inode(inode是指在许多“类Unix文件系统”中的一种数据结构。每个inode保存了文件系统中的一个文件系统对象,包括文件、目录、大小、设备文件、socket、管道, 等等),但无法保证更新inode和写入数据的顺序,当inode保存的大小信息被更新了,但写入数据时发生了崩溃,就产生了空白数据块。CRC校验码可以检查这些块并移除,当然因为崩溃而未写入的数据块也就丢失了。
【转载】Kafka实现篇之消息和日志的更多相关文章
- 漫游Kafka实现篇之消息和日志
消息格式 消息由一个固定长度的头部和可变长度的字节数组组成.头部包含了一个版本号和CRC32校验码. /** * 具有N个字节的消息的格式如下 * * 如果版本号是0 * * 1. 1个字节的 &qu ...
- 漫游Kafka设计篇之消息传输的事务定义
之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...
- 漫游Kafka设计篇之消息传输的事务定义(5)
之前讨论了consumer和producer是怎么工作的,现在来讨论一下数据传输方面.数据传输的事务定义通常有以下三种级别: 最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输. 最 ...
- [转载] KAFKA分布式消息系统
转载自http://blog.chinaunix.net/uid-20196318-id-2420884.html Kafka[1]是linkedin用于日志处理的分布式消息队列,linkedin的日 ...
- 【转载】Apache Kafka:下一代分布式消息系统
http://www.infoq.com/cn/articles/kafka-analysis-part-1 Kafka是由LinkedIn开发的一个分布式的消息系统,使用Scala编写,它以可水平扩 ...
- Apache Kafka:下一代分布式消息系统【转载】
简介 Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和可复制的提交 ...
- [转载] Kafka+Storm+HDFS整合实践
转载自http://www.tuicool.com/articles/NzyqAn 在基于Hadoop平台的很多应用场景中,我们需要对数据进行离线和实时分析,离线分析可以很容易地借助于Hive来实现统 ...
- Apache Kafka —一个不同的消息系统
Apache已经发布了Kafka 0.8,也是自从成为Apache软件基金会的顶级项目后Kafka的 第一个主版本. Apache Kafka是发布—订阅消息传递,实现了分布式提交日志,适用于离线和在 ...
- Kafka不只是个消息系统
作者丨 Jay Kreps Confluent 联合创始人兼 CEO Jay Kreps 发表了一篇博文,给出了 Kafka 的真正定位——它不只是个消息系统,它还是个存储系统,而它的终极目标是要让流 ...
随机推荐
- jeecms支持的freemaker标签大全
<@e.form id="jvForm" action="o_add.do"> <@e.text label="字段名" ...
- 介绍50个 WordPress 动作挂钩
WordPress 之所以能成为世界上最受欢迎的网页内容管理系统,原因就在于它的高度灵活性和可塑性,而这种灵活性和可塑性正是由“挂钩”(Hooks)简洁宜用的结构所决定的.可以说,没有过滤挂钩(Fil ...
- Hibernate映射解析——七种映射关系
首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对 ...
- usr/bin/ld: cannot find 错误解决方法
参考:http://blog.siyebocai.cn/20100324_5p424qs7.html 通常在软件编译时出现的usr/bin/ld: cannot find -lxxx的错误,主要的原因 ...
- Hadoop on Mac with IntelliJ IDEA - 3 解决MRUnit - No applicable class implementing Serialization问题
本文讲述在IntelliJ IDEA中使用MRUnit 1.0.0测试Mapper派生类时因MapDriver.withInput(final K1 key, final V1 val)的key参数被 ...
- java中匿名类的讲解
匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 实例1:不使用匿名内部类来实现抽象 ...
- 解决 DCEF3 在 BeforePopup 事件中打开新窗体的问题
此问题的解决方案从 https://groups.google.com/forum/#!topic/delphichromiumembedded/xzshOr-pjnU 获得. procedure T ...
- ListView添加项目带序列
ListView添加项目带序列 function AddSelItems(listview1:TListView;ListView2:TListView):Boolean;var s: st ...
- 让你的PHP程序真正的实现多线程(PHP多线程类)(转)
通过WEB服务器来实现PHP多线程功能. 当然,对多线程有深入理解的人都知道通过WEB服务器实现的多线程只能模仿多线程的一些效果,并不是真正意义上的多线程. 但不管怎么样,它还是能满足我们的一些需要的 ...
- c实例_挑战程序竞赛,蚂蚁
#include <stdio.h> //蚂蚁的题目 int max(int a,int b) { int count; count=a>b?a:b; return count; } ...