优化缓存以大量使用无痛脚本ES 6.4.2

时间:2018-12-07 13:26:40

标签: elasticsearch elasticsearch-painless

tl; dr::如何更好地将文件系统缓存用于数百万个脚本查询?每个输出到ES的Logstash都会导致运行无痛脚本,从而导致查询。如果查询未由文件系统缓存(由于没有更多可用的RAM),则读磁盘IO上升。我如何最好地进行优化?

  • Elasticsearch版本:6.4.2
  • JVM:openjdk 1.8.0_181
  • 两个节点,总可用系统内存为84GB
  • 每月输入3次250GB JSON
  • 磁盘是SATA SSD(在RAID 0中)和NVMe的组合

我正在通过Logstash处理250 GB的JSON日志,并将其输出到Elasticsearch。输入日志包含整个重复项,因此可以使用无痛脚本来对照Elasticsearch中的内容检查输入日志的时间戳。如果它是新的时间戳,则它将时间戳添加到数组中。否则,什么也不会发生。

问题在于,处理越深入,索引编制就越慢。而且这并不是一个缓慢而逐渐的下降(请参见下图)。在一个小时内,它从18,000 ep / s变为2,000 ep / s。

index rate dropping

在所有文件系统缓存都用完之前,索引速率非常好。实际上,我通过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
   }
}

问题

  1. 如何最好地优化用例?每个输出到ES的Logstash都会导致运行无痛脚本,从而导致查询。如果查询未由文件系统缓存,则读磁盘IO上升。我意识到我可以增加更多的内存,但是最终,我的数据集将超过250GB,并且我不想每次要执行大量索引时都必须使用200+ GB的内存。
  2. 还有另一种方法可以做我想做的事吗?我可以为所有数据建立索引,然后让Elasticsearch合并具有相同文档ID但时间戳不同的文档。例如,拿两个具有相同ID,两个版本不同但时间戳值不同(在数组中)的文档合并到一起?

0 个答案:

没有答案