# 配置
# index template
:索引模板。用于在创建索引时进行初始化配置。
创建索引时,会根据索引模式匹配索引模板。如果存在多个匹配的索引模板,则采用优先级最高的那个。
- 创建索引时,如果加上了配置信息,则会覆盖索引模板中的对应配置。
- 创建、修改索引模板时,只会影响之后新创建的索引,不会影响已创建的索引。
相关 API :
GET /_template # 查询所有的索引模板 GET /_template/<template> # 查询指定的索引模板 PUT /_template/<template> <request_body> # 创建索引模板 DELETE /_template/<template> # 删除索引模板
例:创建一个索引模板
PUT /_template/my_template_1 { "index_patterns": ["mysql-log-*", "nginx-log-*"], # 索引模式,用于匹配一些索引 "aliases": { "test-alias-1": {} }, "settings": {...}, "mappings": {...}, # "version" : 1, # 声明该索引模板的版本 # "_meta": { # 配置该索引模板的元数据,可以加入任意名称的参数,并不会被 ES 使用 # "description": "This is a log template." # } }
- 至少要声明 index_patterns ,其它配置则可以省略。
ES v7.8 版本引入了可组合模板,API 为 _index_template 。
- 可设置
"priority": 100
参数,表示该模板的优先级。- 默认为 0 ,即优先级最低。
- 如果一个索引匹配多个索引模板,则采用优先级最高的那个。
- 可设置
# index pattern
:索引模式。一个用于匹配任意个索引名的字符串。
- 可以是以下格式:
my-index-1 # 一个索引名 my-index-1,my-index-2 # 多个索引名,用逗号分隔 my-index-* # 可以使用通配符 * 匹配多个索引名 my-index-*,-my-index-2 # 可以在索引名之前加上 - ,从而排除它
# alias
- 每个索引可以创建一个或多个别名(alias)。
- ES 的大多数 API 都支持输入索引的别名,会自动解析到原名。
- 别名与索引名共享一个命名空间,不允许重名。
- 相关 API :
GET /_alias # 查询所有索引的所有别名 GET /_alias/<alias> # 加上一个 alias 名称进行筛选,支持使用通配符 * GET /<index>/_alias # 查询指定索引的所有别名 GET /<index>/_alias/<alias> HEAD /_alias/<alias> # 检查索引是否存在 HEAD /<index>/_alias/<alias> PUT /<index>/_alias/<alias> # 给索引创建别名 DELETE /<index>/_alias/<alias> # 删除索引的别名
# mappings
:映射,用于定义某个 index 中存储的文档的数据结构、字段类型。
- 定义方式分为两种:
- explicit mapping
- :显式映射。是在 properties 区块,根据字段名定义一些字段。
- index 在创建之后,不能修改显示映射中已有的字段,只能增加字段。也可以创建一个拥有新 mappings 的新 index ,然后将旧 index 的文档通过 reindex 拷贝过去。
- dynamic mapping
- :动态映射。是在 dynamic_templates 区块,根据至少一个匹配条件,为还没有显式映射的字段添加显式映射。
- explicit mapping
- 例:
"mappings": { "_source": { "enabled": true # 是否保存 _source 字段 }, "dynamic_templates" : [ # 动态映射 { "integer_fields": { # "match" : "*", # 匹配字段名 # "path_match" : "test", # 匹配字段的 JSON 路径 "match_mapping_type": "long", # 匹配字段值的 JSON 数据类型 "mapping": { # 为匹配的字段生成显式映射 "type": "integer" # 该效果为:如果新增的文档中,任意字段满足匹配条件,则存储为 integer 数据类型 } } }, { "string_fields" : { "match_mapping_type" : "string", "mapping" : { "type" : "text" } } } ], "properties": { # 显式映射 "@timestamp" : { "type" : "date" }, "level" : { "type" : "text" }, "message": { "type": "text" # "index": true, # 是否允许搜索该字段,默认为 true # "fielddata": false, # 是否允许 aggregations、sorting、scripting 操作 # "norms": true, # 是否启用 norms } } }
- text 类型的字段默认禁用了 fielddata ,因为会占用大量内存。与其启用 fielddata ,不如给 text 类型的字段增加一个 keyword 类型的子字段:
"message" : { "type" : "text", "fields" : { # 定义子字段 "keyword" : { # 一个名为 keyword 的子字段 "type" : "keyword", "ignore_above" : 256 # 限制字段取值的长度,默认为无限大。如果超过,则保存该字段时不会建立索引 } } }
- norms :给每个字段额外使用一个字节,存储多种有利于计算 score 的调节因子(normalization factors)。
- text 字段默认启用 norms ,keyword 字段默认关闭 norms 。
- text 类型的字段默认禁用了 fielddata ,因为会占用大量内存。与其启用 fielddata ,不如给 text 类型的字段增加一个 keyword 类型的子字段:
# 数据类型
文档中,字段名为字符串类型(区分大小写),而字段值的常见类型如下:
- 字符串 :分为两种:
- text
- 适合存储非结构化数据,比如一篇文章。
- 适合全文搜索。
- keyword
- 适合存储结构化数据,比如文章标题、编号。
- 适合精确搜索、排序、聚合查询。
- text
- 数字 :分为 integer、byte、float 等。
- 布尔值 :boolean
- 日期 :date
- 数组 :array ,其中的所有元素必须采用相同的数据类型。
- 对象 :即 JSON Object
- nested
- :用于嵌套一组文档。这会在当前文档之外,创建独立的 Lucene 文档。
- join
- :用于声明父子文档。
- 父文档与子文档必须位于同一索引、同一 shard 。
- 例:
PUT test_index { "mappings": { "properties": { "test_join": { "type": "join", "relations": { "question": "answer" # 定义一个 join 字段,声明 question 对 answer 的父子关系 } } } } }
PUT test_index/_doc/1 { "text": "This is a question", "test_join": { "name": "question" # 新增一个文档,join 名称为 question ,因此为父文档 } }
PUT test_index/_doc/2?routing=1 # 设置 routing 参数,将 HTTP 请求路由到 _id=1 的文档所在 shard { "text": "This is an answer", "test_join": { "name": "answer", # 新增一个文档,join 名称为 answer ,因此为子文档 "parent": "1" # 父文档是 _id=1 的文档 } }
# 文本分析
文本分析(Text analysis):ES 存储 text 类型的字段时,会先经过 analyzer 处理,再建立索引。从而方便全文搜索。
- 查询时,也先将查询字符串经过 analyzer 处理,再进行查询。
- text 字段存储之后的字符内容、顺序可能变化,因此使用 term、regexp 查询时可能不匹配,应该用 match 查询。
一个分析器(analyzer)包含多个组件:
- character filter :字符过滤器,用于添加、删除、转换某些字符。
- tokenizer :分词器,用于将字符串拆分成一个个单词,称为 token 。
- 比如英语 "Hello World" 会拆分成 2 个单词,汉语 "你好啊" 会拆分成 3 个单词。
- token filter :用于添加、删除、转换某些 token 。
- 例如 the、on、to 等单词通常不影响查询,可以删除。
ES 内置了多种 analyzer :
- standard :默认采用。根据大部分标点符号进行分词。
- 还启用了 Lower Case Token Filter ,将 token 全部小写。
- simple :根据非字母的的字符进行分词,还启用了 Lower Case Token Filter 。
- whitespace :根据空白字符进行分词。
- stop :与 simple 相似,但启用了 Stop token filter ,会删除 a、an、and、are、it、no、the 等冠词、介词、连词。
- standard :默认采用。根据大部分标点符号进行分词。
index 的 analyzer 配置示例:
{ "settings": { "analysis": { "analyzer": { "default": { // 设置存储时的默认 analyzer "type": "standard" }, "default_search": { // 设置查询时的默认 analyzer "type": "standard" } } } }, "mappings": { "properties": { "message": { "type": "text", "analyzer": "standard" // 设置指定字段的 analyzer } } } }
可用 API
/_analyze
测试分析一个字符串:POST /_analyze { "analyzer": "standard", "text": "Hello World! -_1" }
结果如下:
{ "tokens": [ { "token": "hello", "start_offset": 0, "end_offset": 5, "type": "<ALPHANUM>", "position": 0 }, { "token": "world", "start_offset": 6, "end_offset": 11, "type": "<ALPHANUM>", "position": 1 }, { "token": "_1", "start_offset": 14, "end_offset": 16, "type": "<NUM>", "position": 2 } ] }
# settings
:用于控制索引的存储等操作。
- settings 中的配置参数按修改类型分为两种:
- dynamic :支持在运行的索引上配置。
- static :只能在创建索引时配置,有的也支持在 closed 索引上配置。
index.number_of_replicas
属于动态配置,index.number_of_shards
属于静态配置。因此索引在创建之后,不能修改主分片数量。
- 例:
"settings": { "index": { # "codec": "best_compression", # 索引段的压缩率,默认为 LZ4 。更高的压缩率会减少占用的磁盘空间,但是增加读写文档的耗时 "number_of_shards": 3, # 主分片的数量,默认为 1 。该参数属于 static settings 。 "number_of_replicas": 2, # 每个主分片的副本数量,默认为 1 "refresh_interval" : "5s", # 每隔一定时间自动刷新一次索引。默认为 1 s ,接近实时搜索。设置成 -1 则不自动刷新 "max_result_window": 10000, # 单个请求返回文档的最大数量 "mapping": { "total_fields.limit": 1000, # 限制索引包含的字段数 "depth.limit": 50, # 限制字段的深度 "field_name_length.limit": 1000, # 限制字段名的长度,默认不限制 } "blocks": { # 用于禁止对索引的一些操作 "read": true, # 禁止读文档 "write": true, # 禁止写文档 "metadata": true, # 禁止读写元数据 "read_only": true, # 禁止写文档、元数据,也不能删除索引 "read_only_allow_delete": true, # 在 read_only 的基础上,允许删除索引(但依然不允许删除文档,因为这样并不会释放磁盘空间) } } }
# component template
:组件模板。可以被索引模板继承,从而实现更抽象化的模板。
- 例:创建一个组件模板
PUT /_component_template/my_component_template { "template": { "mappings": { "properties": { "@timestamp": { "type": "date" } } } } }
# shard
- ES 的分片(shard)根据用途分为两种:
- 主分片(primary shard)
- :用于存储某个索引的数据。
- 支持读、写请求。
- 每个索引可以划分 1 个或多个主分片。
- 副分片(replica shard)
- :用作某个主分片的副本。
- 只支持读请求,不支持写请求。
- 每个主分片可以有 0 个或多个副分片。
- 主分片(primary shard)
# 分配
ES 集群中,master 节点会决定将每个 shard 分配到哪个节点进行存储。
- 副分片必须分配到主分片以外的节点,否则不能实现灾备。
- 如果没有其它可用节点,副分片就会一直处于未分配状态,导致该索引的状态为 yellow 。
- 副分片必须分配到主分片以外的节点,否则不能实现灾备。
默认启用了自动分配。配置如下:
PUT /_cluster/settings { "transient": { "cluster.routing.allocation.enable": "all" } }
- enable 可以取值为:
- all :自动分配所有分片。
- primaries :只分配主分片。
- new_primaries :只分配新索引的主分片。
- none :禁用自动分配。
- 改变索引、分片、节点数量时,都可能触发 shard 的自动分配。
- enable 可以取值为:
默认启用了基于磁盘的分配规则。配置如下:
"cluster.routing.allocation.disk.threshold_enabled": true # 是否启用基于磁盘阈值的分配规则 "cluster.routing.allocation.disk.watermark.low": "85%" # 低阈值。超出时,不会将新的副分片分配到该节点 "cluster.routing.allocation.disk.watermark.high": "90%" # 高阈值。超出时,会尝试将该节点上的分片迁移到其它节点 "cluster.routing.allocation.disk.watermark.flood_stage": "95%" # 洪水位(危险阈值)。超出时,会找出该节点上存储的所有分片,将它们所属的 index 开启 read_only_allow_delete "cluster.info.update.interval": "30s" # 每隔多久检查一次各节点的磁盘使用率
- 这里可以设置磁盘使用率的一组阈值。超出阈值时会自动开启限制,低于阈值时会自动解除限制。
- 阈值可以设置为磁盘的剩余大小,比如 "100gb" 。
可以添加基于过滤器的分配规则。配置如下:
"cluster.routing.allocation.exclude._name": "node1,node2" # 禁止分配分片到指定节点上,已有的分片也会被迁移走。可以指定 _ip、_name 等
默认会自动均衡各个节点上存储的分片数量。配置如下:
"cluster.routing.rebalance.enable": "all" # 对哪些类型的分片进行均衡。all 表示主分片+副分片 "cluster.routing.allocation.allow_rebalance": "indices_all_active" # 什么时候开始均衡。默认为主发片+副分片都已经被分配时
- rebelance 均衡会遵守其它分配规则,因此不一定完全均衡。
- 建议将一个索引的不同主分片分配到不同节点,从而分散 IO ,也有利于并发查询。
可以手动迁移 shard 。示例:
POST /_cluster/reroute { "commands": [ { "move": { "index": "test1", "shard": 0, "from_node": "node1", "to_node": "node2" } } ] }
- 上例是将 test1 索引的 0 号主分片,从 node1 迁移到 node2 。
- 目标节点上不能存在该分片的副分片,否则不允许迁移。
- 迁移时,建议先禁用自动分配、自动均衡:
"cluster.routing.allocation.enable": "none" "cluster.routing.rebalance.enable": "none"
# split
- API 格式:
POST /<index>/_split/<target-index>
。 - 用途:将一个索引分割为拥有更多主分片的新索引
- 例:
POST /my-index-1/_split/my-index-2 { "settings": { "index.number_of_shards": 2 } }
- 分割索引的前提条件:
- 源索引的 health 为 green 。
- 源索引改为只读模式。可执行以下请求:
PUT /my-index-1/_settings { "settings": { "index.blocks.write": true # 禁止写操作,但允许删除 } }
- 目标索引不存在。
- 目标索引的主分片数,是源索引的主分片数,的整数倍,比如 1 倍、2 倍。使得源索引的每个主分片,都可以平均拆分成多个目标索引的主分片。
- 分割索引的工作流程:
- 创建目标索引,继承源索引的配置,但主分片数更多。
- 将源索引的数据通过硬链接或拷贝,迁移到目标索引。
- 允许目标索引被客户端访问。
# shrink
- API 格式:
POST /<index>/_shrink/<target-index>
。 - 用途:将一个索引收缩为拥有更少主分片的新索引。
- 例:
POST /my-index-1/_shrink/my-index-2 { "settings": { "index.number_of_shards": 1 } }
- 收缩索引的前提条件:
- 源索引的 health 为 green 。
- 源索引为只读,并且所有主分片位于同一个节点上。可使用以下配置:
PUT /my-index-1/_settings { "settings": { "index.number_of_replicas": 0, # 将主分片的副分片数量改为 0 ,方便迁移 "index.routing.allocation.require._name": "node-1", # 将主分片全部移到一个节点上 "index.blocks.write": true } }
- 目标索引不存在。
- 源索引的主分片数,是目标索引的主分片数,的整数倍。
# segment
# API
相关 API :
POST /<index>/_refresh # 触发一次索引的 Refresh POST /<index>/_flush # 触发一次索引的 Flush POST /_forcemerge # 执行一次 segment 的强制合并 POST /<index>/_forcemerge? # 将指定的索引强制合并 only_expunge_deletes=true # 只合并文档删除率超过 expunge_deletes_allowed 的 segment max_num_segments=1 # 将每个 shard 中的 segment 合并到只剩几个,不管文档删除率 GET /_tasks?detailed=true&actions=*forcemerge # 查看正在执行的 forcemerge 任务
- 删除一个文档之后,如果没有 Refresh ,则依然可以查询到该文档,并且再次请求删除该文档时会报错:
version conflict, current version [2] is different than the one provided [1]
- 发出 forcemerge 请求时:
- 会阻塞客户端,直到合并完成才返回响应。
- 如果客户端断开连接,也会继续执行合并任务。
- 如果服务器正在对该 index 执行 delete 任务或 forcemerge 任务,则会忽略客户端发出的合并请求。
- 如果合并请求没有加上 URL 参数,则也是按照自动合并的算法,只处理适合合并的 segment 。
- 删除一个文档之后,如果没有 Refresh ,则依然可以查询到该文档,并且再次请求删除该文档时会报错:
请求
GET /_cat/segments/test_segments?v
的结果示例:index shard prirep ip segment generation docs.count docs.deleted size size.memory committed searchable version compound test_segments 0 p 10.0.0.1 _x 33 6665 0 15.4mb 74939 true true 7.4.0 true test_segments 0 p 10.0.0.1 _12 38 13000 0 28mb 97976 true true 7.4.0 true test_segments 0 p 10.0.0.1 _14 40 39416 0 78.6mb 178092 true true 7.4.0 true
表中每行描述一个 segment 的信息,各列的含义如下:
index # 该 segment 所属的索引 shard # 所属的分片 prirep # 分片类型,为 primary 或 replica ip # 分片所在主机的 IP segment # segment 在当前 shard 中的 36 进制编号,从 _0 开始递增。新增的文档会存储在编号最大的 segment 中,但合并之后,文档所在的 segment 可能变化 generation # generation 的十进制编号,从 0 开始递增 docs.count # 可见的文档数。不包括 deleted 文档、尚未 refresh 的文档、副分片的文档 docs.deleted # deleted 文档数 size # 占用的磁盘空间,单位 bytes size.memory # 占用的内存空间,单位 bytes committed # 该 segment 是否已经提交到磁盘。取值为 false 则说明正在使用 translog searchable # 该 segment 是否允许搜索 version # 存储该 segment 的 Lucene 版本 compound # 该 segment 的所有文件是否已经合并为一个文件。这样能减少打开的文件描述符,但是会占用更多内存,适合体积小于 100M 的 segment
docs.count + docs.deleted
等于实际存储的文档总数。docs.deleted / (docs.count + docs.deleted)
等于文档删除率。
# 配置
- 索引中关于 Lucene segment 配置:
PUT /my-index-1 { "settings": { "index": { "translog": { "durability": "request", # 当客户端发出写请求时,要等到将 translog 通过 fsync 写入磁盘之后,才返回响应 "sync_interval": "5s", # 每隔多久执行一次 fsync (不考虑是否有客户端请求) "flush_threshold_size": "512mb", # 当 translog 超过该大小时,就执行一次 Flush } "merge": { "policy": { "expunge_deletes_allowed": 10, # 调用 expungeDeletes 时,只合并文档删除率超过该值的 segment ,默认为 10% "floor_segment": "2mb", # 自动合并时,总是合并小于该体积的 segment ,不管文档删除率。这样能避免存在大量体积过小的 segment "max_merged_segment": "5gb", # 自动合并时,限制产生的 segment 的最大大小 "max_merge_at_once": 10, # 自动合并时,每次最多同时合并多少个 segment "max_merge_at_once_explicit": 30, # forcemerge 或 expunge_delete 时,每次最多同时合并多少个 segment "segments_per_tier": 10, # 每层最多存在的 segment 数,如果超过该值则触发一次自动合并 } } } } }
- 对于 max_merged_segment :
- 如果 n 个 segment 预计的合并后体积低于 max_merged_segment ,则自动合并。否则,让 n-1 再预计合并后体积。
- 即使 n=1 ,但如果存在 deleted 文档,也可能被自动合并。
- 如果某个 segment 的体积超过 max_merged_segment ,则可能一直不会被自动合并,除非其中的文档删除率足够大。
- 此时可以通过 forcemerge 强制合并,或者通过 reindex 重新创建该索引。
- 如果 n 个 segment 预计的合并后体积低于 max_merged_segment ,则自动合并。否则,让 n-1 再预计合并后体积。
# data stream
:数据流。一种管理单元,包含一个或多个后端索引(backing index)。
- 数据流适合存储大量呈时间序列的数据,且平时只需要新增文档,很少修改、删除文档。
- 数据流创建的索引默认按以下格式命名:
ds-<data-stream>-<yyyy.MM.dd>-<generation_id>
- 当数据流收到一个查询文档的请求时,会自动路由到它的各个索引。
- 每个存储到数据流的文档,必须包含一个
@timestamp
字段,属于 date 或 date_nanos 类型。 - 例:向一个数据流中新增一个文档查询数据流中的文档:
POST /my-data-stream/_doc/ { "@timestamp": "2020-03-08T11:06:07.000Z", "message": "Hello" }
GET /my-data-stream/_search { "query": { "match": { "message": "Hello" } } }
# ILM
:索引生命周期管理(Index lifecycle Management),是一些自动管理索引的策略,比如减少副本的数量、超过多少天就删除索引。
# 线程池
ES 的每个节点创建了多个线程池(thread pool),分别处理 get、index 等不同类型的请求。
可通过
GET /_nodes/stats
查询各个节点的线程池状态,例如:"thread_pool": { "get": { # 处理 get 请求的线程池 "threads": 16, # 线程总数 "queue": 0, # 等待被处理的请求数 "active": 0, # 正在处理请求的线程数 "rejected": 0, # 已拒绝的请求数,ES 重启之后会重新计数 "largest": 16, # 最大的 active 数 "completed": 1580335 # 已完成的请求数,ES 重启之后会重新计数 }, "search": { "threads": 25, "queue": 0, "active": 1, "rejected": 0, "largest": 25, "completed": 3340013239 }, ...}
- 也可通过
GET /_cat/thread_pool?v&h=host,name,size,active,queue_size,queue,rejected,largest,completed
查询。 - 如果 active 的线程数达到线程池上限,即没有空闲的线程,则新增的请求会被放到 queue 缓冲队列,等待处理。
- 如果 queue 中的请求数达到队列上限,则新增的请求会被拒绝(rejected),对客户端报错 HTTP 429 。
- ES 集群的 queue 总量等于 node_count*queue_size 。
- 也可通过
配置示例:
node.processors: 2 # 当前主机可用的 CPU 核数,默认为全部核数 thread_pool: write: # type: fixed # 线程池大小的类型,fixed 是固定数量,scaling 是自动调整数量 # size: 10 # 线程池大小 queue_size: 1000 # 队列大小,取值为 -1 则不限制
- 如果 ES 经常发生 rejected 报错,建议采用默认的线程池 size ,只是增加 queue_size ,或者增加节点数量、增加 CPU 核数。
几个线程池的默认容量:
线程池 处理操作 size queue_size search count、search、suggest CPU_count*3/2+1 1000 get get CPU_count 1000 write index、delete、update、bulk CPU_count 1000 force_merge force_merge 1 -1
# 相关 API
# cat
:Compact and aligned text(紧凑的文本信息)
- ES 返回的响应内容默认采用 JSON 格式,方便程序处理。而使用 _cat API 会按列表形式返回一些统计信息,更适合供人阅读。
- 相关 API :
GET /_cat/nodes # 查询节点的信息 GET /_cat/indices[/<index>] # 查询索引的信息 GET /_cat/shards[/<index>] # 查询分片的信息 GET /_cat/segments[/<index>] # 查询索引段的信息 GET /_cat/templates # 查询索引模板的信息
- _cat 支持在 URL 中加入以下请求参数:
?v # verbose ,增加显示一行表头 ?help # 显示所有可用的列名及其含义 ?v&h=ip,disk* # headers ,只显示指定的列。支持使用通配符 ?sort=index,docs.count # 按一个或多个字段升序排列 ?sort=index:desc # 降序排列
- _cat 支持在 URL 中加入以下请求参数:
# tasks
- _tasks API 用于管理 ES 集群中执行的任务。
- 相关 API :
GET /_tasks # 查询各个节点上正在执行的任务 GET /_tasks?detailed=true # 查询任务的详细信息 GET /_tasks?nodes=node1,node2 # 查询指定节点上执行的任务 GET /_tasks?wait_for_completion=true&timeout=10s # 等待任务执行完,才返回响应 POST /_tasks/<task_name>/_cancel # 取消任务 POST /_tasks/_cancel?nodes=node1,node2 # 取消任务
# reindex
reindex API 用于将源 index 中的文档拷贝到目标 index 中。
- 源 index 可以是位于当前 ES ,也可以是位于其它 ES 。
- 拷贝时,不会拷贝 settings、mappings ,因此需要实现创建 dest index 或 index template 。
例:
POST /_reindex { "source": { "index": "index_1", # "query": { # 可以加上 query 子句,只拷贝部分文档 # "match": { # "test": "data" # } # }, # "_source": ["user.id", "_doc"] # 指定要拷贝的字段。默认为 true ,拷贝全部字段 # "max_docs": 1000, # 限制拷贝的文档数,默认不限制 }, "dest": { "index": "index_2", # "op_type": "create" }, # "conflicts": "proceed" # 拷贝时,如果遇到文档已存在的 version conflict 报错,默认会停止 reindex 。如果设置该参数,则会继续执行 reindex ,只是记录冲突的次数 }
例:从其它 ES 拷贝文档到当前 ES
- 在 elasticsearch.yml 中添加允许 reindex 的远程 ES 白名单:
reindex.remote.whitelist: "10.0.0.2:9200,10.0.1.*:*" # 可以填多个服务器地址,不需要加 http:// 前缀
- 调用 reindex API :
POST /_reindex { "source": { "remote": { # 要连接的远程 ES "host": "http://10.0.0.2:9200", # ES 的地址必须加协议前缀,且声明端口号 "username": "test", "password": "******" }, "index": "index_1", # 要拷贝的源 index 名称 }, "dest": { "index": "index_2" } }
- 查看 reindex 任务的进度:
GET /_tasks?detailed=true&actions=*reindex
- 在 elasticsearch.yml 中添加允许 reindex 的远程 ES 白名单:
# rollover
- 过渡(rollover):当满足指定条件时,将索引迁移到另一个索引。
- 相关 API :
POST /<rollover-target>/_rollover/<target-index> <request_body> # 给索引添加一个过渡规则
- 过渡目标 target-index 可以是索引别名或数据流。如果省略该值,则将原索引名递增 1 ,作为目标名。
- 例:
POST /my-index-1/_rollover/my-index-2 { "conditions": { # 这里指定了多个条件,只要满足其中之一即可 "max_age": "7d", # 索引创建之后的存在时长 "max_docs": 1000, "max_size": "5gb" } }
# snapshot
:用于将索引保存为快照文件,从而备份数据。
用法:
- 在 elasticsearch.yml 中加入配置:
path.repo: ["backups"] # 声明存储备份仓库的目录
- 创建一个备份仓库:
PUT _snapshot/backup_repo_1 { "type": "fs", # fs 类型表示共享文件系统,需要挂载到所有 ES 节点 "settings": { "location": "backup_repo_1", # 指定该仓库的存储路径,这里使用相对路径,实际保存路径为 elasticsearch/backup/backup_repo_1 # "max_snapshot_bytes_per_sec": "20mb", # 限制生成快照的速度 #"max_restore_bytes_per_sec": "20mb" # 限制导入快照的速度 } }
- 创建快照:
PUT /_snapshot/backup_repo_1/snapshot_1 { "indices": "index_1,index_2" }
- 此时会立即返回响应报文,然后在后台创建快照。
- 如果已存在同名的 snapshot ,则会报错:
Invalid snapshot name [snapshot_1], snapshot with the same name already exists
- 生成的第一个快照文件是全量备份,而之后的快照文件是增量备份。
- 从快照中导入索引,从而恢复数据:
PUT /_snapshot/backup_repo_1/snapshot_1 { "indices": "index_1,index_2" }
- 在 elasticsearch.yml 中加入配置:
相关 API :
PUT /_snapshot/<repo> [request_body] # 创建备份仓库 PUT /_snapshot/<repo>/<snapshot> [request_body] # 生成快照 POST /_snapshot/<repo>/<snapshot>/_restore [request_body] # 导入快照 POST /_snapshot/<repo>/_cleanup # 删除未被现有快照引用的过时数据 DELETE /_snapshot/<repo>/<snapshot> # 删除快照 GET /_snapshot/_all # 查看所有备份仓库 GET /_snapshot/<repo> # 查看一个备份仓库的信息 GET /_snapshot/<repo>/_all # 查看一个备份仓库下的所有快照 GET /_snapshot/<repo>/<snapshot> # 查看指定快照的信息 GET /_snapshot/<repo>/<snapshot>/_status # 增加显示快照的 size_in_bytes GET /_recovery/ # 查看所有创建、恢复快照的记录