Kafka宝典
前言
Github:https://github.com/HealerJean
1、消息队列使用场景
消息发布者:只管将消息发布到消息队列中而不需要管谁来获取。
消息使用者:只管从消息队列中取消息,而不管是谁发布的。这样发布者和使用者都不需要知道对方的存在
1.1、解耦
⬤ 一个系统(模块)调用多个系统(模块)的场景
⬤ 多个系统的添加或减少都需修改调用系统的代码
⬤ 且不需要同步调用接口的情况
举例:签到后,送积分 。从业务上来说,签到后我们一定要保证用户的签到正常,而积分的赠送我们可以延迟给用户传递,但是最终我们一定要保证签到后给积分,只是延迟而已。
某一时刻积分服务不正常。不会影响到用户签到,专业积分服务即使报错了,我们后台可以自动重试,保证积分顺利送出,而不出现异常
1.2、流量削峰
每个系统性能都是有极限的,类似淘宝双十一,数据量猛增,这个时候就需要把用户的请求放入消息队列中,每次从队列中取出最大数据(刚好不会使系统崩溃的数据),这样请求就会堆积在消息队列中,等到闲时请求就少了,但系统人以最大吞吐去处理数据,所以堆积消息很快会被解决
1.3、异步
涉及到时间消耗问题,当一个信息传入同时保存到多个系统,期间需要一个时间消耗,这时只需要信息先保存当前系统,剩下的放入消息队列
## 1.3、日志记录
相信没有人认为日志是不重要的,在我们已知的日志框架中,有可能会以为写入日志时的某些故障而导致业务系统访问阻塞,请求延迟,所以我们可以构建一个日志系统,用来提供分析数据
1.4、事务一致性
举个例子,我正在开发的小米供应链金融,我们有用户的金额信息,我们也有个业务系统是账户系统,它里面也有余额信息,涉及到钱,我们就必须保证二者是一致的, 那么这个时候我们就可以使用消息队列来进行处理
2、常见问题
2.1、为什么用消息队列而不是用接口
答案:
1、解耦:一个生产者可以对应多个消费者应用服务
2、流量削峰:放入消息队列可以消息挤压,慢慢处理消息(消费者挂掉之后,可以慢慢处理)
3、异步处理:如果一个消息需要传递给多个消费者,使用消息的方式可以异步处理
2.2、kafka
高吞吐原因
2.2.1、批量发送
Kafka
允许进行批量发送消息,先将消息缓存在内存中,然后一次请求批量发送出去比如可以指定缓存的消息达到某个量的时候就发出去,或者缓存了固定的时间后就发送出去如100
条消息就发送,或者每5
秒发送一次这种策略将大大减少服务端的I/O次数
2.2.2、顺序读写
kafka
的消息是不断追加到文件中的,这个特性使kafka
可以充分利用磁盘的顺序读写性能顺序,读写不需要硬盘磁头的寻道时间,只需很少的扇区旋转时间,所以速度远快于随机读写
2.2.3、文件分段
1、
Kafka
把topic
中一个parition
大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。2、通过索引文件稀疏存储,可以大幅降低
index
文件元数据占用空间大小。3、通过索引信息可以快速定位
message
和确定response
的最大大小。4、通过
index
元数据全部映射到memory缓存
,可以避免segment file
的IO
磁盘操作。
2.2.4、零拷贝
Kafka
使用零复制技术向客户端发送消息——也就是说,Kafka
直接把消息从文件(或者更确切地说是Linux
文件系统缓存)里发送到网络通道,而不需要经过任 何中间缓冲区,这是Kafka
与其他大部分数据库系统不一样的地方,其他数据库在将数据 发送给客户端之前会先把它们保存在本地缓存里。这项技术避免了字节复制,也不需要管理内存缓冲区,从而获得更好的性能。
2.2.5、数据压缩。
Kafka
还支持对消息集合进行压缩,Producer
可以通过GZIP
或Snappy
格式对消息集合进行压缩压缩的好处就是减少传输的数据量,减轻对网络传输的压力Producer
压缩之后,在Consumer
需进行解压,虽然增加了CPU
的工作,但在对大数据处理上,瓶颈在网络上而不是CPU
,所以这个成本很值得