转载:https://blog.csdn.net/sand_clock/article/details/68486599
官方文档定义:kafka是一个分布式、可分区、多副本的日志系统。
kafka术语:
- massage: kafka中最基本的传递对象,有固定格式。
- topic: 一类消息,如page view,click行为等。
- producer: 产生信息的主体,可以是服务器日志信息等。
- consumer: 消费producer产生话题消息的主体。
- broker: 消息处理结点,多个broker组成kafka集群。
- partition: topic的物理分组,每个partition都是一个有序队列。
- segment: 多个大小相等的段组成了一个partition。
- offset: 一个连续的用于定位被追加到分区的每一个消息的序列号,最大值为64位的long大小,19位数字字符长度。
对于一个消息系统而言,追踪客户消费了什么,也即消息消费状态是每个消息系统必须提供的关键功能之一。
系统可以提供的几种可能消息传递保障有3种:
- At most once 消息至多会被发送一次,但如果产生网络延迟等原因消息就会有丢失。
- At least once 消息至少会被发送一次,上面既然有消息会丢失,那么给它加一个消息确认机制即可解决,但是消息确认阶段也还会出现同样问题,这样消息就有可能被发送两次。
- Exactly once 消息只会被发送一次,这是我们想要的效果。
那么kafka是怎么解决的呢?
kafka的解决方案:
- broker将数据流划分为一组互相独立的分区。这些分区的语义由producer定义,由producer指定每条消息属于哪个分区。一个分区内的消息以到达broker的时间为准排序,将来按此顺序将消息发送给consumer。这样一来,就用不着为每一条消息保存一条元数据(比如标记该消息已使用)了,我们只需要为producer、topic、partition的每种组合记录一个“最高水位标记”(high water mark)即可。我们把这个最高水位标记称作偏移量offset。
topic、partition、segment、offset的关系:
- partition、segment、offset都是为topic服务的,每个topic可以分为多个partition,一个partition相当于一个大目录,每个partition下面有多个大小相等的segment文件,这个segment是由message组成的,而每一个的segment不一定由大小相等的message组成。segment大小及生命周期在server.properties文件中配置。offset用于定位位于段里的唯一消息。
接下来弄清楚segment具体细节之后再说offset:
- segment由index和data文件组成,两个文件成对出现,分别存储索引和数据。
- segment文件命名规则:对于所有的partition来说,segment名称从0开始,之后的每一个segment名称为上一个segment文件最后一条消息的offset值。
那么对于分区中的一个offset例如等于345552怎么去查找相应的message呢?
- 先找到该message所在的segment文件,通过二分查找的方式寻找小于等于345552的offset,假如叫S的segment符合要求,如果S等于345552则S上一个segment的最后一个message即为所求;如果S小于345552则依次遍历当前segment即可找到。
网友评论