kafka 数据丢失和速度优化 问题的几点思考:
producer端:
1,首先宏观上看保证数据的可靠安全性,肯定是依据分区数做好数据备份,设立副本数。2,push数据的方式:同步异步推送数据:权衡安全性和速度性的要求,选择相应的同步推送还是异步推送方式。
1)同步就能较准确的保证数据的安全性,但是在速度上就会略逊一筹;
=>若数据的安全级别较高,可采用同步写入的方式,并设置acks参数为-1确保数据写入到leader和各个follows中
2)异步要考虑到partition leader在未完成副本数follows的备份时就宕机的情况,即使选举出了新的leader但是已经push的数据因为未备份就丢失了!
a.不能让内存的缓冲池太满,如果满了内存溢出,也就是说数据写入过快,kafka的缓冲池数据落盘速度太慢,这时肯定会造成数据丢失。
b.尽量保证生产者端数据一直处于线程阻塞状态,这样一边写内存一边落盘。
c.异步写入的话还可以设置类似flume回滚类型的batch数,即按照累计的消息数量,累计的时间间隔,累计的数据大小设置batch大小。
设置合适的方式,增大batch 大小来减小网络IO和磁盘IO的请求,这是对于kafka效率的思考。
=>不过异步写入丢失数据的情况还是难以控制
=>还是得稳定整体集群架构的运行,特别是zookeeper,当然正对异步数据丢失的情况尽量保证broker端的稳定运作吧
3.在producer端可以对push的消息做压缩处理
kafka不像hadoop更致力于处理大量级数据,kafka的消息队列更擅长于处理小数据。针对具体业务而言,若是源源不断的push大量的数据(eg:网络爬虫),可以考虑消息压缩。但是这也一定程度上对CPU造成了压力,还是得结合业务数据进行测试选择
*4.结合上游的flume架构,每一个flume分支对应一个producer,避免在flume-collector机器上一次性往broker推送,一方面造成flume-collector的io压力,一方面可能存在数据丢失的情况。(OS:这是我在离线转实时升级flume架构时考虑的一个点)
broker端:
1,topic设置多分区,分区自适应所在机器,为了让各分区均匀分布在所在的broker中,分区数要大于broker数。
(eg:我们实时的7台机器中,broker3台,分区数设为6,同时保证大于spark-Streaming消费数量(5个works)保证每个consumer都能读到partition)
分区是kafka进行并行读写的单位,是提升kafka速度的关键。
2,kafka消息持久化到磁盘,采用线性读写到硬盘上,速度是可以得到保障的。
这边提一个自己的构想,在持久化硬盘上再多做个分布式缓存,将kafka持久化目录集成到alluxio中。
(eg:在我的毕业设计中清洗数据写到hbase后,hive在集成hbase建外部表时,hbase的目录集成到alluxio中做了一个缓存读取,由于本人电脑配置有限并且毕业设计弄的是伪分布式,所以性能上读取数据上可能没有体现出来。所以这个想法的可行性还待测试...)
3,broker的几个参数:
a)broker能接收消息的最大字节数的设置一定要比消费端能消费的最大字节数要小,否则broker就会因为消费端无法使用这个消息而挂起。
b)broker可赋值的消息的最大字节数设置一定要比能接受的最大字节数大,
否则broker就会因为数据量的问题无法复制副本,导致数据丢失
comsumer端:
1,关闭自动更新offset,等到数据被处理后再手动跟新offset。
(OS:相信都是用的手动提交的方式吧~)
*2,在消费前做验证前拿取的数据是否是接着上回消费的数据,不正确则return先行处理排错。
*3,一般来说zookeeper只要稳定的情况下记录的offset是没有问题,除非是多个consumer group 同时消费一个分区的数据,其中一个先提交了,另一个就丢失了。
JVM调优:
*1,scala语言同样是运行在jvm上的,kafka的源码也是用scala编写的,优化的话也可以从jvm上入手。
(OS:jvm可控参数太多了,每一个参数的调整应该经过一系列的测试,我在这边总结不出来)
2,留意底层GC的时间,若GC阻塞导致kafka丢失了zookeeper会话,需要对jvm参数进行调整配置更大的heap size,或者配置zookeeper更大的超时时间
=》以上是我参考博客及结合自己使用情况的一些思考
BLOG URL:
http://www.sohu.com/a/151179123_463989
http://blog.csdn.net/john2522/article/details/64555065
若是我有说错理解错的地方,可以参看原始博客,另外烦请指正!!