Kafka系统学习(3)
Kafka特点
(1) 压缩消息集合
Kafka支持以集合(Batch)为单位发送消息,在此基础上,Kafka还支持对消息集合进行压缩,Producer端可以通过GZIP或Snappy格式对消息集合进行压缩。Producer端进行压缩之后,在Consumer端需进行解压。压缩的好处是减少传输的数据量,减轻网络传输的压力。在对大数据处理上,瓶颈往往体现在网络上而不是CPU(压缩和解压会耗掉部分CPU资源)上。Kafka在消息头部添加了一个描述压缩属性的字节,这个字节的后两位表示消息的压缩采用的编码,如果后两位为0,则表示消息未被压缩。
(2) 消息持久化
Kakfa依赖文件系统来存储和缓存消息。在人们的固有观念中,硬盘的存取速度总是很慢,基于文件系统的架构能否提供优异的性能?实际上硬盘的存取速度的快慢完全取决于使用方式。为了提高性能,现代操作系统往往使用内存作为磁盘的缓存,所有的磁盘读写操作都会经过这个缓存,所以如果程序在线程中缓存了一份数据,实际上在操作系统的缓存中还有一份,这等于存了两份数据。同时 Kafka 基于 JVM 内存有以下两点缺点:1、对象的内存开销非常高,通常是要存储的数据的两倍甚至更高;2、随着数据的增加,GC(Garbage Collection垃圾回收)的速度越来越慢。
实际上磁盘顺序写入的性能远远大于任意位置写的性能,顺序读写由操作系统进行了大量优化(read-ahead、write-behind 等技术),甚至比随机的内存读写更快。所以与常见的数据缓存在内存中然后刷到硬盘的设计不同,Kafka 直接将数据写到了文件系统的日志中。写操作——将数据顺序追加到文件中;读操作——直接从文件中读取。
正是由于 Kafka 将消息进行持久化,使得 Kafka 在机器重启后,己存储的消息可继续恢复使用,同时 Kafka 能够很好地支持在线或离线处理、与其他存储及流处理框架的集成。
(3) 消息可靠性
在消息系统中,保证消息在生产和消费过程中的可靠性是十分重要的。在实际消息传递过程中,可能会出现如下三种情况:①消息发送失败;②消息被发送多次;③每条消息都发送成功且仅发送了一次(exactly-once,最理想的情况)。
从Producer角度出发,当一个消息被发送后,Producer会等待Broker成功接收到消息的反馈(可通过参数控制等待时间),如果消息在途中丢失或者其中一个Broker挂掉,Producer会重新发送。
从Consumer角度出发,Broker端记录了Partition中的一个offset值,这个值指向Consumer下一个即将消费的Message。当Consumer收到消息,但却在处理过程中失败时,Consumer可以通过这个offset值重新找到上一个消息再进行处理。Consumer有权限控制这个offset值,对持久化到Broker端的消息做任意处理。
(4) 备份机制
备份机制的出现提高了Kafka集群的可靠性、稳定性。有了备份机制后,Kafka集群中的节点宕机后不影响整个集群工作。一个备份数量为n的集群允许n-1个节点失败。在所有备份节点中,有一个节点作为leader节点,这个节点保存了其他备份节点列表,并维持各个备份间的状态同步。
(5) 轻量级
Kafka 的代理是无状态的,即代理不记录消息是否被消费,消费偏移管理交由消费者自己或组协调器来维护。同时集群本身几乎不需要生产者和消费者的状态信息,这就使得 Kafka 非常轻量级,同时也让生产者和消费者客户端的实现也非常轻量级。
(6) 高吞吐量
高吞吐量是Kafka设计的主要目标,Kafka的消息是不断追加到文件中的,这个特性使Kafka可以充分利用磁盘的顺序读写性能,顺序读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写。在Linux kernel2.2之后出现了一种叫作”零拷贝(zero-copy)”系统调用机制,采用 sendfile()函数调用, sendfile()函数是在两个文件描述符之间直接传递数据,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存的直接映射,数据不再复制到“用户态缓冲区”,系统上下文次数切换减少为2次,这样可以提升一倍的性能。
- 点赞
- 收藏
- 关注作者
评论(0)