Message
MinHeaderSize
=
CrcLength
+
MagicLength
+
AttributesLength
+
KeySizeLength
+
ValueSizeLength
1. 4 byte CRC32 of the message
消息的字节内容
buffer
进行crc32编码,从
magic之后的内容进行编码
Utils.crc32(
buffer
.array,
buffer
.arrayOffset +
MagicOffset
,
buffer
.limit -
MagicOffset
)
2. 1 byte "magic" identifier to allow format changes, value is 2 currently
3. 1 byte "attributes” 存的是消息的压缩类型
attributes
= (
attributes
| (
CompressionCodeMask
& codec.codec)).toByte
GZIPCompressionCodec
codec
=
1
name
=
"gzip"
SnappyCompressionCodec
codec
=
2
name
=
"snappy"
LZ4CompressionCodec
codec
=
3
name
=
"lz4"
NoCompressionCodec
codec
=
0
name
=
"none"
4. 4 byte key length, containing length K 如果该消息没有key值,那length设置为-1
5. K byte key 消息key的字节内容,如果length为-1,表示没有这个key的字节内容,跳过
6. 4 bytepayload length, containing length V
7. V bytepayload 消息value的字节内容
MessageAndOffset
class
MessageAndOffset(
message
: Message,
offset
: Long)
MessageAndOffset.
nextOffset
=
offset
+
1 得到这个
MessageAndOffset的下一个偏移量offset
MessageAndMetadata
class
MessageAndMetadata[K, V](
topic
: String,
partition
: Int,
private val rawMessage : Message, offset : Long,
private val rawMessage : Message, offset : Long,
keyDecoder: Decoder[K],valueDecoder: Decoder[V])
MessageAndMetadata包含了这个message所属的topic和partition,在partition的消息偏移量
offset
这个message的key的类型是K
这个message的value类型是V
MessageSet
LogOverhead
=
OffsetLength
+
MessageSizeLength
MessageSizeLength
=
4 messge占用的字节大小
OffsetLength
=
8 message在partition里的消息偏移量
MessageSet中每个结构由
LogOverhead和message组成
ByteBufferMessageSet
ByteBufferMessageSet.
create(offsetCounter: AtomicLong, compressionCodec: CompressionCodec, messages: Message*)
create方法把
Message集合写入字节流中,每个消息存的是
OffsetLength + MessageSizeLength +消息的字节长度来写入这个压缩buff
其中offset存的是
offsetCounter参数的递增值,每个消息写入形如
writeMessage(
buffer
,
message
, offsetCounter.getAndIncrement)
如果需要压缩存储,把
Message集合按照
compressionCodec压缩到中,
bytes之后
message
=
new
Message(
bytes
, compressionCodec)创建一个message,
把这一个message写入到buff中
ByteBufferMessageSet.
shallowValidBytes表示
每个消息占用的总字节的大小
,如果是消息被压缩,需要解开后累加每个消息的字节大小
ByteBufferMessageSet.
internalIterator 遍历这个集合时,如果是
compressionCodec,就先解码,之后再进行遍历
FileMessageSet
class
FileMessageSet
private
[kafka](@
volatile
var
file
: File,
private
[log]
val
channel
: FileChannel,
private [log] val start : Int,
private [log] val end : Int,
private [log] val start : Int,
private [log] val end : Int,
isSlice: Boolean)extends MessageSet
FileMessageSet.
searchFor返回的是
OffsetPosition
//offset是在partition中的消息绝对位移
//position是partition中片段segment的物理的字节偏移量
//position是partition中片段segment的物理的字节偏移量
case
class
OffsetPosition(
val
offset
: Long,
val
position
: Int)
FileMessageSet.
iterator 返回的类型是
MessageAndOffset