Logstash导入数据到Elasticsearch时自定义mapping

template概念

使用logstash导入数据到ES中由于索引按天拆分,手动创建mapping非常麻烦,ES内部维护了template,template定义好了mapping,如果索引的名称被template匹配到,那么该索引的mapping就按照template中定义的mapping自动创建。而且template中定义了索引的主分片和副分片的数量,分词等属性。

启动logstash系统会使用一个默认的动态映射模板,模板名字为logstash,使用_template查看。

在启动logstash过程中你会看到如下信息

你看第一行path=>nil表示没有找到自定义模板,那就使用默认模板,并且最后将模板存储在elasticsearch模板路径中,以logstash命名。模板内容:

{
	"logstash": {
		"order": 0,
		"template": "logstash-*",
		"settings": {
			"index": {
				"refresh_interval": "5s"
			}
		},
		"mappings": {
			"_default_": {
				"dynamic_templates": [{
					"message_field": {
						"mapping": {
							"fielddata": {
								"format": "disabled"
							},
							"index": "analyzed",
							"omit_norms": true,
							"type": "string"
						},
						"match_mapping_type": "string",
						"match": "message"
					}
				}, {
					"string_fields": {
						"mapping": {
							"fielddata": {
								"format": "disabled"
							},
							"index": "analyzed",
							"omit_norms": true,
							"type": "string",
							"fields": {
								"raw": {
									"ignore_above": 256,
									"index": "not_analyzed",
									"type": "string"
								}
							}
						},
						"match_mapping_type": "string",
						"match": "*"
					}
				}],
				"_all": {
					"omit_norms": true,
					"enabled": true
				},
				"properties": {
					"@timestamp": {
						"type": "date"
					},
					"geoip": {
						"dynamic": true,
						"properties": {
							"ip": {
								"type": "ip"
							},
							"latitude": {
								"type": "float"
							},
							"location": {
								"type": "geo_point"
							},
							"longitude": {
								"type": "float"
							}
						}
					},
					"@version": {
						"index": "not_analyzed",
						"type": "string"
					}
				}
			}
		},
		"aliases": {}
	}
}

不指定索引的名字,使用logstash默认模板创建索引,logstash会向Elasticsearch创建一个名为logstash-*的按天创建的index以及名为logstash的template,之后每天创建一个logstash-%{+YYYY.MM.dd}的index用于存储日志。

                          

这种情况下,logstash-%{+YYYY.MM.dd}索引就会有两个type, 一个是defalut, 一个是logs.

不使用logstash默认模板创建索引

如果不想使用logstash默认创建的模板创建索引,有两种解决方式:

1、是可以在logstash配置文件中的output中指定index索引名称,自定义索引名字不以logstash-开头,默认模板只匹配以logstash-开头的索引。

2、修改manage_template=>false #关闭logstash自动管理模板功能,logstash将不会调用Elasticsearch API创建模板  ,默认为true,如果该参数为false,则自定义的模板也不会加载。

索引type的问题

默认情况下,logstash向Elasticsearch提交创建的索引的type为"logs",如果需要自定义type, 有两种方式,一种是在output里指定document_type参数,另一种是在input里指定type参数, output里的document_type优先级大于input里的type,但是在5.0版本以后input插件里面的type属性不会被默认为文档的类型了,需要使用document_type在output插件中指定。

自定义模板

1、在logstash-2.4.0目录下创键mkdir templates

2、vim demo_template.json编写template文件

3、在logstash的output插件中配置如下参数

4、

manage_template => true 开启logstash自动管理模板功能,默认manage_template参数为true, 否则logstash将不会调用Elasticsearch API创建模板。  
template => "/xxx/logstash-2.4.0/templates/logs.json" 模板的路径
template_name => "tempalte_name"     映射模板的名字,template_name如果不指定的话,会使用默认值logstash.
template_overwrite => true     是否覆盖已存在的模板,template_overwrite为true则template的order高的,满足同样条件(如均以searchlog-开头)的template将覆盖order低的

(一)静态模板Demo:

{
	"template": "logstash_normal_index-*",
	"order": 1,
	"settings": {
		"number_of_shards": 5,
		"number_of_replicas": 0,
		"refresh_interval": "60s"
	},
	"mappings ": {
		"normal": {
			"dynamic":"strict",
			"properties": {
				"traceid": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"systemid": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"offset": {
					"type": "long"
				},
				"prospector": {
					"properties": {
						"type": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						}
					}
				},
				"source": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"message": {
					"search_analyzer": "ik_smart",
					"analyzer": "ik",
					"store": true,
					"type": "string"
				},
				"tags": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"input": {
					"properties": {
						"type": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						}
					}
				},
				"@timestamp": {
					"format": "strict_date_optional_time||epoch_millis",
					"type": "date"
				},
				"loglevel": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"@version": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"beat": {
					"properties": {
						"hostname": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						},
						"name": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						},
						"version": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						}
					}
				},
				"host": {
					"properties": {
						"name": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						}
					}
				},
				"fields": {
					"properties": {
						"type": {
							"index": "not_analyzed",
							"store": true,
							"type": "string"
						}
					}
				},
				"logtime": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				},
				"methodname": {
					"index": "not_analyzed",
					"store": true,
					"type": "string"
				}
			}
		}
	}
}

首先有2个问题,如果一个index下有新的type写入,之前没有定义怎么办?如果一个type下有新的字段写入,之前没有定义怎么办?

如果一个index下有新的type写入,之前没有定义,则根据_default_定义的属性来匹配生成。如果一个type下有新的字段写入,之前没有定义,则根据该type下的dynamic_templates来匹配生成。

(二)动态模板Demo:

{

	"template": "logstash_perform_index-*",

	"settings": {

		"index.number_of_shards": 4,

		"number_of_replicas": 0
	},

	"mappings": {

		"_default_": {

			"_all": {
				"enabled": true,
				"omit_norms": true
			},

			"dynamic_templates": [{

				"message_field": {

					"match": "message",

					"match_mapping_type": "string",

					"mapping": {

						"type": "string",
						"index": "analyzed",
						"omit_norms": true,

						"fielddata": {
							"format": "disabled"
						}

					}

				}

			}, {

				"string_fields": {

					"match": "*",

					"match_mapping_type": "string",

					"mapping": {

						"type": "string",
						"index": "not_analyzed",
						"doc_values": true

					}

				}

			}],

			"properties": {

				"@timestamp": {
					"type": "date"
				},

				"@version": {
					"type": "string",
					"index": "not_analyzed"
				}
			}

		}

	}

}

 

总结:template模板使用

1.静态模板 :
                     适合索引字段数据固定的场景,一旦配置完成,不能向里面加入多余的字段,否则会报错 ,测试不会出错,会自动映射,如果加入"dynamic":"true",则会报错。
                     优点:scheam已知,业务场景明确,不容易出现因字段随便映射从而造成元数据撑爆es内存,从而导致es集群全部宕机 
                     缺点:字段数多的情况下配置稍繁琐

1.动态模板 :
      适合字段数不明确,大量字段的配置类型相同的场景,多加字段不会报错 
                     优点:可动态添加任意字段,无须改动scheaml, 
                     缺点:如果添加的字段非常多,有可能造成es集群宕机

定制索引模板,是搜索业务中一项比较重要的步骤,需要注意的地方有很多,比如: 
       (1)字段数固定吗 
       (2)字段类型是什么 
       (3)分不分词 
       (4)索引不索引 
       (5)存储不存储 
       (6)排不排序 
       (7)是否加权 
除了这些还有其他的一些因素,比如,词库的维护改动,搜索架构的变化等等。 
如果前提没有充分的规划好,后期改变的话,改动其中任何一项,都需要重建索引,这个代价是非常大和耗时的,尤其是在一些数据量大的场景中

参考:

Elasticsearch - 自动检测及动态映射Dynamic Mapping

logstash在向elasticsearch输出数据时的动态映射模板问题

logstash使用template提前设置好maping同步mysql数据到Elasticsearch5.5.2

Elasticsearch dynamic mapping(动态映射) 策略

logstash在Elasticsearch中创建的默认索引模板问题

Day9: Elasticsearch template的order

ES系列十一、ES的index、store、_source、copy_to和all的区别

猜你喜欢

转载自blog.csdn.net/qq_39669058/article/details/87615055