目录
一、概述
在ES中,索引别名(index aliases)就像一个快捷方式或软连接,可以指向一个或多个索引。别名带给我们极大的灵活性,我们可以使用索引别名实现以下功能:
- (1)在一个运行中的ES集群中无缝的切换一个索引到另一个索引上(无需停机)
例如,在生产环境中,为了避免索引里面的数据和数据库中的数据不一致,运维每天都要重建一遍ES索引。又比如项目中使用的老的索引,需要重建索引,这样必然需要更新dao层查询中的索引名称,然后重新启动应用,可能会对服务的使用者产生一定的影响。
通常情况下,索引都是分片存储在多个节点上面,所以只有所有分片都重建完成后,才能说整个索引库重建完成。并且重建过程可能发生异常,此时我们还需要将之前已经重建过的那些索引都回滚掉。针对上述描述的问题,我们都可以用索引别名来解决,并且无需停止应用的运行。
解决方法:
旧索引称为a,新索引称为b,他们拥有共同的别名c,而dao层查询的索引名也是c,当新的全量索引b重建完成之后,只需要解除旧索引a与别名c关系,然后添加新索引b与别名c的关系,就能完成无缝切换,中间对用户是无感知的,非常友好。如果b有问题,那么随时都可以重新解除b的关系并恢复a,这就完成了所谓的回滚操作,非常简单优雅。
- (2)分组多个索引,比如按月创建的索引,我们可以通过别名构造出一个最近3个月的索引
order_idx_202203(索引名称) => order_idx_last_three_months(别名)
order_idx_202202(索引名称) => order_idx_last_three_months(别名)
order_idx_202201(索引名称) => order_idx_last_three_months(别名)
# 查询的时候,直接使用别名进行查询
GET /order_idx_last_three_month/_search
{.....}
- (3)查询一个索引里面的部分数据构成一个类似数据库的视图(views)
POST /_aliases
{
"actions" : [
{
"add" : {
"index" : "employee",
"alias" : "emp",
"filter" : { "term" : { "type" : "normal" } }
}
}
]
}
二、索引别名相关 API
- 创建索引别名:将别名emp与索引employee相关联
POST _aliases
{
"actions": [
{
"add": {
"index": "employee",
"alias": "emp"
}
}
]
}
- 删除索引别名:解除别名emp与索引employee的关联
POST _aliases
{
"actions": [
{
"remove": {
"index": "employee",
"alias": "emp"
}
}
]
}
- 重命名别名
重命名一个别名是在同一个 API 中执行添加、删除操作。 这个操作是原子的,不用担心别名不指向索引的短时间。
POST _aliases
{
"actions": [
{
"add": {
"index": "employee",
"alias": "emp"
}
},
{
"remove": {
"index": "employee2",
"alias": "emp"
}
}
]
}
上面的操作是顺序的执行的,先解除employee的别名,然后给employee2添加新的别名,这样一来索引就透明的被切换了,用户不会感觉任何变化,而且也不需要停机操作。
- 别名与多个索引关联(索引分组)
将一个别名与多个索引关联起来只需要同时执行几个添加操作。
POST _aliases
{
"actions": [
{
"add": {
"index": "employee",
"alias": "emp"
}
},
{
"add": {
"index": "employee2",
"alias": "emp"
}
}
]
}
还有一种方式:
POST /_aliases
{
"actions": [
{
"add": {
"indices": [
"employee",
"employee2"
],
"alias": "emp"
}
}
]
}
- 获取集群的别名列表
GET _alias
查询结果如下:
{
"employee2" : {
"aliases" : {
"emp" : { }
}
},
"employee" : {
"aliases" : {
"emp" : { }
}
}
}
- 获取集群中某个索引的别名列表
GET employee/_alias
查询结果如下:
{
"employee" : {
"aliases" : {
"alias1" : { },
"emp" : { }
}
}
}
- 使用别名进行搜索
# 插入文档
PUT user1/_doc/1
{
"name" : "张三",
"age": 20
}
PUT user1/_doc/2
{
"name" : "李四",
"age": 30
}
PUT user2/_doc/1
{
"name" : "王五",
"age": 20
}
PUT user2/_doc/2
{
"name" : "赵六",
"age": 40
}
# 为索引user1/user2指定别名为user
POST /_aliases
{
"actions": [
{
"add": {
"indices": ["user1","user2"],
"alias": "user"
}
}
]
}
# 查询年龄大于等于25的用户
GET /user/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"age": {
"gte": 25
}
}
}
]
}
}
}
# 查询结果
"hits" : [
{
"_index" : "user1",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"name" : "李四",
"age" : 30
}
},
{
"_index" : "user2",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.0,
"_source" : {
"name" : "赵六",
"age" : 40
}
}
]
可以看到, 当我们通过别名user进行搜索的时候,ES会帮我们从别名为user对应的两个索引库:user1、user2中查询满足条件的记录,然后聚合返回给我们。
参考资料: