Elasticsearch最佳实践 之 日志场景优化

1. 背景

       Elasticsearch可广泛应用于日志分析、全文检索、结构化数据分析等多种场景,大幅度降低维护多套专用系统的成本,在开源社区非常受欢迎。然而Elasticsearch为满足多种不同的使用场景,底层组合使用了多种数据结构,部分数据结构对具体的用户使用场景可能是冗余的,从而导致默认情况下无法达到性能和成本最优化。

       幸运的是,Elasticsearch提供非常灵活的模板配置能力,用户可以按需进行优化。多数情况下,用户结合使用场景进行优化后,Elasticsearch的性能都会有数倍的提升,成本也对应有倍数级别的下降。本文主要介绍不同日志使用场景下的调优经验。

2. 日志处理基本流程

       日志处理的基本流程包含:日志采集 -> 数据清洗 -> 存储 -> 可视化分析。Elastic Stack提供完整的日志解决方案,帮助用户完成对日志处理全链路的管理,推荐大家使用。每个流程的处理如下:

  • 日志采集:从业务所在的机器上,较实时的采集日志传递给下游。常用开源组件如Beats、Logstash、Fluentd等。
  • 数据清洗:利用正则解析等机制,完成日志从文本数据到结构化数据的转换。用户可使用Logstash 或 Elasticsearch Ingest模块等完成数据清洗。
  • 存储:使用Elasticsearch对数据进行持久存储,并提供全文搜索和分析能力。
  • 可视化分析:通过图形界面,完成对日志的搜索分析,常用的开源组件如Kibana、Grafana。
image.png

       使用Elastic Stack处理日志的详细过程,用户可参考官方文章Getting started with the Elastic Stack,这里不展开介绍。

3. 日志场景调优

       对于Elasticsearch的通用调优,之前分享的文章Elasticsearch调优实践,详细介绍了Elasticsearch在性能、稳定性方面的调优经验。而对于日志场景,不同的场景使用方式差别较大,这里主要介绍常见使用方式下,性能和成本的优化思路。

3.1 基础场景

       对于多数简单日志使用场景,用户一般只要求存储原始日志,并提供按关键字搜索日志记录的能力。对于此类场景,用户可跳过数据清洗阶段,并参考如下方式进行优化:

  • 打开最优压缩,一般可降低40%存储。
  • 设置原始日志字段(message)为text,去除keyword类型子字段,提供全文搜索能力,降低存储。
  • 关闭_all索引,前面已通过message提供全文搜索能力。
  • 对于其他字符串字段,统一设置为keyword类型,避免默认情况下字符串字段同时存储text、keyword两种类型的数据。
  • 使用开源组件(如Beats)上报数据时会包含较多辅助信息,用户可通过修改组件配置文件进行裁剪。

       这样去除message的keyword子字段、_all等冗余信息后,再加上最优压缩,可以保证数据相对精简。下面给出这类场景的常用模板,供用户参考:

{
	"order": 5,
	"template": "my_log_*",
	"settings": {
		"translog.durability": "async",
		"translog.sync_interval": "5s",
		"index.refresh_interval": "30s",
		"index.codec": "best_compression"    // 最优压缩
	},
	"mappings": {
		"_default_": {
			"_all": {                          // 关闭_all索引
				"enabled": false
			},
			"dynamic_templates": [
				{
					"log": {                       // 原始日志字段,分词建立索引
						"match": "message",
						"mapping": {
							"type": "text"
						}
					}
				},
				{
					"strings": {                   // 其他字符串字段,统一设置为keyword类型
						"match_mapping_type": "string",
						"mapping": {
							"type": "keyword"
						}
					}
				}
			]
		}
	}
}

3.2 精准搜索场景

       对于部分用户,普通的全文检索并不能满足需求,希望精准搜索日志中的某部分,例如每条日志中包含程序运行时多个阶段的耗时数据,对具体一个阶段的耗时进行搜索就比较麻烦。对于此类场景,用户可基于基础场景,进行如下调整:

  • 清洗过程中,可仅解析出需要精准搜索的部分作为独立字段,用于精准搜索。
  • 对于精准搜索字段,如果无排序/聚合需求,可以关闭doc_values;对于字符串,一般使用keyword,可按需考虑使用text。

       下面给出这类场景的常用模板,供用户参考:

{
	"order": 5,
	"template": "my_log_*",
	"settings": {
		"translog.durability": "async",
		"translog.sync_interval": "5s",
		"index.refresh_interval": "30s",
		"index.codec": "best_compression"    // 最优压缩
	},
	"mappings": {
		"_default_": {
			"_all": {                          // 关闭_all索引
				"enabled": false
			},
			"dynamic_templates": [
				{
					"log": {                       // 原始日志字段,分词建立索引
						"match": "message",
						"mapping": {
							"type": "text"
						}
					}
				},
				{
					"precise_fieldx": {            // 精准搜索字段
						"match": "fieldx",
						"mapping": {
							"type": "keyword",
							"doc_values": false
						}
					}
				},
				{
					"strings": {                   // 其他字符串字段,统一设置为keyword类型
						"match_mapping_type": "string",
						"mapping": {
							"type": "keyword"
						}
					}
				}
			]
		}
	}
}

3.3 统计分析场景

       对于某些场景,日志包含的主要是程序运行时输出的统计信息,用户通常会完全解析日志进行精确查询、统计分析,而是否保存原始日志关系不大。对于此类场景,用户可进行如下调整:

  • 清洗过程中,解析出所有需要的数据作为独立字段;原始日志非必要时,建议去除。
  • 如果有强需求保留原始日志,可以设置该字段enabled属性为false,只存储不索引。
  • 多数字段保持默认即可,会自动建立索引、打开doc_values,可用于查询、排序、聚合。
  • 对部分无排序/聚合需求、开销高的字段,可以关闭doc_values。

       下面给出这类场景的常用模板,供用户参考:

{
	"order": 5,
	"template": "my_log_*",
	"settings": {
		"translog.durability": "async",
		"translog.sync_interval": "5s",
		"index.refresh_interval": "30s",
		"index.codec": "best_compression"    // 最优压缩
	},
	"mappings": {
		"_default_": {
			"_all": {                          // 关闭_all索引
				"enabled": false
			},
			"dynamic_templates": [
				{
					"log": {                       // 原始日志字段,关闭索引
						"match": "message",
						"mapping": {
							"enabled": false
						}
					}
				},
				{
					"index_only_fieldx": {         // 仅索引的字段,无排序/聚合需求
						"match": "fieldx",
						"mapping": {
							"type": "keyword",
							"doc_values": false
						}
					}
				},
				{
					"strings": {                   // 其他字符串字段,统一设置为keyword类型
						"match_mapping_type": "string",
						"mapping": {
							"type": "keyword"
						}
					}
				}
			]
		}
	}
}

ES 5.1及之后的版本,支持关键字查询时自动选择目标字段,用户没有必要再使用原始日志字段提供不指定字段进行查询的能力。

4. 小结

       日志的使用方式比较灵活,本文结合常见的客户使用方式,从整体上对性能、成本进行优化。用户也可结合自身业务场景,参考文章Elasticsearch调优实践进行更细致的优化。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ImportSource

NoSQL Sharding 分片

翻译内容: NoSQL Distilled 第四章 Distribution Models 作者简介: ? 本节摘要: 各位周末好,今天我们主...

441120
来自专栏机器学习算法与Python学习

给Python初学者:如何用 Django 写一个36Kr

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 首先需要说明一下,这篇教程是写给初学...

37670
来自专栏谢慧志的专栏

数据倾斜解决方法总结

在使用Spark、Hive的过程中经常会碰到数据倾斜的问题,本文会持续记录实际工作中碰到的这些问题以及具体解决方案。

3.3K00
来自专栏程序人生

想让服务器跑得快,并不是换个编程语言那么简单

最近一个读者问我:程序君,我是一个经常被你黑的phper,我想学一门新的语言,做服务器开发,看你好像用过好多语言,能推荐一个么?最好是开发效率高,支持并发,性能...

41480
来自专栏恰童鞋骚年

谈谈对于企业级系统架构的理解

在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是三层架构,那么,什么是三层架构呢?它包括表现层,业务层,数据访问层;而对于一个新手来说,从...

14520
来自专栏更流畅、简洁的软件开发方式

文档驱动式代码设计器——代码是设计出来的!

  代码是敲出来的吗?是批量生成出来的吗?   No no no,代码是设计出来的!   如果说到代码生成器,大家可能会想到三层、动软代码生成器、数据库表等等。...

22980
来自专栏后端技术探索

Facebook 宣布开源 Katran,高性能第4层负载平衡器

为了管理Facebook的流量,他们部署了一个分布式PoP服务器作为数据中心的代理。鉴于极高的请求量,PoP和数据中心都面临着巨大挑战,比如如何将大量的后端服务...

17320
来自专栏精细化测试

当代码变更遇上精准测试的总结

敏捷模式下迭代频繁,回归测试时总是不知道变动的范围。Devlop 有的时候也不知道他改了哪些东西,影响到哪些节点,或者是很多人改的,彼此不知道。

50840
来自专栏Crossin的编程教室

听说你好不容易写了个爬虫,结果没抓几个就被封了?

近来知乎上如雨后春笋般冒出了大把大把的爬虫教程。这是好事,学了 Python 基础的同学们可以很轻松地搜出许多练手的例子。不过我不是针对谁,我是说网上绝大多数的...

30190
来自专栏CSDN技术头条

偏爱MySQL,Nifty使用4个Web Server支撑5400万个用户网站

【编者按】Nifty运营网站已经有很长一段时间,而在基于HTML5的WYSIWYG网页制作平台推出后,用户在该公司建立的网站已超过5400万个,同时其中大部分网...

226100

扫码关注云+社区

领取腾讯云代金券