一、问题描述
在使用Flume进行数据同步传输时,外部以Flume Source识别的格式向Flume发送Event,当Source接收Event时,它将其存储到一个或多个channel。该channel是一个被动存储器,可以保持Event直到它被Sink消耗。以数据库数据作为Flume Source的数据源,通过sql查询数据库的结果向Flume发送Event。往另一数据表插入数据作为Flume Sink。为保证Event(即Flume Source接收到的由sql查询获取到的数据经过头部等封装成固定格式)能够被传输处理,最终被Sink消耗,就必须保证Sink能够识别处理Event。通俗易懂的讲就是:如果sql只查询了8个字段的数据,却要让Sink往另一张表的9个字段replace数据,Flume就会死掉然后告诉你Unable to deliver event。当然我们在配置时肯定不会范以上的低级错误,但这并不能保证程序就能绝对的运行正常。接下来就通过举例演示和处理Unable to deliver event的问题。
Event示例: { headers:{} body: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21 0D Hello world!. }
二、解决问题
现在有以上表格,欲用Flume将其数据同步到另一表格中,其正常的情况会如下图所示:
但如果遇到数据某些字段为空,比如下面这样,Flume就会出错了。
由于数据表中几个字段为空,所以导致Flume无法处理Event。此时大家可能会想是不是sql查询到空值或Null直接忽略不返回,最终导致Flume Event body_length无法与column_length匹配,显然肯定不是。那是不是sql查询时每个字段都判断一下是否为空保证最终结果不会存在问题呢。这看似是个可行的办法,但如果遇到要查询几十上百个字段,亦或者是其等又该如何呢。下图可以给我们提供解决的思路。
大家从以上根据以上图片不难看出,sql也能将空值进行返回,问题出在如果Event如果后续值都为空,body_length的值会忽略掉后面的空值,导致Flume无法处理Event最终出现Unable to deliver event的问题。因此解决的办法就是确保最后一个字段不为空即可。根据数据库的不通,可通过不同的函数进行判断处理。可参照如下链接: