shan

es滚动索引 —— Rollover api

2019-05-27

当索引过大或过于老旧时,可以使用rollover api创建新的索引;
这个api接受一个别名和一组条件,别名必须指向一个正在工作的索引,一组条件包括:max_age,max_docs,max_size.

创建索引

索引的创建方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PUT /logs-000001 
{
"aliases": {
"logs_write": {}
}
}

# 在logs-000001中添加超过1000个文档后执行下面的语句

POST /logs_write/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

上面的请求会返回下面的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"acknowledged": true,
"shards_acknowledged": true,
"old_index": "logs-000001",
"new_index": "logs-000002",
"rolled_over": true,
"dry_run": false,
"conditions": {
"[max_age: 7d]": false,
"[max_docs: 1000]": true,
"[max_size: 5gb]": false,
}
}

命名新的索引

如果一个已经存在的索引以数字结尾,那么新的索引将会采取相同的模式,即将数值增加。不管旧的索引如何命名,新的索引仍然会是一个长度为6的数字,不足的在数字前面用0填充。
如果旧的索引不匹配这种模式,那么你必须重新为新的索引指定名称:

1
2
3
4
5
6
7
8
POST /my_alias/_rollover/my_new_index_name
{
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

使用日期作为rollover api

使用日期作为索引是非常有用的,如log-2019.2.25-000001, rollover api支持日期格式,并且在日期索引滚动时增加日期和后面的数字。如上面的在max_age=1d时,索引会滚动为log-2019-2-26-000002.
。。。

定义新索引

新索引的settings,mappings以及aliases都是继承自它匹配到的任何索引模板。此外,你可以像创建索引一样在request body中指定settings,mappings以及aliases.请求中的值能够覆盖任何匹配到的模板中的内容。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUT /logs-000001
{
"aliases": {
"logs_write": {}
}
}

POST /logs_write/_rollover
{
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
},
"settings": {
"index.number_of_shards": 2
}
}

测试执行

rollover api 支持dry_run模式,即在不执行rollover的情况下,对请求的数据进行检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PUT /logs-000001
{
"aliases": {
"logs_write": {}
}
}

POST /logs_write/_rollover?dry_run
{
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

写入索引别名

在滚动操作期间,当is_write_index已显式设置为true的写入索引时,不会交换滚动别名。由于别名指向多个索引无法区分应该滚动哪个索引,因此滚动指向多个索引的别名是无效的。因此,默认索引别名指向正在写入的索引。由于is_write_index的设置,使得可以用一个别名指向多个索引,同时也明确表明滚动所针对的索引,因此不需要从之前的滚动索引中删除别名。这使得可以允许使用一个别名同时作为滚动管理的索引的写别名和读别名来简化事情。

例:索引别名中的is_write_index此时被设置到了新滚动的索引之上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
PUT my_logs_index-000001
{
"aliases": {
"logs": { "is_write_index": true }
}
}

PUT logs/_doc/1
{
"message": "a dummy log"
}

POST logs/_refresh

POST /logs/_rollover
{
"conditions": {
"max_docs": "1"
}
}

PUT logs/_doc/2
{
"message": "a newer log"
}

等到索引rollover之后, 两个索引的别名将会有is_write_index的设置,并且分别反映了各自的角色,新创建的索引将会作为写入的索引,老的索引is_write_index将会变为false。

1
2
3
4
5
6
7
8
9
10
11
12
{
"my_logs_index-000002": {
"aliases": {
"logs": { "is_write_index": true }
}
},
"my_logs_index-000001": {
"aliases": {
"logs": { "is_write_index" : false }
}
}
}

示例

存储日志时我们可以使用时间来滚动索引来减少一些不必要的查询压力,可以自己设置按照一定的时间间隔、文档数量以及索引大小等内容来滚动索引,为了统一所有滚动索引的映射以及分词器等设置,我们可以在建立滚动索引之前先建立一个索引的模板,之后再对索引进行滚动。

索引模板如下,其中我们可以指定一个统一的别名来对所有的滚动索引进行统一的搜索,指定映射关系以及设置等,例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PUT _template/log_template
{
"index_patterns": ["log*"],
"mappings": {
"_doc":
{
"properties":{
"name":{
"type":"keyword"
}
}
}
},
"aliases":{"logs_search":{}}
}

之后再使用时间建立滚动索引,并且指定另一个别名始终指向正在写入的索引:

1
2
3
4
5
6
PUT /logs-2019.02.26-000001 
{
"aliases": {
"logs_write": {"is_write_index": true}
}
}

在插入一定的数据之后,定时滚动索引,之后会在一定的条件使索引进行滚动,并且其中一个写入的别名指向滚动后的索引,例,下面的条件表示触发下面任何一个条件都会使索引进行滚动:

1
2
3
4
5
6
7
8
POST /logs_write/_rollover 
{
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

我们想要对索引进行查询的时候,使用logs_write指向正在写入的索引,使用log_search指向所有的形如log*索引,当想要按照一定范围进行查询的时候,可以先计算出需要哪些索引,再按照一定的格式进行查询。如:

1
2
3
4
5
6
7
8
9
10
11
# 查询全部内容
GET logs_search/_doc/_search

# 查询最新日志内容
GET logs_write/_doc/_search

# 想要查2,3月的索引内容
GET logs-2019.02*,logs-2019.03*/_doc/_search

# 想要查2019年的索引内容
GET logs-2019*/_doc/_search

但所有类似的分割索引、分片的操作都有类似的问题,查询结果排序不是十分准确,这是es内部结构以及查询原理等决定的。

refernece

官方文档Rollover Index
官方文档Index Templates
And the big one said “Rollover”

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章