0x01 前言

最近在kibana中添加可视化视图时需要增加一个流量统计的图标,可是遇到了很严重的问题。

我们都知道数据是具有类别之分的,例如:

  1. 数字:long, integer, short, byte, double, float
  2. 字符串
  3. 日期格式
  4. … …

而保存在elasticsearch中的数据一样需要指明格式,要不然就无法生成特定的图表。例如计算总和、均值这类运算则需要数字的支持,这也是合乎常理的,如果值的类型为字符串,这要怎样进行数学运算?

0x02 问题

因为我在配置elasticsearch的时候还没意识到格式的问题,当导入将近20G的数据后,在添加可视化试图时却发现无法添加某些图表。

最显而易见的就是流量统计,我的nginx日志包含bytes这个字段,可是在elasticsearch中是以默认的string类型来存储。这就是导致无法进行数学运算的根本原因。

0x03 思路

因为elasticsearch中已经处理存储着20G的数据,我不希望通过删除索引重新处理数据这种方式解决这个问题,而且日后再遇到这个问题也不可能通过这种粗暴的方式来解决问题。

0x03.1方法一

—————

修正:
2016.12.24:应该先添加模版再调整logstash

—————

在经过一天翻看文档后,我找到了解决办法。大概思路如下:

  1. 新建索引hk1-v2
  2. 将logstash输出索引从hk1指向hk1-v2并重启logstash服务
  3. 为elasticsearch添加”hk1*“模版
  4. 将hk1重新索引至hk1-v2
  5. 删除hk1

0x03.2 方法二

为什么要那么麻烦?通过模版重新定义字段的类型不就好了?

其实这也是可以的,如果你的索引是按天或按月生成,通过模版重新定义字段的类型这种方式很适合你。不过要注意的是,模版只对下一次生成的索引有效。例如:

如果你在24号这天添加模版,而且模版适用于索引格式:filebeat-*;
那么你目前正处于filebeat-2016.12.24这个索引的使用期,模版是不会对这个索引有任何作用的;
模版只对24号以后的索引(如:filebeat-2016.12.25)生效。

这样的话问题又来了:我不是使用这种方式来管理我的索引,我只有一个或者按月度生成,这该怎么办?那只好使用方法一来解决问题。

在这里还需要注意的是,如果你的logstash在实时接收日志,例如syslog的UDP 514端口的日志,那么在重启logstash的时候可能会有几十秒处于无法接收的状态,这段时间的日志可能会丢失!

0x04 模版

首先要向elasticsearch添加模版,在这里我使用kibana中的Dev Tools而不使用curl:

上面的Dev Tools中,左侧作为输入框,右侧为输出框。

我们不需要从头编写模版,因为kibana内置filebeat的模版,我们可以直接进行修改,在输入框中输入以下命令:

并点击运行按钮:

左侧即为logstash中所有的模版,但我们只需要filebeat的模版,请通过以下命令导出:

将输出的所有内容复制到文本编辑器中:

在properties字段下添加以下内容:

要注意这个模版中含有两处properties字段,其中一处是位于geoip下的,请不要修改geoip下的内容:

最后要修改模版名称和匹配的索引,修改2、4行:

最后删除第一行与最后一行的”[“与”]”,删除第二行的 “hk1”: 

完成后即可通过以下命令向elasticsearch中导入模版:

0x05 logstash

如果你按照我之前写的文章进行安装(安装配置Elastic Stack 5),那么你可能在elasticsearch的配置文件中允许自动创建”hk1*”索引:

如果没有,请手动创建:

然后修改output并重启logstash:

0x06 索引

这里要注意的是,如果你的elasticsearch不是以集群模式运行并且数据即为庞大,例如数据量为千万级的,那么重新索引的时间会极为漫长。在重新索引的时候,CPU将长时间处于高负荷,磁盘则处于高IO的环境中。

另一个需要注意的点是,重新索引并不是仅处理修改过的部分,而是所有字段都进行重新索引处理,如果你又多个字段都出现错误,那么可以一并解决。

在重新索引的时候,如果你的服务没有配置集群,那么很有可能通过kibana提取数据时会出现超时的情况。

一切准备就绪后就可以通过以下命令进行重新索引:

重新索引的操作是以task的形式在后台运行,如果你使用kibana提交这个操作,那么在经过预设的超时时间后,kibana会返还超时的提示;如果是使用curl提交操作,在经过一段时间后也会返还超时。

但这个问题不必担心,因为重新索引的操作是以任务(task)的形式在后台工作的,我们可以通过以下命令查看相关任务,在kibana中输入并运行:

在输出框中搜索:reindex 即可看到相关任务信息。以下是类似的返还内容(并不是reindex的任务信息,仅用于说明情况):

请注意第二行(高亮行),这是任务ID,如果遇到需要终止任务的情况,请通过以下命令进行终止:

还有更粗暴的方法:

在重新索引的过程,推荐通过elasticsearch-head插件进行监控,安装方法如下:

在Elasticsearch5中使用Elasticsearch-head插件

0x07 结语

在使用ELK时,最好是先配置elasticsearch,添加模版,确定字段与相关的类型,然后再通过logstash等软件向内导入内容。

使用上面介绍的方法会有几十秒的空档期会导致实时内容丢失,其实还有另一种方法在0停摆时间的情况下进行重新索引操作,这个日后再介绍。

不过重启logstash不会导致通过 *beat(如filebeat) 传入的内容丢失,因为相关的软件之间会有检验机制,这个有机会再作介绍。

修改完成后:

有疑问欢迎给我留言!