Logstash从SQL Server同步至Elasticsearch丢失记录问题排查
我用Logstash将SQL Server中的数据同步至Elasticsearch,数据库查询结果为2027203条,但每次同步后Elasticsearch索引中都会少2298条记录。hwgdid是查询结果中的唯一非空字段,我的Logstash配置如下:
input { jdbc { jdbc_driver_library => "F:\MG_ES\elasticsearch-5.4.3\elasticsearch-5.4.3\lib\sqljdbc42.jar" jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver" jdbc_connection_string => "******" jdbc_user => "*******" jdbc_password => "*******" statement => "select * from ******" jdbc_paging_enabled => "true" jdbc_page_size => "500000" } } filter { mutate { remove_field => [ "message", "path", "score", "@version", "host" ] } #mutate { convert => ["REGCONNTYPEID","integer"]} #mutate { convert => ["data_time_id","integer"]} } output { elasticsearch { hosts => "localhost" index => "sql_elk_fct_data" document_type => "devices" document_id => "%{hwgdid}" } #stdout { codec => rubydebug { metadata=> true } } }
在Kibana中查看的记录数少于数据库查询结果,请问该问题可能的原因是什么?
可能的原因及排查方向
结合你的配置和问题现象,我梳理了几个最可能的原因,你可以逐一排查:
hwgdid存在重复值:你在输出配置里指定了document_id => "%{hwgdid}",这意味着ES中同一个hwgdid只会保留最后一条同步的记录——后面的会直接覆盖前面的。如果数据库里刚好有2298条重复的hwgdid记录,那最终ES的数量自然会比数据库少这么多。建议先查数据库里的重复情况,比如执行这条SQL:SELECT hwgdid, COUNT(*) FROM ****** GROUP BY hwgdid HAVING COUNT(*) > 1,统计下重复的条目数,看是否和缺失的数量对应。分页查询导致的数据遗漏:你开启了JDBC分页,页大小设为500000。但如果查询语句没有指定明确的排序字段,SQL Server的分页逻辑可能会出现问题——比如某些记录在分页边界被跳过或者重复读取。建议给你的查询语句加上排序,比如
select * from ****** ORDER BY hwgdid(毕竟hwgdid是非空字段,适合当排序依据),这样分页时就能保证数据的一致性,避免丢失。数据写入时的异常丢弃:虽然你注释掉了类型转换的配置,但如果某些字段的数据类型和ES索引的映射不兼容,或者存在ES无法解析的特殊值,就会导致这条文档写入失败被丢弃。建议你临时打开Logstash的stdout输出(把配置里的stdout部分注释去掉),跑一小段时间看看有没有报错的记录;或者直接去Logstash的日志目录(一般是
logs/logstash-plain.log)里找有没有_status => failure的条目,这些就是写入失败的记录。Kibana显示的延迟问题:有时候Kibana的计数可能没有实时同步ES的最新状态,因为ES默认1秒才刷新一次索引。你可以手动刷新索引:在Kibana的Dev Tools里执行
POST /sql_elk_fct_data/_refresh,然后再去查看计数。另外,建议直接用ES的Count API查询准确数量:GET /sql_elk_fct_data/_count,对比这个结果和数据库的数量,确认是真的少了数据,还是Kibana显示的问题。ES的写入限制或磁盘问题:如果ES所在的磁盘空间不足,或者你的索引设置了最大文档数限制,也会导致部分文档无法写入。可以去ES的日志文件(
elasticsearch.log)里看看有没有磁盘告警或者写入失败的错误信息。驱动或版本兼容性问题:你用的是Elasticsearch 5.4.3,对应的Logstash也应该是5.x版本,要确认你的SQL Server JDBC驱动(sqljdbc42.jar)和数据库版本是否兼容,有时候驱动版本不匹配会导致查询时丢失部分数据。
内容的提问来源于stack exchange,提问作者Mrin

