比如csv文件的内容如下:
rec1,1,5,5
rec1,2,2,2
rec1,3,44,44
rec1,4,33,22
rec2,5,66,55
rec2,6,4,4
csv的mapping:
csv {
separator => ","
skip_empty_rows => true
columns => [
"Sensornr",
"serial_nr",
"test2",
"test3"
]
convert => {
"serial_nr" => "float"
"test2" => "float"
"test3" => "float"
}
}
我希望在每条记录添加到ES的时候,查询当前记录的[Sensornr]是否以前出现过,如果没有出现过,就增加一个字段 [FirstIn] = 'Y', 如果以前曾经出现过,就增加一个字段 [FirstIn] = 'N'.
logstash的file input插件每次读取很多行新增的数据,所以除了查询当前条记录出现在ES的中的数量外,还要考虑同一批次的数据中是否包含着当前 [Sensornr]
首先查询当前记录的 [Sensornr] 是否出现在当前读取批次中,用到了throttle filter,如果当前 [Sensornr] 出现在了同一批数据中,则将第2此以及以后出现的数据都增加一个tag: "Dup"
throttle {
before_count => 0
after_count => 1
period => 10
max_age => 20
key => "%{Sensornr}"
add_tag => "Dup"
}
同时用elasticsearch filter查询ES中是否有当前记录
elasticsearch {
hosts => "127.0.0.1:9200"
index => "logstash-test2019"
query_template => "esquery.json"
result_size => 1000
aggregation_fields=>
{
"types_count" => "es_count"
}
}
其中的esquery.json内容如下,查询[Sensornr.keyword]的数量,并将结果存在“value_count”中:
{
"query": {
"match": {
"Sensornr":"%{[Sensornr]}"
}
},
"aggs" : {
"types_count" : {
"value_count" : { "field" : "Sensornr.keyword" }
}
}
}
然后根据以上两个查询结果进行综合判断:
if "Dup" not in [tags] and [es_count][value]==0{
mutate{
add_field => {
"FirstIn"=> "Y"
}
}
}
else{
mutate{
add_field => {
"FirstIn"=> "N"
}
#remove_tag => ["Dup"]
}
}
问题来了:
有时候,我会得到这样的结果:
Jan 1, 2020 @ 11:39:52.993 rec1 1 Jan 1, 2020 @ 11:39:52.993 0 Y -
Jan 1, 2020 @ 11:39:52.994 rec1 2 Jan 1, 2020 @ 11:39:52.994 - N Dup
Jan 1, 2020 @ 11:39:52.994 rec1 3 Jan 1, 2020 @ 11:39:52.994 - N Dup
Jan 1, 2020 @ 11:39:52.995 rec1 4 Jan 1, 2020 @ 11:39:52.995 - N Dup
Jan 1, 2020 @ 11:40:29.116 rec2 5 Jan 1, 2020 @ 11:40:29.116 - N Dup
Jan 1, 2020 @ 11:40:29.117 rec2 6 Jan 1, 2020 @ 11:40:29.117 0 Y -
意味着rec2 - 6 被认为以前不存在重复记录,而rec2 - 5被认为以前存在重复记录,这与我csv文件中的顺序不符。
通过在https://discuss.elastic.co/t/why-input-plugin-file-doesnt-read-lines-in-sequence/213476进行提问,得知原来在logstash的pipeline配置中,有2个配置项目影响着文件读取顺序:
pipeline.workers: 1 <===同时工作的管道数
pipeline.java_execution: true <===默认配置为true
如果pipeline.workers配置成大于1的值,个人理解logstash读取文件的顺序会不确定,因为不同的workers处理不同行。
根据网友的回复,即便pipeline.workers配置为1,如果pipeline.java_execution被启用的话,仍然会引起logstash将读取到的数据行重新排序。而pipeline.java_execution在默认配置中就是true。
另外,按照网友回复,建议将throttle的before_count设置为-1,防止第1条数据被当作throttled的数据。
综上所述,解决csv文件不按顺序处理数据行的方法:
1. pipeline.workers设置为1
2. pipeline.java_execution设置为false
3. throttle的before_count设置为-1
再观察一段时间,看看这样是否可以完美标记新出现的重复记录。