背景介绍:创建了两个索引模版,一个是针对java的应用日志,一个是针对nginx的日志,java日志是nginx日志的量的50倍左右,且做了数据冷热处理,现象是java日志查询很快,nginx日志哪怕很小的时间范围,查询也异常缓慢。
问题原因:通过对比索引模版,发现nginx的模版多了一个运行时字段的填写,而且把时间戳字段添加上去了,刚开始以为没啥影响,因为索引日志也能正常生成,数据结构也和原始日志字段相匹配,就没在意,后面实在没有其他的差别,就查了下运行时字段的功能介绍,原来自己当初没对这个功能做仔细研究,功能误用,导致查询变慢。官方文档解释,运行时字段添加后,会不会占用索引的空间,因此日志索引不会变大,但会牺牲搜素性能,这也是当初为啥查询变得异常缓慢的问题,添加运行时字段后,改字段不会变成索引,而我恰恰把时间戳填写上去了,而es默认就是采用时间戳作为字段索引,没有了索引就像mysql中字段缺少查询的索引字段一样,少量的数据也会引起查询变慢。
解决:删除运行时字段的时间戳字段,同时将@tiemstamp添加在已映射字段如下图,因为nginx的时间格式无法匹配动态模版的时间格式,这里只能手动将@timestamp设置为日期格式,删除之前的日志索引,重新生成后,再次查看,速度飞一般的体验。
另一种解决方法:可以同时兼顾索引性能和存储空间,就是在设置运行时字段同时将改字段设置为索引字段,这样联合使用效果也不错【官方文档介绍:To balance search performance and flexibility, index fields that you’ll frequently search for and filter on, such as a timestamp. Elasticsearch automatically uses these indexed fields first when running a query, resulting in a fast response time. You can then use runtime fields to limit the number of fields that Elasticsearch needs to calculate values for. Using indexed fields in tandem with runtime fields provides flexibility in the data that you index and how you define queries for other fields.】