1. 索引别名是用于引用一个或多个现有索引的辅助名称。大多数ES API接受索引别名来代替索引。
  2. 别名是一组索引的辅助名称,一个别名可以指向多个索引,一个索引可以有多个别名。
  3. 使用别别名,在重建索引数据时,无需停机或更改程序代码。
  4. 别名类似Nginx反向代理的感觉,当访问别名时,相当于访问的实际索引的代理。

使用场景

滚动索引

  1. 存储大量日志数据的场景,或者 存储几亿订单数据的场景。由于ES索引的单个分片建议大小为30G左右,同时ES的分片数量也不要太大,建议1~5之间。所以,势必要建立多个索引去存储大量数据。比如 按日、按月、按季度、按年 存储等。
  2. 此时如果要从这些索引里去查询数据,在不使用Alias的情况下,肯定要在业务代码里写上一堆复杂的逻辑,然后是兼容各种场景和异常,即使感觉做的比较完善了,可能上线后还有未知的问题。
  3. 使用Alias后,业务代码无需改动,只需要给相关索引建立同样的别名,然后利用Alias查询,ES会自动将相关的索引数据都查出来。

无缝切换

  1. 正在使用的索引A存在部分异常数据,此时可以重新构建索引B,然后将Alias指向索引B,这样可以无缝切换索引,并且业务层无感知。

重建索引

  1. 在ES中无法对索引的现有字段做改动,一般的做法是创建新的索引,然后把文档从旧的索引复制到新的索引里。针对这种情况,别名的使用优势就体现出来了,索引别名可以实现旧索引到新索引的平滑迁移。

带过滤条件索引

  1. 针对某个索引,有些场景需要固化视图时,就可以设置别名来实现,这样调用方使用起来很方便,无需加入重复的查询条件。比如有个 订单索引,多处需要查询 30天内已支付订单,此时可以利用Alias构建出这样的视图。

使用别名

创建别名

  1. 创建索引时指定别名,order索引指定alias_1,alias_2别名。
1
2
3
4
5
6
7
PUT /order
{
    "aliases": {
        "alias_1": {},
        "alias_2": {}
    }
}
  1. 创建索引后指定别名。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
POST _aliases
{
  "actions": [
    {
      "add": {
        // order_202201 别名 order_alias
        "index": "order_202201",
        "alias": "order_alias"
      }
    },
    {
      "add": {
        // order_202202 别名 order_alias
        "index": "order_202202",
        "alias": "order_alias"
      }
    }
  ]
}
  1. 当索引别名指向多个索引时,进行写操作,其中的一个索引必须被指定为写索引,并且只能指定一个,否则则无法写入。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 
POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias1",
                 "is_write_index" : true
            }
        },
        {
            "add" : {
                 "index" : "test2",
                 "alias" : "alias1"
            }
        }
    ]
}

移除别名

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
POST _aliases
{
  "actions": [
    {
        // 移除
      "remove": {
        "index": "order_202201",
        "alias": "order_alias"
      }
    }
  ]
}

切换别名

  1. 把product索引别名重命名为product_new。(原子操作)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
POST _aliases
{
  "actions": [
    {
      "remove": {
        // 移除
        "index": "product",
        "alias": "product_old"
      }
    },
    {
      "add": {
        // 添加
        "index": "product",
        "alias": "product_new"
      }
    }
  ]
}
  1. 切换写索引属性,(原子操作)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 
POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias1",
                 "is_write_index" : false
            }
        }, {
            "add" : {
                 "index" : "test2",
                 "alias" : "alias1",
                 "is_write_index" : true
            }
        }
    ]
}

过滤视图

  1. 创建索引后添加别名并指定过滤条件。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
POST /_aliases
{
  "actions" : [
    {
      // order_202303索引创建order_alias别名
      // 当前使用order_alias别名查找数据时,默认带上指定的过滤条件
      "add" : {
         "index" : "order_202303",
         "alias" : "order_alias",
         "filter": {"term" : {"pay_state": 1}}
      }
    }
  ]
}

查询索引别名

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 查询logs_20162801索引的所有别名
GET /logs_20162801/_alias/*
// 查询别名为2016的所有索引
GET /_alias/2016
// 查询别名为20开头的所有索引
GET /_alias/20*
 
HEAD /_alias/2016
HEAD /_alias/20*
HEAD /logs_20162801/_alias/*
  1. 创建索引时指定别名并设置过滤条件。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
PUT /test
{
    "aliases": {
        "alias_1": {},
        "alias_2": {
            "filter": {
                "user.id": "kim"
            }
        }
    }
}

区别对比

不使用alias方案

  1. 该方案无法实现无缝切换,因为在删除旧的index-A之后,新的index-A还没创建,而且数据还没拷贝完毕。
  2. 基于这种方案要想无缝切换,那只能是先创建index-B,通过reindex将index-A的数据拷贝到index-B,然后业务代码改成访问index-B。
 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
26
27
28
29
// 1) 将index_A拷贝到备份index_A_bak
POST _reindex                    
{
  "source": {
    "index": "index_A"
  },
  "dest": {
    "index": "index_A_bak"
  }
}

// 2) 删除index_A
DELETE index_A

// 3) 创建新的 index_A,此处省去创建新的index_A的过程

// 4) 将备份index_A_bak拷贝到新的index_A
POST _reindex
{
  "source": {
    "index": "index_A_bak"
  },
  "dest": {
    "index": "新的index_A"
  }
}

// 5) 删除备份index_A_bak
DELETE index_A_bak

使用Alias的方案

  1. 该方案无需改动代码即可实现无缝切换。后续切换索引只需要操作3、4、5步即可。
 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 1) 给index_A添加别名
POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "index_A",
        "alias": "index_alias"
      }
    }
  ]
}

// 2) 业务层的代码改成使用别名操作索引

// 3) 将index_A数据拷贝到index_B
POST _reindex                    
{
  "source": {
    "index": "index_A"
  },
  "dest": {
    "index": "index_B"
  }
}

// 4) 别名切换
POST /_aliases
{
    "actions": [
    {
        "add": {
            "index": "index_A",
            "alias": "index_alias"
        },
        "remove": {
            "index": "index_B",
            "alias": "index_alias"
        }
    }
    ]
}

// 5) 删除索引index_A
DELETE index_A

参考

  1. https://mp.weixin.qq.com/s/U6YAN_yW809NvF1JDntBHw