场景介绍
Elk stack 是个好东西大家都知道了,并且就跟全家桶一样都在使用中。
但是对于有一定业务量,并初次使用的公司来说,如何快速接入还是有一定技巧和方法的。
本文介绍的就是当公司内部多个业务需要接入时,如何快速的把各个业务侧的不同需求的日志接入es中的一些思考和实践。
业务log接入Elasticsearch方案分析
方法1
方案内容:各个业务组定义需求字段,并确定字段类型,交由运维组去统一添加维护。
优点:字段维护统一收口,交给专人处理,适合运维团队人员充沛,适合大公司。
缺点:维护成本高,字段变动流程长,不灵活。
方法2
方法内容:约定字段命名规范 交给业务侧研发自行根据约定的规范,添加需求字段。
优点:业务接入快,字典更灵活,运维接入工作少。
缺点:
- 需要业务研发对Es有基本认识。不随意定义需求字段。
- 字段管理分散。适合小公司多业务快速接入Elk体系。
方案选择和分析
两种方案本人都经历过,具体选择哪一个大家可根据各自公司情况去抉择。
这里我们讨论方案2,也是我现在公司使用的场景,下面我们详细说明下。
Elasticsearch 字段类型
虽然Es属于搜索引擎(Lucene),相对于mysql等关系型数据库,对schema的定义不是很严格属于schema-less。
但是比较好的字段定义对于Es的搜索性能和索引大小都起到了关键的作用。
尤其在我们现在使用的场景下,大量业务数据需要接入Es,字段的规范约定更是必要的工作。
在es使用中,字段的查询场景和字段索引类型影响了整体查询吞吐量。
Es主要字段有:
- string
- byte, short, integer, long
- float, double
- boolean
- date
- ip等
可见基本类型都有了,对于业务log的使用场景完全够用了。
使用场景分析
针对于业务日志使用的场景下,查询多为完全匹配,很少使用全文搜索,并使用大量的聚合查询做统计等。
但是公司业务众多,业务中使用的场景也是五花八门。
- 需要统计接口的响应情况
- 需痛统计业务指标
- 需要统计业务分支运行情况
- 等等。
所以想制定一套es字段去通吃是不切实际的。
既然无法制定一套es字段去满足是有需求,那就需要找到一个灵活的方案去定制各种es字段,满足研发的查询需求。
如何去做呢,我们这里引出es的 动态mapping(Dynamic Mapping)。在这假设大家都已经了解会使用了映射(Mapping)。
字段约定与动态mapping
官方说明:
当 Elasticsearch 处理一个位置的字段时,
它通过【动态映射】来确定字段的数据类型且自动将该字段加到类型映射中。
有时这是理想的行为,有时却不是。或许你不知道今后会有哪些字段加到文档中,但是你希望它们能自动被索引。
或许你仅仅想忽略它们。特别是当你使用 Elasticsearch 作为主数据源时,你希望未知字段能抛出一个异常来警示你。
根据之前介绍的es字段类型和业务log的大部分使用场景,可以看出我们需要一种极本的字段类型约定和灵活的字段添加的能力。
这里使用动态mapping配置,去适配业务侧自定义的各种字段,但是我们需要明确的提供字段类型。
{
"template": "json-php*", //(1)
"settings": {
"number_of_shards": 1,
"index.mapper.dynamic": true
},
"mappings": {
"_default_": { //(2)
"dynamic": true, //(3)
"date_detection": false, //(4)
"_all": {
"enabled": false
},
"dynamic_templates": [ //(5)
{
"string_template": {
"match_mapping_type": "string", //(6)
"match": "*", //(7)
"mapping": {
"type": "keyword", //(8)
"null_value": "null"
}
}
},
{
"date": {
"match": "date_*", //(9)
"mapping": {
"type": "date",
"format": "yyyy-MM-dd'T'HH:mm:ssZZ.SSS" //(10)
}
}
},
{
"strings": {
"match_mapping_type": "string",
"match": "s_*", //(11)
"mapping": {
"type": "keyword",
"ignore_above": 256,
"null_value": "null"
}
}
},
{
"long": {
"match_mapping_type": "*",
"match": "l_*",
"mapping": {
"type": "integer" //(12)
}
}
},
{
"double": {
"match_mapping_type": "*",
"match": "d_*",
"mapping": {
"type": "double" //(13)
}
}
},
{
"boolean": {
"match_mapping_type": "boolean",
"match": "b_*",
"mapping": {
"type": "boolean"
}
}
},
{
"analyzer": {
"match": "t_*",
"mapping": {
"type": "text", //(14)
"index": true,
"analyzer": "english", //(15)
"null_value": "null"
}
}
},
{
"ip": {
"match_mapping_type": "*",
"match": "ip_*",
"mapping": {
"type": "ip"
}
}
}
]
}
}
}
- 说明此模版 只会在 index 为 json-php* 才会适配生效。即说明此模版为php业务下json格式的日志
- 定义一个默认的mapping 去放置配置
- 激活动态字段配置
- 禁用时间自动适配,即除下文明确定义,不会再把字符串适配为时间类型了
- dynamic_templates 动态模版配置项,放置动态 mapping 配置的
- 取配所有字符串类型的字段
- 取配所有字段
- 取配的字段类型 设置为es的keyword,即不使用全文文本,只用于确切值进行查询的字段
- 取配所有
date_
开头的字段 - 取配的字段格式必须为此配置的时间格式
- 取配所有
s_
开头的字段 - 取配字段类型设置为
integer
- 取配字段类型设置为
boolean
- 取配字段类型设置为
text
,即全文文本字段,可以进行全文搜索 - 全文搜索的分词规则 使用
english
, 可中文分词,需安装插件
-------
总结
通过上面配置不难看出,我们约定了一些字段命名前缀,并指定了它们的字段类型。
- 明确的可用的字段类型和使用场景。后续使用中不会超出范围,不同类型字段得到有效利用
- 业务侧接入快捷。研发只要查看相关字段约定,即可快速接入,不在关心具体字段的配置细节
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。