0x01 前言
我最近重建某些服务的时候遇到日志格式发生了变化,某些字段的type也做了修改,这时候需要将以前的索引进行reindex操作。
我刚开始配置elasticsearch的时候并没有设定别名,这里会带来一个问题:当我将索引A的数据reindex到索引B时,logstash依旧会将数据发送到索引A。
对于reindex的操作,可以参考以下文章:
如果想将数据发送到索引B,就需要修改logstash的output配置并且重启服务。这里又会有一个问题:我收集的所有日志都依赖logstash并且只有一个logstash节点在接收。一旦重启logstash服务就会有一小部分的日志丢失。
当然,这些都是我在家里测试用的服务,丢失一点点日志并不会造成任何损失。如果这是发生在生产环境中呢?这肯定是不可接受的。
0x02 别名
为了提高elasticsearch的可用性,建立一个index的别名是必不可少的。在elasticstack 6.x的文档里关于索引别名的文档连接如下:
索引别名就是一个映射关系,可以是一个索引映射到这个别名,也可以多个索引一起映射到一个别名,如:
{
"actions": [
{
"add": {
"alias": "alias1",
"index": "test1"
}
},
{
"add": {
"alias": "alias1",
"index": "test2"
}
}
]
}
如果在外部通过API写入数据到别名alias1中,那么这些数据将会同时存放在两个索引中。
通过别名也可以很好地解决我已开始所说的reindex问题。我会在一开始就建立以下映射关系:
{
"actions": [
{
"add": {
"alias": "public-ngx-alias",
"index": "public-nginx-main-v1"
}
}
]
}
而logstash的ouput如下:
output {
if "server_ngx_access_log" in [tags] {
elasticsearch {
hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]
manage_template => false
index => "public-ngx-alias"
}
}
}
如果某天我日志的格式发生了变化,同时某些字段的类型也发生了变化,我只需要新建一个index:
curl -XPUT 'es6-node1.t.com:9200/public-nginx-main-v2?pretty'
然后将旧的index从别名中移除,同时将新的index映射到别名中:
curl -XPOST 'es6-node1.t.com:9200/_aliases?pretty' -H 'Content-Type: application/json' -d'
{
"actions" : [
{ "remove" : { "index" : "public-nginx-main-v1", "alias" : "public-ngx-alias" } },
{ "add" : { "index" : "public-nginx-main-v2", "alias" : "public-ngx-alias" } }
]
}
'
这样就可以实现elasticsearch数据的读写实现无缝对接。成功切换index后就可以进行reindex的操作:
curl -XPOST 'es6-node1.t.com:9200/_reindex?pretty' -H 'Content-Type: application/json' -d'
{
"source": {
"index": "public-nginx-main-v1"
},
"dest": {
"index": "public-nginx-main-v2"
}
}
'
当然,在kibana中也需要将别名添加到index pattern中,而不是实际的index名称:
别名还提供了其他更多的高级功能,具体请参考官方文档。
0x03 其他
还有一点需要注意的,elasticsearch的索引模板匹配规则请不要匹配上别名的名称。例如我nginx日志在elasticsearch中的索引模板如下:
{
"public_nginx": {
"order": 0,
"index_patterns": [
"public-nginx-*"
],
"settings": {
"index": {
"number_of_shards": "5"
}
},
"mappings": {
"doc": {
"properties": {
"bytes": {
"type": "long"
},
"client_ip": {
"type": "ip"
},
"geoip": {
"dynamic": true,
"properties": {
"location": {
"type": "geo_point"
}
},
"type": "object"
},
"request_time": {
"type": "float"
},
"upstream_response_time": {
"type": "float"
}
}
}
},
"aliases": {}
}
}
index_patterns字段为匹配规则,匹配一切传入public-nginx-*索引的数据,其中就包含public-nginx-main-v1与public-nginx-main-v2这两个索引,但不匹配public-ngx-alias这个别名名称。
如果把别名也匹配上,那么就算你怎样reindex也无法调整旧数据的字段类型。
请不要给别名设置索引模板,所有操作都在索引上操作即可。
0x04 结语
别名的操作起来并不复杂,只是reindex倒腾数据很耗时间而已。






















