Flume使用udp丢包问题

问题描述

有用户提出通过udp协议发送数据到实时平台,所以考虑在flume接收节点添加udp source来接收udp请求

  • flume配置如下
1
2
3
4
a2.sources.syslog_udp_src.type=syslogudp
a2.sources.syslog_udp_src.host=0.0.0.0
a2.sources.syslog_udp_src.port=5340
a2.sources.syslog_udp_src.channels=test_channel
  • 系统环境如下
1
2
3
CentOS Linux release 7.2.1511
4核cpu
8G内存

在测试中发现当发送速度超过500/s时开始出现数据丢失,开始以为是网络丢包,但通过tcpdump抓包比对发现并没有丢包

netstat -su命令显示有数据包接收失败

1
2
3
4
5
6
Udp:
    4329216468 packets received
    329761 packets to unknown port received.
    301745872 packet receive errors
    337569082 packets sent
    RcvbufErrors: 1061789

 

  • packets received表示application接收到的数据包的数量
  • packets to unknown port表示由于端口没有打开而丢失的数据包数据量,例如应用挂掉或者重启
  • packet receive errors表示接收数据包的异常的数量,需要注意的是error和接收失败的数据包并不是一对一的关系,即有一个数据包有可能会产生多个error

问题原因

当客户端发送一个udp请求到flume时,整个流转顺序是这样的

1
Client -> Kernel UDP socket buffer(4MB) -> Flume UDP Source buffer(64KB) -> Flume Channel buffer(磁盘,file channel)

 

  • flume通过SyslogUDPSource接收UDP请求,底层是使用Netty的OioDatagramChannelFactory来创建服务器端channel,实现BIO(阻塞式IO)。BIO会对每个请求分配一个线程来处理,这种处理模式效率很低。经过测试,Flume UDP只能达到1100+的QPS,0.324MB/s

  • 当client的发送速度大于flume udp source的接收速度时,数据开始在Kernel UDP socket buffer堆积,当buffer满了的时候,后续的请求就会被丢弃,发生packet receive errors

  • 即使平均吞吐量没有超过flume udp的接收能力,但如果出现发送速度波动或者网络波动导致短时间内Kernel UDP socket buffer被填满,也会出现接收失败

解决方案

  • 网上看了一下,有的建议扩大Kernel UDP socket buffer,比如50MB
    1
    2
    
    sysctl -w net.core.rmem_max=52428800
    sysctl -w net.core.netdev_max_backlog=2000
    

但这只能在一定程度上避免波动的问题,如果发送速度大于接收速度,再大的缓存总会有满的时候

  • 用NIO重写flume SyslogUDPSource,提高处理效率,目前并没有这么做的打算,因为采取了下一个方案

  • 部署syslog-ng接收udp请求,并转发到flume tcp source。Syslog-ng是一个轻量框架,并不需要对数据进行过多的处理和缓存,可以直接对udp请求进行转发,并且使用的是多路复用的NIO,因此处理效率很高。即使是这样,经过压力测试发现也同样是有瓶颈,当qps大于24000时开始出现同样的packet receive errors,因为无论如何syslog-ng也是有处理上限的

    1
    2
    
    2.5W QPS,丢包率0.008%
    10W QPS,丢包率2.2%
    
  • 以上两种方案在数据量大到一定程度的时候都不可避免的丢包,所以如果可以的话,应该在数据发送之前就进行必要的过滤,把不需要的数据扔掉,降低请求数

  • 最终的解决方案,也是我最推崇的:

放弃UDP,改用TCP

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值