基于时间的数据

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

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

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

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

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

按时间范围索引

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

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

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

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

POST /_aliases
{
  "actions": [
    { "add":    { "alias": "logs_current",  "index": "logs_2014-10" }}, 
    { "remove": { "alias": "logs_current",  "index": "logs_2014-09" }}, 
    { "add":    { "alias": "last_3_months", "index": "logs_2014-10" }}, 
    { "remove": { "alias": "last_3_months", "index": "logs_2014-07" }}  
  ]
}

logs_current 由九月切换至十月。

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