索引别名

  1. 索引别名可以通过API的方式进行操作
  2. 一个索引别名可以映射到一个或一个以上的索引
  3. 索引名和索引别名不能重复,在集群中都是唯一的
  4. 别名可以与过滤器结合使用
  5. 一个索引可以拥有多个别名
  6. 只映射到一个索引的索引别名默认可以写入。目前有特性,当别名关联到多个索引的时候,可以通过配置别名的写入索引,来通过别名写入,否则无法通过别名进行写入操作,但是非日志类的索引不建议使用。

Elasticsearch 有一些操作索引别名的APIs,可以为索引设计索引别名。索引别名API允许用一个名字来别名一个索引,所有的API都会自动将别名转换为实际的索引名称。一个别名支持被映射到一个以上的索引,当指定它时,别名将自动展开到被别名的索引。一个别名也可以与一个过滤器相关联,该过滤器将在搜索时自动应用,并路由值。一个别名不能与一个索引有相同的名称。

下面是一个将别名alias1与索引test1关联的例子:

PUT gudong20230629001

POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "gudong20230629001", "alias" : "gudong" } }
    ]
}

GET gudong20230629001

{
    "gudong20230629001": {
        "aliases": {
            "gudong": {}
        },
        "mappings": {},
        "settings": {
            "index": {
                "creation_date": "1688021916053",
                "number_of_shards": "5",
                "number_of_replicas": "1",
                "uuid": "o_Q5UdbPRWy4w_E9QJS9PA",
                "version": {
                    "created": "6070299"
                },
                "provided_name": "gudong20230629001"
            }
        }
    }
}

删除同样的索引别名

POST /_aliases
{
    "actions" : [
        { "remove" : { "index" : "gudong20230629001", "alias" : "gudong" } }
    ]
}

GET gudong20230629001

{
    "gudong20230629001": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "creation_date": "1688021916053",
                "number_of_shards": "5",
                "number_of_replicas": "1",
                "uuid": "o_Q5UdbPRWy4w_E9QJS9PA",
                "version": {
                    "created": "6070299"
                },
                "provided_name": "gudong20230629001"
            }
        }
    }
}

重命名一个别名是一个简单的remove然后add操作,在同一个API中。这个操作是原子的,不需要担心短时间内别名不指向索引的问题:

在一次api请求的actions是什么样的原子原子性,gudong20230629002索引实际上不存在,请求直接异常退出。

POST /_aliases
{
    "actions" : [
        { "remove" : { "index" : "gudong20230629001", "alias" : "gudong" } },
        { "add" : { "index" : "gudong20230629001", "alias" : "gudong" } }
    ]
}

下例子,请求成功结束,虽然gudong20230629001上并没有别名gudong,但是有remove操作没有影响add操作。

POST /_aliases
{
    "actions" : [
        { "remove" : { "index" : "gudong20230629001", "alias" : "gudong" } },
        { "add" : { "index" : "gudong20230629001", "alias" : "gudong" } }
    ]
}

在一个API中一次为一个索引别名关联多个索引的写法有:

  1. 将一个别名与一个以上的索引相关联,只需要几个 add动作:
POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "gudong20230629001", "alias" : "gudong" } },
        { "add" : { "index" : "gudong20230629002", "alias" : "gudong" } }
    ]
}
  1. 可以用indices数组语法为一个动作指定多个索引:
POST /_aliases
{
    "actions" : [
        { "add" : { "indices" : ["gudong20230629001", "gudong20230629002"], "alias" : "gudong" } }
    ]
}
  1. glob模式(通配符模式)也可以用来将一个别名与多个具有共同名称的索引联系起

    在计算机编程中,特别是在类似Unix的环境中,术语globbing有时被用来指基于通配符的模式匹配。名词 "glob "用来指代一个特定的模式,例如 “使用glob *.log来匹配所有这些日志文件”。它的符号比正则表达式更简单。

POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "gudong20230629*", "alias" : "gudong" } }
    ]
}

glob模式别名是对某一时刻,集群上满足条件的索引映射生效,不会随着匹配该模式的新索引的添加/删除而自动更新。

也可以在一次操作中把一个索引和一个别名互换:

索引名称和别名名称 不是不能重名吗?这方式可以跳过验证?这里的actions里面的add和remove_index是原子的。如果只add,则会报错。

PUT gudong20230629001     
PUT gudong20230629002   
POST /_aliases
{
    "actions" : [
        { "add":  { "index": "gudong20230629002", "alias": "gudong20230629001" } },
        { "remove_index": { "index": "gudong20230629001" } }  
    ]
}

要在一个动作中指定多个别名,也存在相应的aliases数组语法。

带有过滤器的别名

带有过滤器的别名提供了一种简单的方法来创建同一索引的不同 “视图”。过滤器可以使用Query DSL来定义,并应用于所有的搜索、计数、通过查询删除和更多类似的操作,都有这个别名。

要创建一个过滤的别名,首先我们需要确保这些字段已经存在于mappings中:

PUT /test1
{
  "mappings": {
    "_doc": {
      "properties": {
        "user" : {
          "type": "keyword"
        }
      }
    }
  }
}

现在我们可以创建一个别名,在字段user上使用一个过滤器:

POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test1",
                 "alias" : "alias2",
                 "filter" : { "term" : { "user" : "donny" } }
            }
        }
    ]
}
Routing

可以将路由值与别名相关联。这个功能可以和过滤别名一起使用,以避免不必要的分片操作。

下面的命令创建了一个新的别名alias1,指向索引test。在alias1被创建后,所有使用这个别名的操作都会被自动修改为使用1值进行路由:

POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias1",
                 "routing" : "1"
            }
        }
    ]
}

也可以为搜索和索引操作指定不同的路由值:

POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias2",
                 "search_routing" : "1,2",
                 "index_routing" : "2"
            }
        }
    ]
}

如上例所示,搜索路由可以包含几个用逗号分隔的值。索引路由只能包含一个单一的值。

如果一个使用路由别名的搜索操作也有一个路由参数,那么将使用搜索别名路由和参数中指定的路由的交集。例如,下面的命令将使用 "2 "作为路由值:

GET /alias2/_search?q=user:kimchy&routing=2,3
Write Index

我们可以将别名所指向的索引作为写索引。当被指定时,所有针对指向多个索引的别名的索引和更新请求将试图解析到作为写索引的那个索引。每个别名在同一时间只能有一个索引被指定为写入索引。如果没有指定写索引,并且有多个索引被别名引用,那么将不允许写。

可以使用别名API和索引创建API来指定一个与别名相关的索引作为写索引。

设置一个索引作为别名的写入索引也会影响到在Rollover过程中对该别名的操作。

POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias1",
                 "is_write_index" : true
            }
        },
        {
            "add" : {
                 "index" : "test2",
                 "alias" : "alias1"
            }
        }
    ]
}

在这个例子中,我们将别名alias1testtest2相关联,其中test将是被选择写入的索引。

PUT /alias1/_doc/1
{
    "content": "Test Content"
}

被索引到/alias1/_doc/1的新文件将被当作/test/_doc/1来索引。

GET /test/_doc/1

要交换哪个索引是一个别名的写入索引,可以利用Aliases API来做一个原子交换。这种交换不依赖于动作的顺序。

POST /_aliases
{
    "actions" : [
        {
            "add" : {
                 "index" : "test",
                 "alias" : "alias1",
                 "is_write_index" : false
            }
        }, {
            "add" : {
                 "index" : "test2",
                 "alias" : "alias1",
                 "is_write_index" : true
            }
        }
    ]
}

如果别名没有为一个索引明确设置is_write_index: true,并且只引用了一个索引,那么这个被引用的索引就会表现得好像它是写入索引,直到引用了另外一个索引。在这一点上,将没有写入索引,写入将被拒绝。

REST单一添加一个别名

也可以用REST端点添加一个别名

PUT /{index}/_alias/{name}
参数解释
index别名所指的索引. 可以是以下任一一个 `*
name别名的名称。必填项。
routing可选项,路由值
filter可选项,过滤器

你也可以使用复数的_aliases

示例:
  • 增加一个基础别名

    PUT /logs_201305/_alias/2013

  • 增加一个带过滤器的别名

    首先创建索引并为user_id字段添加一个映射:

    PUT /users
    {
        "mappings" : {
            "_doc" : {
                "properties" : {
                    "user_id" : {"type" : "integer"}
                }
            }
        }
    }
    

    然后为一个特定的用户添加别名:

    PUT /users/_alias/user_12
    {
        "routing" : "12",
        "filter" : {
            "term" : {
                "user_id" : 12
            }
        }
    }
    

索引创建是增加别名

别名也可以在索引创建期间指定:

PUT /logs_20162801
{
    "mappings" : {
        "_doc" : {
            "properties" : {
                "year" : {"type" : "integer"}
            }
        }
    },
    "aliases" : {
        "current_day" : {},
        "2016" : {
            "filter" : {
                "term" : {"year" : 2016 }
            }
        }
    }
}

删除别名

删除别名的REST endpoint 是: /{index}/_alias/{name}

路径参数备注
index别名所指的索引。`*
name别名的名称。`*

或者你可以使用复数的_aliases。例子:

DELETE /logs_20162801/_alias/current_day

检索现有别名

获取索引别名API允许通过别名名称和索引名称进行过滤。这个api重定向到主节点并获取所请求的索引别名,如果有的话。这个api只对找到的索引别名进行序列化。

参数名说明
index要获取别名的索引名称。通过通配符支持部分名称,也可以指定多个索引名称,用逗号分隔。也可以使用一个索引的别名。
alias响应中要返回的别名的名称。和index选项一样,这个选项支持通配符和指定多个用逗号隔开的别名的选项。
ignore_unavailable如果指定的索引名称不存在,该怎么做。如果设置为true,那么这些索引将被忽略。

REST的端点地址: /{index}/_alias/{alias}.

示例:

查询索引logs_20162801下的所有别名:

GET /logs_20162801/_alias/*

Response:

{
 "logs_20162801" : {
   "aliases" : {
     "2016" : {
       "filter" : {
         "term" : {
           "year" : 2016
         }
       }
     }
   }
 }
}

在任何索引中具有2016年名称的所有别名:

GET /_alias/2016

Response:

{
  "logs_20162801" : {
    "aliases" : {
      "2016" : {
        "filter" : {
          "term" : {
            "year" : 2016
          }
        }
      }
    }
  }
}

任何索引中以20开头的所有别名:

GET /_alias/20*

Response:

{
  "logs_20162801" : {
    "aliases" : {
      "2016" : {
        "filter" : {
          "term" : {
            "year" : 2016
          }
        }
      }
    }
  }
}
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐