问题

        目前官网暂时不支持es8.x版本的connector,但是目前项目组用的es已经是8.6.2版本,针对flink写入es这个问题展开了一系列的debug。

        问题1:兼容问题

        问题2:异常

解决

        问题1:兼容问题

        这个问题es官网针对客户端7.x的有了兼容的方案,因为我们flink1.14.4中用的也是high rest api方式,针对这个我们需要改动flink-connector-es 使得使用兼容模式。我们的es客户端也必须得是7.16及以上版本。

        

flink写入多个sink flink批量写入es_字段

        然后flink部分,我将flink源代码部分拷贝过来,将模式添加完毕即可。

flink写入多个sink flink批量写入es_flink写入多个sink_02

Elasticsearch7ApiCallBridge 中  createClient

flink写入多个sink flink批量写入es_大数据_03

        至此我们的兼容方案已经修改完毕!

问题2:异常

        因为数据的原因,过程还是遇到了很多异常。我们的数据都是动态的去做逻辑,最后生成索引名称,不同数据发送到不同的index中。

异常1:Caused by: java.lang.OutOfMemoryError: Direct buffer memory.

        这个异常很明显了,也不是说写es就会出现,就是在开发过程中,数据大小的问题,导致配置内存不够,从而引发。异常中也指定了我们需要调那些参数,我们对应调一下就可以了。In this case 'taskmanager.memory.framework.off-heap.size' configuration option should be increased. If the error persists then there is probably a direct memory leak in user code or some of its dependencies which has to be investigated and fixed. The task executor has to be shutdown...
 

异常2:java.lang.OutOfMemoryError: GC overhead limit exceeded

        这个也是我们数据大小问题导致oom,那就重新改一下tm 内存大小

异常3:bulk request size 大于 1 ,checkpoint就一直失败

        这个问题一直困扰了我好几天, setBulkFlushMaxActions 这个参数本来是一个优化方案,批量一次输入条数,但是只要大于1就会导致flink作业checkpoint一直失败,es的上游任务就不给es task发送数据,最后的结果就是flink任务挂掉。如果设置为1就一直没问题,自己一直困在了这个问题上,陷入了以为是兼容问题上。

异常4:doc_as_upsert[false], doc[index {[null][_doc][null], source[n/a, actual length: [8.4kb], max length: 2kb]}], upsert[index {[null][_doc][null], source[n/a, actual length: [8.4kb], max length: 2kb]}],

异常5: xxxx scripted_upsert[false], detect_noop[true]},exceptionStackTrace:java.lang.InterruptedException

        还有很多异常,但没有记录下来,其实真正的本质异常是3 4,也是查了各种资料,google。这个问题基本是说bulk写入堆满了,或者是mapping映射问题。数据字段太多了,并且也都是动态字段。一个doc有几百个字段,对起来确实费劲。靠着猜的方式去尝试删除不必要的数据,第一个线上任务再不停解决字段类型问题上终于上线了。其实当时自己对于本质问题还是没解决。

        在继续做接下来的任务的时候还是遇到了异常3的问题,同时异常报出来的是异常5 ,这个任务也是根据逻辑生成动态的10来个索引,最后自己通过Side Outputs 方式将每一个索引分开写入es。在观察中发现只有第一条链路在setBulkFlushMaxActions 大于1时候会一直checkpoint失败。那么问题就锁定到第一个链路上的数据问题上,这次因为数据字段不对,所以去es看一下mapping然后跟我们的代码进行了对比发现确实是类型不统一导致,只要类型不统一就会出现异常4 5这种情况。将类型统一以后,setBulkFlushMaxActions 设置 100 对测试环境再次测试。问题得到了解决,这次也算是真的解决了这个异常。

        

flink写入多个sink flink批量写入es_数据_04

总结

        还是把问题进行分解处理,针对每个链路进行debug,这样可能会更明显的去发现问题的所在。有时候一个问题的发生,可能并不在这个地方,不要陷入在一个地方!