时间序列建模 #
时间序列数据(如日志、指标、事件流)是 Easysearch 的常见用例。这类数据有几个特点:文档数量快速增长、基本不更新、主要查询最近的数据。本页介绍如何为时间序列数据设计索引结构。
时间序列数据的特点 #
与传统的搜索场景不同,时间序列数据有以下特点:
- 文档数量快速增长:日志、指标等数据持续写入,不会停顿
- 文档基本不更新:写入后很少修改,主要是追加
- 查询集中在最近数据:大多数查询关注最近几小时、几天或几周的数据
- 旧数据逐渐失去价值:随着时间推移,旧数据的查询频率降低
按时间范围索引 #
如果我们为此种类型的文档建立一个超大索引,我们可能会很快耗尽存储空间。日志事件会不断的进来,不会停顿也不会中断。
我们可以使用 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 别名来查询最近三个月的数据。
时间序列索引的最佳实践 #
1. 选择合适的索引粒度 #
- 按年索引:适合数据量较小、查询跨度较长的场景
- 按月索引:适合中等数据量、查询跨度中等的场景
- 按天索引:适合数据量很大、查询主要集中在最近几天的场景
2. 合理设置分片数 #
- 根据单索引的数据量设置分片数
- 避免过多的小分片,也避免过少的大分片
- 考虑查询的并行度和写入的吞吐量
3. 使用索引模板 #
使用索引模板可以自动创建时间序列索引:
PUT /_template/logs_template
{
"index_patterns": ["logs_*"],
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"message": {
"type": "text"
}
}
}
}
4. 定期清理旧数据 #
- 根据业务需求设置数据保留策略
- 定期删除超过保留期的索引
- 可以使用索引生命周期管理(如果支持)自动化这个过程
查询时间序列数据 #
查询时间序列数据时,通常需要:
- 指定时间范围:使用
range查询过滤时间 - 使用别名:通过别名查询多个时间段的索引
- 时间聚合:使用
date_histogram聚合分析趋势
示例:
GET /last_3_months/_search
{
"query": {
"range": {
"@timestamp": {
"gte": "now-7d/d"
}
}
},
"aggs": {
"per_hour": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "hour"
}
}
}
}
小结 #
- 时间序列数据适合按时间范围组织索引,而不是使用单个大索引
- 使用别名可以透明地管理时间序列索引的切换
- 根据数据量和查询模式选择合适的索引粒度(年/月/天)
- 定期清理旧数据,避免存储成本过高
- 使用索引模板自动化索引创建过程
下一步可以继续阅读: