【异常】转载 KAFKA生产者数据丢失问题的排查

1)如何定位到是写入端丢失数据的,而不是YDB消费者端丢失数据的?
    kafka支持数据的重新回放的功能(换个消费group),我们清空了ydb的所有数据,重新用kafka回放了原先的数据。
    如果是在ydb消费端丢失数据,那么第二遍回放数据的结果,跟第一次消费的数据在条数上肯定会有区别,完全一模一样的几率很低。数据回放结果为:与第一次回放结果完全一样,可以确认为写入段丢失。


2)写入kafka数据为什么会丢失?
导入数据我们采用的为kafka给的官方的默认示例,官方默认并没有处理网络负载很高或者磁盘很忙写入失败的情况,一旦网络中断或者磁盘负载很高导致的写入失败,并没有自动重试重发消息。

    第1次测试是在共享集群环境上做的测试,由于有其他任务的影响,网络与负载很不稳定,就会导致数据丢失。
    第2次测试是在独立集群,并没有其他任务干预,但是我们导入程序与kafka不在一台机器上,而我们又没有做限速处理(每小时导入5亿条数据)
    千兆网卡的流量常态在600~800M左右,如果此时突然又索引合并,瞬间的网络跑满是很正常的,丢包也是很正常的。
    延云之前持续压了20多天,确实一条数据没有丢失,究其原因是导入程序与kafka在同一个机器上,且启用了限速。

3)这个问题如何解决?
    官方给出的默认示例并不可靠,并没有考虑到网络繁忙的情况,并不适合生产。
    故kafka一定要配置上消息重试的机制,并且重试的时间间隔一定要长一些,默认1秒钟并不符合生产环境(网络中断时间有可能超过1秒)。
    延云认为,增加如下参数会较大幅度的减少kafka写入数据照成的数据丢失,在公司实测,目前还没遇到数据丢失的情况。

    设置生产者重试等相关参数:

         props.put("compression.type", "gzip");   发送的数据会压缩
         props.put("linger.ms", "50");  一个Batch批量发送的时间阈值,最大这个时间就会发送Batch
         props.put("acks", "all");
         props.put("retries ", 30);
         props.put("reconnect.backoff.ms ", 20000);
         props.put("retry.backoff.ms", 20000);

 

参考:https://www.cnblogs.com/technologykai/articles/8795226.html

 

posted @ 2020-03-25 15:52  lemon胡  阅读(1423)  评论(0编辑  收藏  举报