基于时间的数据

Elasticsearch 的常用案例之一便是日志记录,它实在太常见了以至于 Elasticsearch 提供了一个集成的日志平台叫做(((“ELK stack”))) ELK stack— Elasticsearch,Logstash,以及 Kibana ——来让这项工作变得简单。

Logstash 采集、解析日志并在将它们写入Elasticsearch之前格式化。Elasticsearch 扮演了一个集中式的日志服务角色, Kibana 是一个 图形化前端可以很容易地实时查询以及可视化你的网络变化。

搜索引擎中大多数使用场景都是增长缓慢相对稳定的文档集合。搜索查找最相关的文档,而不关心它是何时创建的。

日志——以及其他基于时间的数据流例如社交网络活动——实际上有很大不同。索引中文档数量迅速增长,通常随时间加速。 文档几乎不会更新,基本以最近文档为搜索目标。随着时间推移,文档逐渐失去价值。

我们需要调整索引设计使其能够工作于这种基于时间的数据流。

按时间范围索引

如果我们为此种类型的文档建立一个超大索引,我们可能会很快耗尽存储空间。日志事件会不断的进来,不会停顿也不会中断。 我们可以使用 scroll 查询和批量删除来删除旧的事件。但这种方法 非常低效 。当你删除一个文档,它只会被 标记 为被删除(参见 deletes-and-updates)。 在包含它的段被合并之前不会被物理删除。

替代方案是,我们使用一个 时间范围索引。你可以着手于一个按年的索引 (logs_2014) 或按月的索引 (logs_2014-10) 。 也许当你的网页变得十分繁忙时,你需要切换到一个按天的索引 (logs_2014-10-24) 。删除旧数据十分简单:只需要删除旧的索引。

这种方法有这样的优点,允许你在需要的时候进行扩容。你不需要预先做任何艰难的决定。每天都是一个新的机会来调整你的索引时间范围来适应当前需求。 应用相同的逻辑到决定每个索引的大小上。起初也许你需要的仅仅是每周一个主分片。过一阵子,也许你需要每天五个主分片。这都不重要——任何时间你都可以调整到新的环境。

别名可以帮助我们更加透明地在索引间切换。当创建索引时,你可以将 logs_current 指向当前索引来接收新的日志事件, 当检索时,更新 last_3_months 来指向所有最近三个月的索引:

  1. POST /_aliases
  2. {
  3. "actions": [
  4. { "add": { "alias": "logs_current", "index": "logs_2014-10" }}, <1>
  5. { "remove": { "alias": "logs_current", "index": "logs_2014-09" }}, <1>
  6. { "add": { "alias": "last_3_months", "index": "logs_2014-10" }}, <2>
  7. { "remove": { "alias": "last_3_months", "index": "logs_2014-07" }} <2>
  8. ]
  9. }

<1> 将 logs_current 由九月切换至十月。

<2> 将十月添加到 last_3_months 并且删掉七月。