0x01 前言

我最近重建某些服务的时候遇到日志格式发生了变化,某些字段的type也做了修改,这时候需要将以前的索引进行reindex操作。

我刚开始配置elasticsearch的时候并没有设定别名,这里会带来一个问题:当我将索引A的数据reindex到索引B时,logstash依旧会将数据发送到索引A。

对于reindex的操作,可以参考以下文章:

如果想将数据发送到索引B,就需要修改logstash的output配置并且重启服务。这里又会有一个问题:我收集的所有日志都依赖logstash并且只有一个logstash节点在接收。一旦重启logstash服务就会有一小部分的日志丢失。

当然,这些都是我在家里测试用的服务,丢失一点点日志并不会造成任何损失。如果这是发生在生产环境中呢?这肯定是不可接受的。

0x02 别名

为了提高elasticsearch的可用性,建立一个index的别名是必不可少的。在elasticstack 6.x的文档里关于索引别名的文档连接如下:

索引别名就是一个映射关系,可以是一个索引映射到这个别名,也可以多个索引一起映射到一个别名,如:

如果在外部通过API写入数据到别名alias1中,那么这些数据将会同时存放在两个索引中。

通过别名也可以很好地解决我已开始所说的reindex问题。我会在一开始就建立以下映射关系:

而logstash的ouput如下:

如果某天我日志的格式发生了变化,同时某些字段的类型也发生了变化,我只需要新建一个index:

然后将旧的index从别名中移除,同时将新的index映射到别名中:

这样就可以实现elasticsearch数据的读写实现无缝对接。成功切换index后就可以进行reindex的操作:

当然,在kibana中也需要将别名添加到index pattern中,而不是实际的index名称:

别名还提供了其他更多的高级功能,具体请参考官方文档。

0x03 其他

还有一点需要注意的,elasticsearch的索引模板匹配规则请不要匹配上别名的名称。例如我nginx日志在elasticsearch中的索引模板如下:

index_patterns字段为匹配规则,匹配一切传入public-nginx-*索引的数据,其中就包含public-nginx-main-v1与public-nginx-main-v2这两个索引,但不匹配public-ngx-alias这个别名名称。

如果把别名也匹配上,那么就算你怎样reindex也无法调整旧数据的字段类型。

请不要给别名设置索引模板,所有操作都在索引上操作即可。

0x04 结语

别名的操作起来并不复杂,只是reindex倒腾数据很耗时间而已。