Elastic Stack应用宝典
上QQ阅读APP看书,第一时间看更新

3.1 索引别名与配置

在Elasticsearch中,可以使用四HTTP方法请求索引,即PUT、GET、DELETE和HEAD。其中,PUT请求用于创建索引;GET请求用于查看索引;DELETE请求则用于删除索引;HEAD请求有点特殊,用于索引存在性检验,如果索引存在则返回200状态码,否则返回404状态码。所以示例3-1中的请求方式都是正确的:

示例3-1 索引操作

在示例3-1中的所有请求都只是简单地请求了一个索引名称,索引名称不可以随意命名,在创建索引时有一些重要的命名限制需要引起注意,具体如下:

● 索引名称只能使用小写字母;

● 索引名称不能包括:\,/,*,?,",<,>,|,''(空格),,(逗号),#;

● 在7.0版之后不可以包含冒号;

● 索引名称不能以下列符号开头:-,_,+;

● 索引名称不能使用“.”或“..”;

● 索引名称长度必须小于255 B。

在实际使用中,一般不会像示例3-1那样只使用PUT请求创建索引而不对索引做任何配置。因为在向一个索引添加文档时,如果索引不存在Elasticsearch会自动将这个索引创建出来。所以如果接受索引的默认参数,完全可以等到添加文档时由Elasticsearch自动创建。任何一个索引都包括别名、映射和配置三个参数,它们可在创建索引时使用aliases、mappings和setting设置。映射(mappings)已经在第2章做了详细介绍,本节主要介绍索引的别名和配置。

3.1.1 索引别名

索引别名可以类比为传统关系型数据库中的视图,Elasticsearch在处理别名时会自动将别名转换为对应的索引名称。所以如果别名与索引完全相同,它就没有存在的意义。因此与视图类似,索引别名一般都会与一些过滤条件相关联。过滤条件可以使用本书第5章中介绍的文档查询语句,比如term、match等。例如,创建students索引存储学生信息,并根据性别添加男生和女生别名:

示例3-2 students索引与别名

如示例3-2所示,students索引一共关联了girls和boys两个别名。在别名的定义中,filter用于定义过滤器,routing用于定义路由规则,它们将在使用别名检索时自动应用。在定义过滤条件时通常要指定路由规则,这样会将同一别名的文档路由到相同的分片上,可以有效减少使用别名检索时的分片操作。但这也要求在存储文档时必须要通过别名,否则在使用别名检索时有可能会漏掉合法文档。例如使用students添加文档而使用girls、boys检索文档,就有可能会出现检索不到文档的情况发生,读者可以自己试一下。

别名并不一定只与一个索引关联,它可以与多个索引关联,这种设计在一些应用场景中十分有价值。比如在第2.4.3节讲解索引容量规则时曾经提到,如果文档数量整体容量不可估算并且每天都在增加,可以按时间段每隔一段时间就创建一个新索引。这虽然解决了索引容量问题,但带来的问题就是在检索时需要指定多个索引。有了索引别名就可以给这些同属一个领域的索引关联相同的别名,这样在检索文档时就可以对它们共同的别名做检索,避免了不停变换索引名称带来的麻烦。

索引别名不仅可以在创建索引时指定,也可以在索引创建后再动态添加或删除。下面就来看看这些有关别名的接口。

1._alias和_aliases接口

在索引创建后,_alias和_aliases接口都可以用于添加或删除别名,不同的是前者一般针对某一具体的索引,而后者可以对多个索引做批量操作。例如,为索引students添加一个代表一年级的别名grade1:

示例3-3 使用_alias接口

在示例3-3中,PUT请求的资源为“/students/_alias/grade1”,资源中使用_alias表明这是一个对别名资源操作的请求,并且确定了索引为students而别名为grade1。资源中的索引名可以使用_all来代表所有索引,也可以使用类似“log_*”这样的形式匹配多个索引。一般情况下,使用PUT或POST方法请求上述资源时是添加别名,别名的过滤条件、路由等配置信息则在请求体中以filter、routing参数定义;使用DELETE方法则是删除别名,不需要使用请求体;使用GET方法请求“/students/_alias”,可以查看students索引的所有别名。Elasticsearch的CAT接口提供“_cat/aliases”接口,以GET方法访问接口会以纯文本形式返回所有别名。

下面再来看一看_aliases接口如何实现相同的需求,如示例3-4所示:

示例3-4 使用_aliases接口

_aliases接口请求的资源中也可以添加索引名称,例如“/students/_aliases”代表只针对students索引做操作。_aliases接口的请求体接收数组类型的actions参数,它可以指定的行为包括add、remove、remove_index等,分别对应添加别名、删除别名和删除索引等行为。示例3-4只给出了单个索引对应单个别名的情况,实际上还可以通过indices和aliases指定多个索引和多个别名。所以_aliases接口可以针对多个索引、多个别名,实现添加、删除等多种操作。

2._rollover接口

_rollover接口用于根据一系列条件将别名指向一个新的索引,这些条件包括存续时间、文档数量和存储容量等。这与日志文件使用的文件滚动类似,文件滚动是通过不断创建新文件并滚动旧文件来保证日志文件不会过于庞大,而_rollover接口则是通过不断将别名指向新的索引以保证索引容量不会过大。这其实是本书第2.4.3节介绍容量规划时提到的无限容量存储的一种解决方案,但这种别名滚动并不会自动完成,需要主动调用_rollover接口。

别名滚动的条件可通过conditions参数设置,包括max_age、max_docs和max_size等三个子参数。例如,创建一个索引logs-1并分配别名logs,然后调用logs别名的_rollover接口设置别名滚动条件,如示例3-5所示:

示例3-5 使用_rollover接口

在示例3-5中,logs别名指向logs-1索引,最大存活周期为14天,最大文档数量10000条,最大存储容量4GB。因为logs-1索引刚刚创建,存活时间、文档数量和存储容量都不满足条件,所以使用示例3-5的请求不会对logs别名产生任何影响。这通过请求返回的结果也可以看到:

示例3-6 _rollover接口返回结果

从返回结果的conditions属性来看,三个条件匹配的结果都是false,所以不会触发索引滚动。如果想体验别名滚动的效果,可以将max_age设置为1 s再调用上面的请求。之后通过“GET _cat/indices”接口就会发现有新的索引logs-000002产生,再分别查看这两个索引就会发现,logs-1的别名已经被清空,而logs-000002的别名中则已经添加了logs。新索引的命名规则在原索引名称数字的基础上加1,并且将数值长度补0凑足6位。所以使用_rollover接口时,要求索引名称必须以数字结尾,数字与前缀之间使用连接线“-”连接,即满足正则表达式“^.*- \\ d+$”。如果索引名称没有遵从这样的规则,则需要在调用_rollover接口时指定新索引名称,例如:

示例3-7 _rollover接口指定新索引名称

由于_rollover接口在滚动新索引时,会将别名与原索引的关联取消,所以通过别名再想查找已经编入索引的文档就不可能了。为了保证原文档可检索,可以通过别名is_write_index参数保留索引与别名的关系。当使用is_write_index参数设置了哪一个索引为写索引时,_rollover接口滚动别名指向索引时将不会取消别名与原索引之间的关系。它会将原索引的is_write_index参数设置为false,并将新索引的is_write_index参数设置为true。例如在创建logs-1时添加参数如示例3-8所示:

示例3-8 使用is_write_index

再执行示例3-5中的请求时,会发现logs-1的is_write_index参数被设置为false,而新生成索引logs-000002的is_write_index参数则为true。在两者的别名列表中都包含有logs,可以继续通过logs别名对原索引进行查询。

3.1.2 索引配置

索引的settings参数用于添加索引配置,索引的所有配置项都以“index”开头,在设置这些配置项时也可以通过JSON对象的形式来编写。例如,在示例3-9中两种创建索引的方式都是正确的:

示例3-9 索引配置

索引配置包括静态配置和动态配置两种,静态配置只能在索引创建时或索引关闭时设置,而动态配置没有这个限制。

1.索引关闭与打开

索引可以被关闭,关闭后的索引除了维护自身元数据信息以外,基本上不会再占用集群资源,同时也不能再被用户读写。索引关闭后可以再次打开,所以通过关闭索引可以实现索引存档的目的。Elasticsearch提供了索引关闭与打开的REST接口,例如:

示例3-10 索引关闭与打开

在示例3-10中,test为任意索引名称。索引名称可以使用_all或*号将所有索引关闭或打开,但如果配置文件中设置了action.destructive_requires_name为true,则在这里就不能使用_all或*号;如果配置文件中设置cluster.indices.close.enable为false,则索引将不能被关闭。

2.索引静态配置

索引静态配置主要有索引主分片、压缩编码、路由等相关信息的参数,它们只能在创建索引时设置,一旦索引创建完成就不能再修改静态配置。具体静态配置参数参见表3-1,其中配置参数名都以index开头。

表3-1 索引静态配置

其中,number_of_shards和routing_partition_size参数就是本书第2章2.4.2节中介绍分片路由运算时使用的主分片数量和分区参数。

3.索引动态配置

Elasticsearch为查询和修改索引配置提供_settings接口,以GET方法请求_settings接口时可获取索引配置信息,而以PUT方法访问时则可以修改配置。调用该接口时可以在路径中添加一个或多个索引名称,这时请求将只针对某一或某些索引,否则请求将针对所有索引。示例3-11展示了使用_setting接口查询和修改test索引的配置项:

示例3-11 _settings接口

在查询配置时还可以在地址中添加flat_settings参数,这可以使返回结果的JSON对象被平铺展示,以使结果更加紧凑。flat_settings参数默认值是false,一般在使用程序读取结果时可将它设置为true。同时这个参数是一个通用参数,在其他查看配置的接口中使用也有效,比如GET _cluster/settings?flat_settings。

修改索引配置项只能针对动态配置项,静态配置项一旦设置好了就不能再修改。对于某些动态配置项,还需要先将索引关闭才能更新。动态配置可以通过更新索引配置接口随时更改,具体的索引动态配置项见表3-2。

表3-2 索引动态配置项

在这些参数中,number_of_replicas和auto_expand_replicas用于设置副本分片数量,这在本书第2章2.4.4节中已有介绍。search.idle.after和refresh_interval则会影响到索引的刷新频率,在本书第2章2.1.3节在讲索引时曾经有过简单的介绍,但实际上这两个参数并不针对索引而是针对索引中具体的某一个分片。如果一个索引分片没有接收到数据查询的请求,那么它会一直等到search.idle.after参数设置的时间后才有可能去刷新索引。当然如果在这段时间有新的数据检索请求,索引就会与其他索引一起做刷新。search.idle.after参数是在Elasearch 7之后才加入的新参数,目的是为了提升索引刷新的性能。由于这种处理机制只有在refresh_interval参数没有设置明确值时才会起作用,所以如果不想使用这种机制,可以明确地将refresh_interval参数设置为1s。其余参数大多与具体的查询语言相关,它们将在讲解到查询语言时再做介绍。