tl; dr::如何更好地将文件系统缓存用于数百万个脚本查询?每个输出到ES的Logstash都会导致运行无痛脚本,从而导致查询。如果查询未由文件系统缓存(由于没有更多可用的RAM),则读磁盘IO上升。我如何最好地进行优化?
我正在通过Logstash处理250 GB的JSON日志,并将其输出到Elasticsearch。输入日志包含整个重复项,因此可以使用无痛脚本来对照Elasticsearch中的内容检查输入日志的时间戳。如果它是新的时间戳,则它将时间戳添加到数组中。否则,什么也不会发生。
问题在于,处理越深入,索引编制就越慢。而且这并不是一个缓慢而逐渐的下降(请参见下图)。在一个小时内,它从18,000 ep / s变为2,000 ep / s。
在所有文件系统缓存都用完之前,索引速率非常好。实际上,我通过JVM减少了很多,以便为缓存提供尽可能多的内存。无论如何,最终索引率会大大下降,然后磁盘IO要求很高。看到sdb(一个nvme SSD)花了所有的时间而不是写。
# iostat -m -x 5
avg-cpu: %user %nice %system %iowait %steal %idle
1.16 0.00 7.31 47.55 0.00 43.98
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdb 1.20 64.87 12333.93 20.96 1275.55 0.43 211.51 144.78 11.73 11.71 18.40 0.08 100.10
这是输入数据的示例:
{"timestamp":"1534023333", "hash":"1", "value":"something1"}
{"timestamp":"1534022222", "hash":"1", "value":"something1"}
{"timestamp":"1534011111", "hash":"1", "value":"something1"}
{"timestamp":"1534023333", "hash":"2", "value":"something2"}
{"timestamp":"1534022222", "hash":"2", "value":"something2"}
{"timestamp":"1534011111", "hash":"2", "value":"something2"}
这是Logstash输出和正在使用的简单脚本的示例:
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
index => "testing"
document_id => "%{[hash]}"
doc_as_upsert => true
script => 'if(ctx._source.timestamp.contains(params.event.get("timestamp")[0])) return true; else (ctx._source.timestamp.add(params.event.get("timestamp")[0]))'
action => "update"
retry_on_conflict=>5
}
}
问题: