(8.2)link
You know, for search (and analysis)
Elasticsearch是Elastic Stack中核心的分布式搜索和分析引擎。Logstash和Beats帮助收集,聚合以及丰富你的数据并存储在Elasticsearch。Kibana使你能够交互式地探索、可视化和分享对数据的见解,并管理和监视stack。Elasticsearch用于索引,查询以及分析。
Elasticsearch提供对所有类型的数据的近实时搜索(near real-time)和分析。无论是结构化还是非结构化的文本,数值类型的数据,或者地理位置数据,Elasticsearch都能有效的进行存储并以某种方式进行索引来实现快速查询。你可以不仅仅是简单的数据检索而是可以进一步的对信息进行聚合来发现你数据中的趋势和patterns。随着你的数据和查询体量的增大,Elasticsearch的分布式功能使你的部署能够无缝地(seamless)随之增长。
虽然不是每一个问题都是一个查询问题,Elasticsearch为在各种用例中处理数据提供了速度(speed)和灵活性(flexibility)。
添加一个搜索框(search box)到一个app或者网页中
存储和分析日志,指标以及安全事件数据
使用machine learning自动对你的数据行为构建实时的模型
使用Elasticsearch作为一个存储引擎自动化业务工作流(business workflows)
使用Elasticsearch作为一个管理,集成以及分析空间信息地理信息系统(GIS: geographic information system)
使用Elasticsearch作为一个生物信息学研究工具( bioinformatics research tool)来存储以及处理基因数据
我们不断的因为用户使用新颖(novel)的搜索方式而感到惊讶(amaze)。但是不管你的使用案例是否类似与这些中的一种,或者你正在使用Elasticsearch解决(tackle)一个新的问题,你在Elasticsearch中处理你数据, 文档以及索引都是一样的。
(8.2)link
Elasticsearch是一个分布式的文档存储。Elasticsearch 存储已序列化为 JSON 文档的复杂数据结构,而不是将信息存储为列式数据行。当你的集群中有多个Elasticsearch节点,存储的文档跨集群分布并能立即从任何节点访问。
文档在存储之后,它会被索引(index)并且在能在near real-time--一秒内完全的用于搜索。Elasticsearch使用了称为倒排表(inverted index)的数据结构,它能够用于快速的全文检索。inverted index列出了出现在所有文档中的每一个unique word并识别出每一个单词所在的所有文档。
索引(index)可以认为是一个优化后的文档集合,每一篇文档是一个域(field)的集合,每一个域是包含数据的一个键值对(key-value pair)。默认情况下,Elasticsearch会索引所有域中的数据并且每一种索引域(indexed field)都有专门的优化后的数据结构。例如,text field存储在倒排索引(inverted index)中,numeric和geo field存储在BKD树中。使用每一种域的数据结构进行组合(assemble)和返回查询结果的能力使得Elasticsearch特别的快。
Elasticsearch同样有schema-less的能力,意味着不用显示的指定如何处理一篇文档中的不同的域就可以直接对文档进行索引。当开启dynamic mapping后,Elasticsearch能自动的检测并添加新的域到索引中。默认的行为使得索引以及探索你的数据变得简单。只需要开始索引文档,Elasticsearch就会进行检测并将booleans,floating point,integer values,dates和strings映射成Elasticsearch中合适的数据类型。
最终,当你比Elasticsearch更了解自己的数据并且想要按照自己的方式来处理。你可以定义规则来控制dynamic mappings以及显示的(explicit)定义mapping来完全的控制如何对域进行存储和索引。
定义你自己的mapping可以让你:
区分出full-text string field跟exact value string field
执行特定语言的文本分析
为部分匹配对域进行优化
使用自定义的date formats
使用geo_point
和 geo_shape
这些不能被自动检测的数据类型
基于不同的目的,用不同的方式索引同一个域通常是很有用的。例如你可能想要将一个string field索引为text field用于全文检索以及keyword域用于排序、聚合。或者你可能会选择使用多个语言分词器来处理包含用户输入的内容。
在索引期间作用到full-text field的analysis chain在查询期间同样需要使用。当你查询一个full-text field,在索引中查找term前,它的请求文本(query text)也会经历(undergo)相同的analysis。
(8.2)link
当使用Elasticsearch作为一个文档存储(document store),检索文档以及文档的元信息(metadata)时,你能够轻松访问全套搜索能力,其能力来源是因为构建在Apache Lucene 搜索引擎库之上。
Elasticsearch提供了一套简单的,容易理解的(coherent)的REST API,用于管理集群,索引以及查询数据。出于测试的目的,你可以简单的通过命令行或者Kibana中的Developer Console直接提交一个请求。在你的应用中,你可以选择语言并使用Elasticsearch client:Java, JavaScript, Go, .NET, PHP, Perl, Python 或者 Ruby。
Elasticsearch REST APIs支持结构化查询(structured query),全文检索,以及复杂的查询,比如query的组合。结构化查询类似你在SQL中构造的查询类型。例如,你可以在employee
索引中查询gender
和age
域并且根据hire_date
域对匹配的结果进行排序。全文检索会找到满足查询条件的所有的文档并且根据相关性(relevance,how good a match they are for your search terms)排序。
除了查询不同的term,你还可以执行短语查询(phrase search),相似度查询(similarity search),前缀查询(prefix search)以及获得autocomplete suggestions。
想要查询地理位置或者其他数值类型的数据的话,Elasticsearch将这类非文本的数据索引到一个优化后的数据结构(BKD)使得支持高性能的地址位置和数值查询。
你可以使用Elasticsearch中JSON风格的查询语言(Query DSL)来访问所有的查询能力。你也可以构造SQL-style query查询/聚合数据,以及使用JDBC和ODBC驱动使得更多的第三方应用通过SQL使用Elasticsearch。
Elasticsearch的聚合(aggregation)能让你构建复杂的数据汇总并获得关键指标的洞见(insight),模式(pattern)以及趋势(trend)。聚合能让你回答下面的问题,而不是仅仅如谚语中所说的needle in a haystack:
haystack中有多少个needle?
needle的平均长度
每个生产商(manufacturer)制造的needle的median length
过去的六个月中,每个月添加到haystack的needle的数量
你可以使用聚合回答更多subtle问题,例如:
最受欢迎的needle生产商是哪家?
是否存在不寻常或者异常的(anomalous)needle?
由于聚合使用了查询中使用的相同的数据结构,所以非常的快,使得可以实时的分析以及可视化你的数据。报表跟dashboard可以随着你的数据的变更而更新,使得你可以基于最新的信息采取措施(take action)。
聚合是跟查询请求一起执行的。你可以在单个请求中对相同的数据进行查询,过滤,以及分析。因为聚合要在某个查询的上下文中计算,你不仅仅能展示70号needle的数量统计,你还能展示满足你的策略的needle:比如说70号的不沾针(non-stick embroidery needles)。
想要自动分析你的时序数据吗?你可以使用machine learning功能创建你的数据中普通行为(normal behavior)的准确基线以及识别出异常模式(anomalous pattern)。使用machine learning,你可以检测下面的信息:
Anomalies related to temporal deviations in values, counts, or frequencies
Statistical rarity
Unusual behaviors for a member of a population
And the best part? 你不需要指定算法,模型或者其他数据科学相关的配置就可以实现上面的功能。
(8.2)link
Elasticsearch总是可用的(available)并且根据你的需要进行扩展。It does this by being distributed by nature。你可以向一个集群中添加服务(节点)来提高承载力(capacity),Elasticsearch可以跨所有可用的节点,自动的分布/查询(distribute/query)数据。不需要overhaul你的应用,Elasticsearch知道如何平衡多个节点的集群来提供扩展以及高可用能力。The more nodes, the merrier。
Elasticsearch是如何工作的?在底层实现中,一个Elasticsearch index只是一个或多个物理分片(physical shards)的逻辑组合(logical grouping)。每一个分片实际上是一个self-contained index。通过将索引中的文档分布到多个分片,将分片分布到多个节点,Elasticsearch可以确保冗余(ensure redundancy),使得应对硬件故障以及节点添加到集群后,查询能力的提升。随着集群的增长(收缩),Elasticsearch能自动的迁移(migrate)分片来rebalance集群。
分片的类型有两种:主分片跟副本分片(primary and replica shard)。索引中的每一篇文档属于某一个主分片。一个副本分片是某个主分片的拷贝。副本分片提供了数据的冗余来应对硬件故障以及提高例如查询或者检索一篇文档的读取请求的能力。
某个索引中的主分片数量在索引创建后就固定了。但是副本分配的数量可以在任何时间内更改,不会影响(interrupt)索引或者查询操作。
对于分片大小和索引的主分片数量,有很多性能考虑点以及trade off。分片越多,维护这些索引的开销就越大。分片大小越大,当Elasticsearch需要rebalance集群时,移动分片花费的时间越大。
在很多较小的分片上查询时,在每一个分片上的查询很快,但是分片越多,查询次数就越多,开销就越大,所以在数量较小,体积较大的分片上的查询可能就更快。In short…it depends。
As a starting point:
将分片的平均大小保持在几个GB以及十几个GB之间。对于基于时间的数据,通常来说,分片的大小在20GB到40GB之间
避免出现大量分片的问题。一个节点可以拥有的分片数量跟可用的堆内存成正比。一般来说(as a general rule),每1GB的堆内存中的分片数量应该小于20个。
对于你的用例,确定最佳配置的最好方式是通过testing with your own data and queries。
集群中的节点之间需要良好的,可靠的连接。若要能提供一个较好的连接,你通常会将节点放在相同的数据中心或者附近的数据中心。然而为了高可用,你同样需要避免单点故障(single point of failure)。某个地区(location)发生停电后,其他地区必须能接管服务。这个问题的答案就是使用CCR(Cross-cluster replication)。
CCR提供了一种从主集群(primary cluster)自动同步索引到secondary remote cluster的方法,即secondary remote cluster作为一个热备(hot backup)。如果primary cluster发生了故障,secondary cluster可以进行接管。你可以使用CCR创建secondary cluster,给地理上靠近(geo-proximity)这个secondary cluster的用户提供读取请求。
与任何企业系统一样,你需要工具来secure,manage,以及monitor你的Elasticsearch 集群。Security,monitoring,以及administrative features都集成到了Elasticsearch,使得你可以使用Kibana作为控制中心来管理集群。比如data rollups、index lifecycle management这些功能能帮助你根据时间来管理你的数据。
这个章节介绍了如何设置Elasticsearch并且使其运行,包含的内容有:
下载
安装
启动
配置
官方给出的操作系统以及JVM的支持列表见Support Matrix.Elasticsearch在这些平台上都经过了测试,但是在列表外的其他平台上还是有可能可以正常工作的。
Elasticsearch使用Java构建,并且每次发布都捆绑了一个OpenJDK,这个OpenJDK由JDK维护者使用GPLv2+CE协议维护。建议使用捆绑的JDK,它位于Elasticsearch home目录中名为jdk的目录中。
可以通过设置环境变量ES_JAVA_HOME
来使用你自己的Java版本。如果你一定要使用一个跟捆绑的JVM不一样的Java版本,我们建议你使用Java的长期支持版本LTS 。如果使用了一个错误Java版本的,Elasticsearch将不会启动。当你使用了自己的JVM后,绑定的JVM目录可能会被删除。
在生产上,我们建议你在专用的主机或者主服务器上(primary service)运行Elasticsearch。假定Elasticsearch是主机上或者容器上唯一的资源密集型的应用,那么一些Elasticsearch的功能比如自动化分配JVM堆大小就能实现。比如说,你可能同时运行Metribeat跟Elasticsearch来做集群统计,那么就应该将resource-heavy的Logstash部署在它自己的主机上。
你可以在自己的设备上运行Elasticsearch或者也可以使用AWS, GCP, and Azure上专用的Elasticsearch服务器。
Elasticsearch以下列的打包方式呈现:
我们同样提供了下列的配置管理工具有助于大型的部署
在Linux和MacOS平台下,Elasticsearch是作为一个.tar.gz
的归档文件。
这个安装包同时包含了免费和订阅的特性,30天试用可以使用所有的功能。
Elasticsearch最新的稳定版本可以从这个页面下载,其他版本可以从过去的发布页面下载。
NOTE: Elasticsearch中捆绑了一个OpenJDK,这个OpenJDK由JDK维护者使用GPLv2+CE协议维护,如果要使用自己的Java版本,
Linux下Elasticsearch-7.15.2归档文件的下载以及安装如下所示:
xxxxxxxxxx
51wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linux-x86_64.tar.gz
2wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linux-x86_64.tar.gz.sha512
3shasum -a 512 -c elasticsearch-7.15.2-linux-x86_64.tar.gz.sha512
4tar -xzf elasticsearch-7.15.2-linux-x86_64.tar.gz
5cd elasticsearch-7.15.2/
上文第三行Compares the SHA of the downloaded .tar.gz
archive and the published checksum,which should output elasticsearch-{version}-linux-x86_64.tar.gz: OK
。
上文第五行就是所谓的 $ES_HOME
。
MacOS下Elasticsearch-7.15.2归档文件的下载以及安装如下所示:
xxxxxxxxxx
51wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-darwin-x86_64.tar.gz
2wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-darwin-x86_64.tar.gz.sha512
3shasum -a 512 -c elasticsearch-7.15.2-darwin-x86_64.tar.gz.sha512
4tar -xzf elasticsearch-7.15.2-darwin-x86_64.tar.gz
5cd elasticsearch-7.15.2/
上文第三行Compares the SHA of the downloaded .tar.gz
archive and the published checksum,which should output elasticsearch-{version}-linux-x86_64.tar.gz: OK
。
上文第五行就是所谓的 $ES_HOME
。
一些商业功能会自动创建索引。默认情况下,Elasticsearch可以被配置为允许自动创建索引,并且不需要再做额外的步骤。然而,如果你关闭了自动创建索引, 你必须在elasticsearch.yml
中配置action.auto_create_index来允许商业功能创建下面的索引:
xxxxxxxxxx
11action.auto_create_index: .monitoring*,.watches,.triggered_watches,.watcher-history*,.ml*
IMPORTANT:如果你正在使用Logstash或者Beats,那么你很有可能需要在action.auto_create_index配置额外的索引名,确切的名字取决去你的本地配置。如果你不能保证正确的名字,你可以考虑将索引名设置为*,这样就会自动创建所有的索引
Elasticsearch可以通过下面的命令行启动:
xxxxxxxxxx
11./bin/elasticsearch
如果Elasticsearch keystore有密码保护,你会被提示(be prompted to)输入keystore's的密码,详细内容见安全配置。
默认情况下,Elasticsearch将日志打印到控制台(标准输出)以及日志目录的<clustername>.log
文件中。Elasticsearch在启动期间会生成一些日志,但一旦初始化完成,它将继续在前台(foreground)运行并且不再生成任何日志直到一些值的记录的信息产生。在Elasticsearch运行期间,你可以通过HTTP接口访问默认的9200端口与Elasticsearch交互。输入Ctrl-c
来停止Elasticsearch。
NOTE:Elasticsearch安装包中的所有脚本要求的Bash版本需要支持arrays并且假定/bin/bash是存在的,同样的,Bash在这个路径是存在的或者能通过动态链接找到
你能通过HTTP请求访问localhost:9200来测试Elasticsearch节点是否在运行中:
xxxxxxxxxx
11GET /
你应该能收到类似下面的回应(response)
xxxxxxxxxx
171{
2 "name" : "Cp8oag6",
3 "cluster_name" : "elasticsearch",
4 "cluster_uuid" : "AT69_T_DTp-1qgIJlatQqA",
5 "version" : {
6 "number" : "7.15.2",
7 "build_flavor" : "default",
8 "build_type" : "tar",
9 "build_hash" : "f27399d",
10 "build_date" : "2016-03-30T09:51:41.449Z",
11 "build_snapshot" : false,
12 "lucene_version" : "8.9.0",
13 "minimum_wire_compatibility_version" : "1.2.3",
14 "minimum_index_compatibility_version" : "1.2.3"
15 },
16 "tagline" : "You Know, for Search"
17}
在命令行指定-d
使得Elasticsearch成为一个后台程序,并且通过参数-p
生成一个pid
文件记录进程号。
xxxxxxxxxx
11./bin/elasticsearch -d -p pid
如果Elasticsearch keystore有密码保护,你会被提示(be prompted to)输入keystore's的密码,详细内容见安全配置。
在$ES_HOME/logs/
目录能找到日志信息。
通过杀死pid
文件中记录的进程号来关闭Elasticsearch。
xxxxxxxxxx
11pkill -F pid
NOTE:tar.gz的安装包中不包含systemd组件。如果要把Elasticsearch作为一个服务管理,用RPM或者Debian的安装包进行安装。
Elasticsearch默认装载(load)的配置文件路径为$ES_HOME/config/elasticsearch.yml
,这个配置文件中的格式见Configuring Elasticsearch。
在配置文件中可以指定的任何设置(settings)都可以通过命令行的参数指定,使用-E
语法:
xxxxxxxxxx
11./bin/elasticsearch -d -Ecluster.name=my_cluster -Enode.name=node_1
TIP:一般来说,任何集群范围(cluster-wide)的配置(比如说 cluster.name)都应该在elasticsearch.yml文件中配置,同时具体节点的任意配置比如说node.name可以通过命令行参数指定
归档发行版 (archive distribution)是self-contained(意思就是所有的文件都在同一个目录中,Elasticsearch还有安装包发行版package distribution,通过这种方式安装后,文件会分散在不同的目录中)。所有的文件和目录默认情况下都在$ES_HOME
下,$ES_HOME
在解压归档后会被创建。
这是一种非常方便的方式因为你不需要创建任何目录来开始使用Elasticsearch,并且当卸载Elasticsearch时只要简单的移除$ES_HOME
。然而我们建议把配置文件目录config directory、数据目录data directory、以及日志目录log directory的位置进行变更,以免在以后重要的数据被删除。
类型Type | 描述Description | 默认位置Default Location | 设置Setting |
---|---|---|---|
home | Elasticsearch home目录或者$ES_HOME | 解压归档后创建这个目录 | |
bin | 二进制脚本,包含elasticsearch 用于启动一个节点以及elasticsearch-plugin 用于安装插件 | $ES_HOME/bin | ES_PATH_CONF |
conf | 包含elasticsearch.yml 的所有配置文件 | $ES_HOME/config | |
data | 每一个索引/分片的数据文件的位置 | $ES_HOME/data | path.data |
logs | 日志文件位置 | $ES_HOME/logs | path.logs |
plugins | 插件文件位置。每个插件在一个子目录中 | $ES_HOME/plugins | |
repo | Shared file system repository locations. Can hold multiple locations. A file system repository can be placed in to any subdirectory of any directory specified here. | NOT_configured | path.repo |
现在你建好了一个Elasticsearch测试环境。在你开始认真做开发护着进入Elasticsearch的生产环境,你必须做一些额外的设置:
(8.2)link
Elasticsearch附带(ship with)了很好的默认配置并且只需要较小的配置。在一个运行中的集群中,大部分的设置可以通过Cluster update settings API进行更改。
配置文件应该包含对指定节点(node-specific)的设置,例如node.name
以及路径,或者是能让节点加入集群的配置,例如cluster.name
以及network.host
。
Elasticsearch有三个配置文件:
elasticsearch.yml
用于配置 Elasticsearch
jvm.options
用于配置Elasticsearch JVM 设置
log4j2.properties
用于配置 Elasticsearch日志记录
这三个文件都在config目录中,他们的默认路径取决于使用哪种方式安装:归档发行版(archive distribution)tar.gz
或者zip
还是安装包发行版(package distribution)Debian 或者RPM安装包。
对于归档发行版,config目录位置默认是$ES_HOME/config
。config目录的位置能通过ES_PATH_CONFIG
这个环境变量进行更改:
xxxxxxxxxx
11ES_PATH_CONF=/path/to/my/config ./bin/elasticsearch
或者,通过在命令行或profile文件中export
ES_PATH_CONFIG
这个环境变量。
对于安装包发行版,config目录的位置默认在/etc/elasticsearch
,config目录的位置可以通过ES_PATH_CONF
这个环境变量变更。注意的是在shell中设置这些是不够的。Instead, this variable is sourced from /etc/default/elasticsearch
(for the Debian package) and /etc/sysconfig/elasticsearch
(for the RPM package). You will need to edit theES_PATH_CONF=/etc/elasticsearch
entry in one of these files accordingly to change the config directory location.
配置格式是YAML,下面是更改数据和日志目录的例子
xxxxxxxxxx
31path:
2 data: /var/lib/elasticsearch
3 logs: /var/log/elasticsearch
配置也可以进行平铺(flattened)
xxxxxxxxxx
21path.data: /var/lib/elasticsearch
2path.logs: /var/log/elasticsearch
在YAML中,你可以格式化non-scalar的值写成序列:
xxxxxxxxxx
41discovery.seed_hosts:
2 - 192.168.1.10:9300
3 - 192.168.1.11
4 - seeds.mydomain.com
尽管下面的方式不是很常见(Thought less common),你也可以把non-scala的值写成数组:
xxxxxxxxxx
11discovery.seed_hosts: ["192.168.1.10:9300", "192.168.1.11", "seeds.mydomain.com"]
在配置文件中可以通过使用${...}
这类符号的方式引用环境变量:
xxxxxxxxxx
21node.name: ${HOSTNAME}
2network.host: ${ES_NETWORK_HOST}
环境变量的值必须是简单的String值,用逗号分隔的String值会被Elasticsearch解析成一个list。例如,Elasticsearch将下面的环境变量的String值根据逗号切分到list中。
xxxxxxxxxx
11export HOSTNAME="host1,host2"
集群跟节点的设置基于他们是如何被配置可以分类为:
在一个正在运行的集群上,你可以使用cluster update settings API来配置或更新动态设置。你也可以使用elasticsearch.yml
对本地未启动或者关闭的节点配置动态设置。
使用cluster update settings API更新可以是永久的(persistent),即使集群重启也生效,也可以是临时的(transient),集群在重启后就重置了。你也可以通过使用API把配置设置为null也能重置使用persistent或者transient更新过的设置。
如果你用多种方式配置了一样的设置,那么Elasticsearch会根据下面的优先顺序(order of precedence)来应用设置(apply settings)。
Transient Setting
Persistent Setting
elasticsearch.yml
setting
Default setting value
例如,你可以使用一个transient setting覆盖persistent setting或者elasticsearch.yml
。然而,在elasticsearch.yml
上的变更不会覆盖定义好的(defined)transient 或者 persistent setting。
TIP:如果你使用Elasticsearch Service,使用user settings功能来配置所有的设置。这个方法能让Elasticsearch自动的拒绝(reject)掉任何会破坏你集群的设置。 如果你在自己的设备(hardware)上运行Elasticsearch,可以使用cluster update settings API来配置集群动态设置。对于集群或者节点的静态设置只使用elasticsearch.yml来配置。使用API不会要求重启并且保证所有节点都被配置成相同的值。
WARNING: We no longer recommend using transient cluster settings. Use persistent cluster settings instead. If a cluster becomes unstable, transient settings can clear unexpectedly, resulting in a potentially undesired cluster configuration. See the Transient settings migration guide.
静态设置只能在未启动或者关闭的节点上使用elasticsearch.yml
来配置。
静态配置必须在集群中相关的所有节点上一一配置。
(8.2)link
Elasticsearch只需要很少的配置就能启动。但是在生产中使用你的集群时必须要考虑这些条目:
我们的Elastic Cloud service能自动配置这些条目,使得你的集群处在生产就绪状态。
Elasticsearch把你的索引数据和数据流(data streams)都写到data
目录中。
Elasticsearch本身也会生产应用日志,包含集群健康信息以及集群操作信息,并且写入到logs
目录中。
对于在MacOS和Linux下使用.tar.gz
, 以及Windows下使用zip
方式安装时,data
和logs
目录默认是$ES_HOME
下的子目录,然而在升级Elasticsearch时,位于$ES_HOME
下的文件是存在风险的。
在生产中,我们强烈建议在elasticsearch.yml
中设置path.data
和path.logs
将data
和logs
目录放到$ES_HOME
以外的位置。其他安装方式(rpm、macOS Homebrew、Windows .msi
)默认会把data
和logs
目录放到$ES_HOME
以外的位置。
支持在不同的平台,path.data
和path.logs
可以是不同的值:
Unix-like systems
Linux and macOS installations support Unix-style paths:
xxxxxxxxxx
31path:
2 data: /var/data/elasticsearch
3 logs: /var/log/elasticsearch
Windows
Windows installations support DOS paths with escaped backslashes:
xxxxxxxxxx
31path:
2 data: "C:\\Elastic\\Elasticsearch\\data"
3 logs: "C:\\Elastic\\Elasticsearch\\logs"
WARNING:不要更改data目录中的任何内容(content),也不要运行可能会影响data目录内容的程序。如果Elasticsearch以外的程序更改了data目录的内容,那么Elasticsearch可能会失败,报告损坏或者其他数据不一致性(data inconsistencies)的问题,也可能工作正常但是丢失了一些你的数据。
WARNING: 在7.13.0版本中废弃了
如果有这个需要,你可以在path.data
中指定多个路径。Elasticsearch会在这些路径上存储节点的数据,但是会在相同的路径上存储同一个shard的数据。
Elasticsearch不会在多个路径上去平衡shards的写入。在某个路径上的高磁盘使用率会触发整个节点的high disk usage watermark。触发后,Elasticsearch不会在这个节点增加shard,尽管这个节点的在其他路径上有可用的空间。如果你需要额外的磁盘空间,我们建议你增加新的节点而不是增加data的路径。
Unix-like systems
Linux and macOS installations support Unix-style paths:
xxxxxxxxxx
51path:
2 data:
3 - /mnt/elasticsearch_1
4 - /mnt/elasticsearch_2
5 - /mnt/elasticsearch_3
Windows
Windows installations support DOS paths with escaped backslashes:
xxxxxxxxxx
51path:
2 data:
3 - "C:\\Elastic\\Elasticsearch_1"
4 - "E:\\Elastic\\Elasticsearch_1"
5 - "F:\\Elastic\\Elasticsearch_3"
在7.13版本中弃用了多个数据路径的支持,将会在未来的版本中移除。
作为多个数据路径的替代方案,你可以通过使用硬件虚拟化层(如RAID)或软件虚拟化层(如Linux上的逻辑卷管理器(LVM)或Windows上的存储空间)来创建跨多个磁盘的文件系统。如果你希望在单台机器上使用多个数据路径,则必须为每个数据路径运行一个节点。
如果你正在一个highly available cluster中使用多个数据路径,你可以无需停机,使用类似rolling restart的方式对一个节点使用单个数据路径来实现迁移:轮流关闭每一个节点,并用一个或多个配置为使用单个数据路径的节点替换它。跟进一步的说,对于每一个当前有多个数据路径的节点来说,你应该按照下面的步骤进行迁移。原则上你可以在升级到8.0版本时执行这类迁移,但是我们建议在升级版本前先完成单个数据路径的迁移工作。
执行快照防止你的数据出现灾难性的问题
(可选)使用allocation filter将目标节点的数据进行迁移
xxxxxxxxxx
61PUT _cluster/settings
2{
3 "persistent": {
4 "cluster.routing.allocation.exclude._name": "target-node-name"
5 }
6}
你可以使用cat allocation API来跟踪数据迁移的进度。如果某些分片没有迁移,那么cluster allocation explain API会帮助你查明原因。
按照rolling restart process中的步骤执行,包括关闭目前节点。
确保你的集群是yellow
或者green
,使得你的集群中至少有一个节点有每一个分片的拷贝。
如果执行了上面的第二步,现在需要移除allocation filter。
xxxxxxxxxx
61PUT _cluster/settings
2{
3 "persistent": {
4 "cluster.routing.allocation.exclude._name": null
5 }
6}
通过删除数据路径的方式来丢弃被停掉的节点拥有的数据。
重新配置你的存储。使用LVM或者Storage Spaces将你的磁盘合并到单个文件系统中。确保你重新配置的存储有足够的空间存储数据
通过设置elasticsearch.yml
文件中的path.data
来重新配置你的节点。如果有需要的话,安装更多的节点,并使用他们自己各自的path.data
。
启动新的节点并按照rolling restart process中的其他步骤执行
确保你的集群健康是green
,使得所有的分片都已经分配结束
你也可以在你的集群中增加一些单数据路径的节点,使用allocation filters将你的数据迁移到新的节点中,然后将这些旧的节点从集群中移除。这个方法会临时增大集群中的体积,所以只有你的集群有这个膨胀能力才能使用这个方法。
如果你目前使用多个数据路径,但你的集群并不具备高可用性,则可以通过拍摄快照、创建具有所需配置的新集群并将快照还原到其中来迁移到非废弃配置。
在一个集群中,一个节点只有跟集群中的其他节点共享他的cluster.name
才能加入到这个集群中。默认的名字是elasticsearch
,但是你应该把这个名字改成一个合适的名字,这个名字能描述这个集群的目的。
xxxxxxxxxx
11cluster.name: logging-prod
IMPORTANT:在不同的环境中不要重复使用相同的集群名,否则节点可能会加入到错误的集群中。
Elasticsearch使用node.name
作为可读(human-readable)的一个特定的Elasticsearch实例。在很多APIs的返回中(response)会用到。当Elasticsearch启动后,节点名字默认是服务器的hostname,可以在elasticsearch.yml
中显示配置:
xxxxxxxxxx
11node.name: prod-data-2
默认清下,Elasticsearch只绑定类似127.0.0.1以及[::1]的回调地址(lookback address)。这样的话能够在单个服务上允许一个集群的多个节点用于开发以及测试。但是一个resilient production cluster必须是包含在其他服务上的节点。尽管还有许多newwork settings,但是通常你只需要配置network.host
:
xxxxxxxxxx
11network.host: 192.168.1.10
当你提供了network.host的值,Elasticsearch会假设你正在从开发模式转到生产模式,并且会在系统启动时升级warning到exception的检查。见development and production modes的差异。
在进入生产前配置两个重要的discovery和cluster formation设置,使得这个集群中的节点能互相发现并且选出一个master节点。
如果没有配置任何网络设置,Elasticsearch会绑定可见的回调地址并且扫描本地的9300到9305端口去连接同一个服务上的其他节点。这种行为提供了一种自动集群体验,而无需进行任何配置。即开箱即用(out of box)。
当你想要组成(form)一个集群,它包含的节点在其他服务器上时,可以使用静态的discovery.seed_hosts
设置。这个设置可以提供一个集群中其他节点的list,这些节点是候选的主节点(mater-eligible),并且有可能是live的,并且能在discovery process中作为可以联系的节点来选出种子选手(and contactable to seed the discovery process。翻译能力有限,只可意会,不可言传)。这个设置可以将集群中所有候选的主节点的地址用YAML中的序列或者数组的风格书写。每一个地址可以是IP地址或者hostname,hostname可以通过DNS关联一个或多个IP地址。
xxxxxxxxxx
51discovery.seed_hosts:
2 - 192.168.1.10:9300
3 - 192.168.1.11
4 - seeds.mydomain.com
5 - [0:0:0:0:0:ffff:c0a8:10c]:9301
如果IP地址中没有指定端口号,那么就是默认的9300,默认的端口号也可以被override
如果hostname关联多个IP 地址,那么当前节点会试图发现hostname关联的所有地址上的节点
IPv6地址使用方括号包裹(enclosed in square brackets)
如果候选的主节点的节点没有固定的名字或者地址,可以使用alternative hosts provider 来动态的找到他们的地址。
当你第一次启动Elasticsearch集群,在cluster bootstrapping阶段确定在第一次参与投票的候选主节点。在development mode中,with no discovery settings configured, this step is performed automatically by the nodes themselves。
因为auto-bootstrapping是内在不安全的,在生产模式中启动一个新的集群时,你必须显式列出候选的主节点并且他们的投票要被统计在第一轮的选票中。你可以使用cluster.initial_master_nodes
设置来列出这些候选的主节点。
IMPORTANT:当一个新的集群第一次形成之后,从每个节点的配置中移除cluster.initial_master_nodes设置。当重启一个集群或者往已存在的集群中添加一个新的节点时,不要使用该配置。
xxxxxxxxxx
91discovery.seed_hosts:
2 - 192.168.1.10:9300
3 - 192.168.1.11
4 - seeds.mydomain.com
5 - [0:0:0:0:0:ffff:c0a8:10c]:9301
6cluster.initial_master_nodes:
7 - master-node-a
8 - master-node-b
9 - master-node-c
通过node.name
来确定最初的master节点身份,默认是hostname。要确保cluster.initial_master_nodes
跟node.name
的值是一致的。如果节点的名字使用了全限定域名(fully-qualified domain name),比如master-node-a.example.com,那么你必须在cluster.initial_master_nodes中使用FQDN。相反的,如果只是仅仅使用了hostname而没有尾随的限定符,那么在cluster.initial_master_nodes也不能带尾随的限定符
见 bootstrapping a cluster和discovery and cluster formation settings。
默认情况下,Elasticsearch会根据节点的roles跟内存大小来自动的设置JVM堆的大小。我们建议使用默认的大小,它适用于大部分生产环境。
NOTE:堆大小的自动配置需要bundle JDK,如果使用自定义的JRE位置,需要Java 14以及更新的JRE。
如果有必要,你可以通过setting the JVM heap size手动覆盖默认值。
默认情况下,Elasticsearch会配置JVM,使得OOM异常转存(dump)到data
目录。在基于ROM跟Debian的安装包中,data
目录位于/var/lib/elasticsearch。在Linux、MacOs以及Windows发行版中,data
目录位于Elasticsearch安装目录的根目录。
如果默认的路径用于接受heap dump不是很合适,那么可以通过在文件jvm.options
中修改-XX:HeapDumpPath=...
。
如果你指定了一个目录,JVM将会基于正在运行的实例,用它的PID来为heap dump文件命名
如果你指定了一个固定的文件名而不是一个目录,那么这个文件必须不存在,否则heap dump会失败
默认情况下,Elasticsearch开启了垃圾回收日志。在jvm.options
文件中配置,并且输出到Elasticsearch的logs
文件中。默认的配置中,每64M就会轮换一次日志,最多消耗2G的磁盘空间。
你可以命令行来配置JVM的日志打印,见JEP 158: Unified JVM Logging。除非你直接更改jvm.options
文件,Elasticsearch的默认配置会被应用(apply)除了你自己的设置。如果要关闭默认配置,第一步先通过提供参数-Xlog:disable
关闭日志打印,然后提供你自己的命令选项。以上操作会关闭所有的JVM日志打印,所以要确定好可用的选项来满足你的需求。
见 Enable Logging with the JVM Unified Logging Framework了解更多在原始的JEP(origin JEP)中不包含的虚拟机选项。
下面的例子中创建了$ES_HOME/config/jvm.options.d/gc.options
并包含一些虚拟机选项:把默认的GC 日志输出到/opt/my-app/gc.log
。
xxxxxxxxxx
81# Turn off all previous logging configuratons
2-Xlog:disable
3
4# Default settings from JEP 158, but with `utctime` instead of `uptime` to match the next line
5-Xlog:all=warning:stderr:utctime,level,tags
6
7# Enable GC logging to a custom location with a variety of options
8-Xlog:gc*,gc+age=trace,safepoint:file=/opt/my-app/gc.log:utctime,pid,tags:filecount=32,filesize=64m
下面的例子中配置一个Elasticsearch Docker container,将GC的debug日志输出到stderr
,让容器编排器处理输出。
xxxxxxxxxx
21MY_OPTS="-Xlog:disable -Xlog:all=warning:stderr:utctime,level,tags -Xlog:gc=debug:stderr:utctime"
2docker run -e ES_JAVA_OPTS="$MY_OPTS"
默认情况下,Elasticsearch会使用一个私有的临时目录,它由一个启动脚本创建,并位于系统的临时目录中。
在一些Linux发行版中,一些系统工具会清楚 /tmp
目录下长时间未被访问的文件。这会导致Elasticsearch的私有临时目录可能会被删除。移除私有的临时目录会导致一些问题,比如一些功能随后会访问这些私有临时目录。
如果你使用.deb
或者.rpm
安装的Elasticsearch,并且在systemd
下运行,那么Elasticsearch使用的私有临时目录不会被周期性的清除(periodic cleanup)。
如果你想要在Linux跟MacOS上运行.tar.gz
发行版,可以考虑为Elasticsearch创建一个专用的临时目录,并且该目录所在路径中不包含旧的文件或目录,并且这个目录只有Elasticsearch有访问权限。最后在Elasticsearch启动前设置环境变量$ES_TMPDIR
。
默认情况下,Elasticsearch会配置JVM将fatal错误日志写到默认的日志目录中。在RPM
和Debian
安装中,目录位置为/var/log/elasticsearch
,在Linux、MacOs、Windows
发行版中,logs
目录位于Elasticsearch的安装目录。
当遇到一些fatal错误日志,它由JVM产生,比如说段错误(segmentation fault)。如果接受这些日志的路径不是很合适,可以在jvm.options
中修改-XX:ErrorFile=...
。
在发生灾难时,snapshot能防止数据永久丢失。Snapshot lifecycle management是最简单的办法来对集群实现定期备份。见Create a snapshot。
WARNING:快照是唯一可靠并且被支持的方式(supported way)来备份集群。 你不能通过拷贝data目录中的节点数据进行备份。没有一种支持方式(supported way)从文件系统层面的备份来恢复数据。如果你想尝试从这种备份中恢复集群,可能会失败并且Report出corruption或者文件丢失或者其他数据一致性的问题,或者出现成功的悄无声息的丢失一些你的数据
(8.2)link
有些设置是敏感的(sensitive),仅仅依靠文件系统的权限来保护这些值是不够。对于这种情况,Elasticsearch提供了keystore和 elasticsearch-keystore tool 来管理这些设置。
IMPORTANT:只有一些设置被设计为从keystore中读取。但是keystore没有验证一些不支持的设置。增加不支持的设置会导致Elasticsearch启动失败。
所有在keystore中的变更只有在Elasticsearch重启后才生效。
keystore中设置跟配置文件elasticsearch.yml
中的普通的设置项一样都需要在每个节点上指定。当前,所有的安全设置都是特定于节点的,即所有的节点上必须设置相同的值。
跟elasticsearch.yml
中的设置值一样,keystore中的内容无法自动的应用(apply)到正在运行的Elasticsearch节点,需要重启。然而有一些安全设置被标记为reloadable,这些设置可以被reload。
对于安全设置的值,不管是否可以reloadable,集群中的所有节点都必须一致。在安全设置变更后,执行bin/elasticsearch-keystore
调用下面的请求:
xxxxxxxxxx
41POST _nodes/reload_secure_settings
2{
3 "secure_settings_password": "keystore-password"
4}
Elasticsearch keystore会对密码进行加密。
上述API会解密并且重新读取集群中所有节点的整个keystore,但是只有reloadable的安全设置可以被应用(apply)。其他的安全设置不会生效直到下一次重启。一旦API调用返回了,意味着reload完成了,即所以依赖这些设置的内部数据结构都已经发生了变更。Everything should look as if the settings had the new value from the start。
当更改了多个reloadable安全设置后,在集群中的每一个节点上修改后,随后发起reload_secure_settings的调用,而不用在每一次变更后reload。
下面是reloadable安全设置
(8.2)link
你可以使用audit logging来记录安全相关的事件,比如认证失败,拒绝连接,以及数据访问事件。另外也会记录通过API访问安全配置的操作,例如创建、更新、移除native、built-in users,roles、role mappings 以及 API keys。
TIP:日志审计只在某些订阅中提供,详细信息见 https://www.elastic.co/subscriptions
在配置后,集群上的所有节点都需要设置一遍。静态设置,比如说xpack.security.audit.enabled
,在每个节点的elasticsearch.yml
中都必须配置。对于动态的日志设置,使用cluster update settings API 可以让所有节点的设置一致。
(Static)设置为true来开启。默认值为false。在每个节点上日志事件会被放到一个名为<clustername>_audit.json
的专用的文件中。
如果开启了,集群中的所有节点的elasticsearch.yml
都需要配置该设置。
日志事件以及其他一些信息比如获取什么样的日志可以通过下面的设置来控制:
(Dynamic)在日志输出中指定事件类型(kind of events),设置为_all
会彻底的记录所有的日志事件,但通常不建议这么做因为会非常的verbose。默认值是一个list包含:access_denied
, access_granted
, anonymous_access_denied
, authentication_failed
, connection_denied
, tampered_request
, run_as_denied
, run_as_granted
, security_config_change
。
(Dynamic)从包含的(kind of events)列表中指定排除部分选项。当xpack.security.audit.logfile.events.include的值设置为_all
时,然后用xpack.security.audit.logfile.events.exclude
来进行指定选项的排除是不错的方式。默认值是空的list。
(Dynamic)用于指定是否将REST请求的请求body作为日志事件的属性,这个设置可以用于audit search queries。
默认是false,那么请求body不会被打印出来。
IMPORTANT:注意的是,当日志事件中包含请求body时,一些敏感数据可能以明文形式被记录,即使是一些安全相关API,比如修改用户密码,认证信息在开启后有被泄露(filter out)的风险
(Dynamic)指定在每一个日志事件中,节点名字node name是否作为其中的一个域field。默认值是false。
(Dynamic)指定在每一个日志事件中,节点的地址是否作为其中的一个域field。默认值是false。
(Dynamic)指定在每一个日志事件中,节点的主机名是否作为其中的一个域field。默认值是false。
(Dynamic)指定在每一个日志事件中,节点的id是否作为其中的一个域field。不同于node name,管理员可以在配置文件中修改节点id,节点id在集群启动后将不可变更,默认值是true。
下面的设置会影响ignore policies,它们能更精细的(fine-grained)控制日志事件打印到日志文件中。拥有相同police_name的设置将会组合到一个策略(police)中。如何一个事件匹配到任意一条策略的所有条件,该日志事件将被忽略并不会被打印。大多数的日志事件都遵照(subject to)忽略策略。唯一的例外(sole exception)是security_config_change
类型的事件,无法被过滤掉(filter out),除非完全的通过xpack.security.audit.logfile.events.exclude
进行exclude。
(Dynamic)用户名字列表或者名字通配值(wildcards)。匹配该值的所有用户的日志事件不会打印出来。
(Dynamic)authentication realm的列表或者通配值,匹配该值的所有realm的日志事件不会打印出来。
(Dynamic)action名字的列表或者通配值,action的名字可以在日志事件的action
域中找到, 匹配该值的所有action的日志事件不会打印出来。
(Dynamic)角色列表或者角色通配值(wildcards)。匹配该值并且拥有该角色的所有用户的日志事件不会打印出来。如果用户拥有多个角色,而一些角色没有被策略覆盖到,那么该策略不会覆盖其日志事件。
(Dynamic)索引名字列表或者通配值,日志事件中所有的索引名都匹配后才不会打印。如果事件中涉及(concern)了多条索引,并且一些索引没有被该策略覆盖到,那么该策略不会覆盖日志事件。
(8.2)link
Elasticsearch包含多种熔断器来防止导致OOM的操作。每一种熔断器指定了内存的使用限制。另外,父级别的熔断器指定了内存的总量,限制子级别的熔断器的内存使用总量。
除了特别的说明,这些设置能通过cluster-update-settings API在运行中的集群上进行动态的更新。
关于熔断器提供的报错信息,见Circuit breaker errors。
父级别的熔断器可以通过下面的设置进行配置:
(Static)如果该值为true,那么父级别的熔断器会考虑真实的内存使用量,否则考虑的是子级别的熔断器预定(reserved)的内存量总和。默认值为true。
(Dynamic)当indices.breaker.total.use_real_memory
为false,并且虚拟机的内存使用量达到70%,或者当indices.breaker.total.use_real_memory
为true时,并且虚拟机的内存使用量达到95%,所有的父熔断器开始限制内存使用。
Filed data熔断器会估算把域filed载入到field data cache所使用的堆内存量。如果载入后会导致缓存超过了先前定义的内存限制值,熔断器将会停止该操作并返回错误。
(Dynamic)fielddata breaker的限制值,默认是40%的JVM堆内存量。
(Dynamic)该配置是一个常量,所有field data的估算值乘以这个常量来计算出最终的估算值。默认是值1.03。
Request熔断器允许Elasticsearch防止每一个请求的数据结构(例如,在一次请求中,聚合计算占用的内存量)超过一定量的内存量。
(Dynamic)Request熔断器的限制值,默认是60%的JVM堆内存量。
(Dynamic)该配置是一个常量,所有Request的估算值乘以这个常量来计算出最终的估算值。默认是值1。
in flight Request熔断器允许Elasticsearch限制所有在传输或者HTTP层的请求的内存使用量不超过在一个节点上的相对内存总量。内存使用量基于请求本身的content length。This circuit breaker also considers that memory is not only needed for representing the raw request but also as a structured object which is reflected by default overhead。
(Dynamic)in flight Request熔断器的限制值,默认是60%的JVM堆内存量。
(Dynamic)该配置是一个常量,所有in flight Request的估算值乘以这个常量来计算出最终的估算值。默认是值2。
accounting熔断器允许Elasticsearch限制某些请求已经结束,但是相关内存还未被释放的内存量。比如说Lucene的段占用的内存。
(Dynamic)accounting熔断器的限制值,默认是100%的JVM堆内存量。这意味着受到父级熔断器的配置限制。
(Dynamic)该配置是一个常量,所有accounting Request的估算值乘以这个常量来计算出最终的估算值。默认是值1。
和上文中的熔断器稍微不同的是,Script compilation熔断器限制了在一个时间周期内inline script compilation的数量。
见scripting 文档中prefer-parameters
章节的内容来了解更多。
(Dynamic)Limit for the number of unique dynamic scripts within a certain interval that are allowed to be compiled. Defaults to 150/5m, meaning 150 every 5 minutes。
写的不好的正则表达式会降低(degrade)集群稳定性以及性能。regex熔断器限制了Painless scripts中正则表达式的使用以及复杂性。
(Static))允许painless脚本中使用正则表达式,该值可以是:
limited(默认值)
允许使用正则表达式但是使用集群设置中的script.painless.regex.limit-factor限制正则表达式的复杂性
true
允许使用正则表达式并且不限制正则表达式的复杂性。regex熔断器关闭
false
不允许使用正则表达式。包含任何正则表达式的painless脚本都会返回错误
(Static))用来限制painless脚本中正则表达式的字符数量。Elasticsearch通过当前设置的值与脚本输入的值的长度的乘积值作为限制值。
比如说输入值foobarbaz
的长度为9,如果script.painless.regex.limit-factor
的值为6,那么基于foobarbaz
的正则表达式的长度为54(6 * 9)。如果超过这个限制值,将触发regex熔断器并返回错误。
只有script.painless.regex.enabled
为limited
时,Elasticsearch才会使用该限制值。
(8.2)link
Shard allocation说的是分配分片到节点的过程。该过程会在initial recovery、副本(replica)分配、rebalancing或者增加或者移除节点时发生。
master node的其中一个作用是决定如何分配分片到节点,何时在节点之间移动分片来平衡集群。
以下的一些设置用来控制分配分片的过程:
Cluster-level shard allocation settings用来控制分片和平衡操作
Disk-based shard allocation settings描述了Elasticsearch如何考虑(take into account)磁盘空间等等相关信息
Shard allocation awareness 和Forced awareness用来控制在不同的rack和可见区域上发布分片
Cluster-level shard allocation filtering允许一些节点或者组内的节点不会被分配分片,使得这些节点能够被关闭(decommissioned)
除此之外,还有一些其他的配置,见Miscellaneous cluster settings。
你可以使用下面的设置来控制分片的分配以及恢复:
(Dynamic)开启或者关闭某些分片类型的分配:
all
:(default)所有类型的分配都可以被分配
primaries
:只有主分片才能被分配
new_primaries
:只有主分片中新的索引才能被分配
none
:任何分片中的任何索引都不能被分配
在节点重启后,上述的配置不会影响本地主分片的恢复。重启后的节点上的未分配的主分片的allocation id如果匹配了集群状态中的active allocation ids,那么会立即恢复。
(Dynamic)在一个节点上允许同时进行恢复incoming recoveries的并发数量。incoming recoveries中的分片(大多数是副本分片或者就是分片正在重新分配位置relocating)将被分配到当前节点上。默认值是2。
(Dynamic)在一个节点上允许同时进行恢复outgoing recoveries的并发数量。outgoing recoveries中的分片(大多数是当前节点上的主分片或者就是分片正在重新分配位置relocating)将被分配到当前节点上。默认值是2。
(Dynamic)一种快捷方法shortcut来设置cluster.routing.allocation.node_concurrent_incoming_recoveries
和cluster.routing.allocation.node_concurrent_outgoing_recoveries
。
(Dynamic)在一个节点重启后,副本分片replica的恢复是通过网络实现的,然而一个未分配的主分片unassigned primary则是通过读取本地磁盘数据恢复的。在同一个节点上通过这种本地恢复的方式是很快的,默认值是4。
(Dynamic)该值允许执行一个检查,防止在单个主机上上分配多个相同的分片,通过主机名以及主机地址来描述一台主机。默认值是false。意味着默认不会进行检查。只有在同一台机器上的多个节点启动后,该值才会作用(apply)。
当每一个节点上的分片数量是相等并且在任何节点的任何索引上没有集中分片(concentration of shards),那么集群是平衡的。Elasticsearch会运行一个自动程序(automatic process)称为rebalancing,它会在集群中的节点之间移动分片来提高平衡性。rebalancing遵守类似 allocation filtering 和 forced awareness的分片分配规则。这些规则会阻止完全的平衡集群,因此rebalancing会努力(strive to)在你配置的规则下尽可能的去平衡集群。如果你正在使用 data tiers,那么Elasticsearch会自动的应用分配过滤规则将每一个分配放到合适的数据层,这些规则意味着平衡器在每一层中独立工作。
你可以使用下面的设置在集群中控制分片的平衡:
(Dynamic)为指定的分片类型开启或关闭rebalancing:
all
:(default)所有类型的分片都允许rebalancing
primaries
:只有主分片才允许rebalancing
replicas
:只有副本分片才允许rebalancing
none
:任何类型分片的任何索引都不允许rebalancing
(Dynamic)用于指定什么时候允许分片rebalancing
always
:总是允许rebalancing
indices_primaries_active
:只有当集群中的所有主分片都被分配后
indices_all_active
:(default)只有当集群中所有的分片(primaries and replicas)都被分配后
(Dynamic)用于控制集群范围(cluster wide)内分片平衡并发数,默认值是2。注意的是这个设置仅仅控制因为集群不平衡导致的分片重定位(shard relocating)的并发数。这个设置不会限制因 allocation filtering 和 forced awareness导致的分片重定位。
基于每个节点上分片的分配情况计算出一个weight来实现rebalancing,并且通过在节点之间移动分片来降低heavier节点的weight并且提高lighter节点的weight。当不存在可能使任何节点的权值与其他节点的权值更接近超过可配置阈值的分片移动时,集群是平衡的。下面的设置允许你控制计算的细节
(Dynamic)为节点上分配的分片总数定义一个weight因子。默认值是0.45f。提高这个值会使集群中所有节点的分片数量趋于均衡。
(Dynamic)为每一个索引的分片数量定义一个weight因子。默认值是0.55f。提高这个值会使集群中所有节点上的每一个索引的的分片数量趋于均衡。
(Dynamic)该值时候一个非负的浮点之后,Minimal optimization value of operations that should be performed。提高这个值将导致集群在优化分片平衡方面不那么积极(leess aggressive)。
NOTE:无论balancing算法的结果如何,rebalancing可能因为forced awareness或者allocation filtering而无法执行
基于磁盘的分片分配器能保证所有节点都有足够的磁盘空间而不用执行更多的分片移动。它基于一对阈值来分配分片:low wateremark 和 high watermark。主要的目的是保证在每一个节点不会超过high watermark,或者是暂时的超过(overage is temporary)。如果某个节点上超过了high watermark,那么Elasticsearch会通过把分片移动到集群中的其他节点来的方式来解决。
NOTE:节点上有时(from time to time)出现临时的超过high watermark是正常的
分配器总是尝试通过禁止往已经超过low watermark的节点分配更多分配的方式来让节点远离(clear of)high watermark。重要的是,如果所有的节点都已经超过了low watermark那么不会有新的分片会被分配并且Elasticsearch不会通过在节点间移动分片的方式来让磁盘使用率低于high watermark。你必须保证在你的集群中有足够的磁盘空间并且总存在一些低于low watermark的节点。
通过基于磁盘的分片分配器进行的分片移动必须满足(satisfy)其他的分片分配规则,例如 allocation filtering 和 forced awareness。如果这些规则过于严格,它们还可以防止碎片移动,以保持节点的磁盘使用在控制之下。如果你正在使用 data tiers,那么Elasticsearch会自动的应用分配过滤规则将每一个分配放到合适的数据层,这些规则意味着平衡器在每一层中独立工作。
如果某个节点填满磁盘的速度比Elasticsearch将分片移动到其他地方的速度还要快就会有磁盘被填满的风险。为了防止出现这个问题,万不得已的情况下( as a last resort),一旦磁盘使用达到flood-stage
watermark,Elasticsearch会阻塞受到影响的节点上的分片索引的写入。但仍然继续将分片移动到集群中的其他节点。当受到影响的节点上的磁盘使用降到high watermark,Elasticsearch会自动的移除write block。
TIP:集群中的节点各自使用容量不相同的磁盘空间是正常的。集群的balance取决与每一个节点上分片的数量以及分片中的索引。基于下面的两个理由,集群的balance既不会考虑分片的大小,也不会考虑每一个节点上磁盘可用的空间:
磁盘的使用随着时间发生变化。平衡不同节点的磁盘使用将会有很多更多的分片移动,perhaps even wastefully undoing earlier movements。移动一个分片会消耗例如I/O资源以及网络带宽,并且可能从文件系统缓存中换出(evict)数据。这些资源最好用于你的查询和索引。
集群中每一个节点有相同的磁盘使用在性能上通常没有有不同磁盘使用的性能高,只要所有的磁盘不是太满
你可以使用下面的设置控制基于磁盘的分配:
(Dynamic)默认值为true
。设置为false
则关闭基于磁盘的分配。
(Dynamic)控制磁盘使用量的水位下限(low watermark)。默认值为85%
。意味着Elasticsearch不会将分片分配到磁盘使用超过85%的节点上。该值也可以是一个字节单位的值(例如500mb
),使得当磁盘空间小于指定的值时就不让Elasticsearch分配分片到这个节点。这个设置不会影响新创建的索引的主分片,但是会组织副本分配的创建。
(Dynamic)控制磁盘使用量的水位上限。默认值为90%
,意味着Elasticsearch将对磁盘使用量超过90%的节点上的分片进行relocate。该值也可以是一个字节单位的值(跟low watermark类似)。使得当磁盘空间小于指定的值时就把该节点上的分片进行relocate。这个设置会影响所有分片的分配,无论之前是否已经分配。
(Static) 在更早的发布中,当做出分配决策时,对于单个数据节点的集群是不会考虑disk watermark的。在7.14之后被值为deprecated并且在8.0移除。现在这个设置唯一合法的值为true
。这个设置在未来的发布中移除。
(Dynamic)控制flood stage watermark。只要至少有一个节点超过该值,分配到这个节点的一个或者分片对应的索引会被Elasticsearch强制置为read-only index block(index.blocks.read_only_allow_delete
)。这个设置是防止节点发生磁盘空间不足最后的手段。当磁盘使用量降到high watermark后会自动释放index block。
NOTE:你不能在设置中混合使用比例值(percentage)和字节值(byte value)。要么所有的值都是比例值,要么都是字节值。这种强制性的要求使得Elasticsearch可以进行一致性的处理。另外要确保low disk threshold要低于high disk threshold,并且high disk threshold要低于flood stage threshold。
下面的例子中在索引my-index-000001
上重新设置read-only index block:
xxxxxxxxxx
41PUT /my-index-000001/_settings
2{
3 "index.blocks.read_only_allow_delete": null
4}
(Dynamic)用于专用的frozen node,控制flood stage watermark,默认值为95%
(Dynamic)用于专用的frozen node,控制flood stage watermark的head room。当cluster.routing.allocation.disk.watermark.flood_stage.frozen
没有显示设置时默认值为20GB。该值限制(cap)了专用的frozen node上磁盘的空闲量。
(Dynamic)Elasticsearch定时检查集群中每一个节点上磁盘使用情况的时间间隔。默认值为30s
。
NOTE:比例值说的是(refer to)已使用的磁盘空间,而字节值说的是剩余磁盘空间。这可能会让人疑惑,因为它弄反了高和低的含义。比如,设置low watermark为10GB,high watermark为5GB是合理的,反过来设置的话就不行
下面的例子讲low watermark的值设置为至少100gb,high watermark的值设置为至少50gb,flood stage watermark的值为10gb,并且每一分钟进行检查:
xxxxxxxxxx
91PUT _cluster/settings
2{
3 "persistent": {
4 "cluster.routing.allocation.disk.watermark.low": "100gb",
5 "cluster.routing.allocation.disk.watermark.high": "50gb",
6 "cluster.routing.allocation.disk.watermark.flood_stage": "10gb",
7 "cluster.info.update.interval": "1m"
8 }
9}
你可以自定义节点属性作为感知属性(awareness attributes)让Elasticsearch在分配分片时考虑你物理硬件的配置。如果Elasticsearch知道哪些节点在同一台物理机上、同一个机架(rack)、或者同一个区域,使得在发布主分片跟副本分片时能最低限度的降低丢失所有副本分片的风险。
当使用(Dynamic)的cluster.routing.allocation.awareness.attributes
的设置开启awareness attribute后,分片只会被分配到设置了awareness attributes的节点上。当你使用多个awareness attribute时,Elasticsearch在分配分片时会单独地(separately)考虑每一个attribute。
NOTE: attribute values的数量决定了每一个位置上副本分配的分配数量。如果在每一个位置上的节点数量是unbalanced并且有许多的副本,副本分片可能不会被分配
开启分片的分配awareness,需要:
使用一个自定义的节点属性来指定每个节点的位置。如果你想要Elasticsearch在不同的机架间发布分片,你可能需要在配置文件elasticsearch.yml
上设置一个名为rack_id
的属性。
xxxxxxxxxx
11node.attr.rack_id: rack_one
你也可以在启动的时候设置自定义的属性。
xxxxxxxxxx
11./bin/elasticsearch -Enode.attr.rack_id=rack_one
在每一个master-eligible node的配置文件elasticsearch.yml
上设置cluster.routing.allocation.awareness.attributes
,告诉Elasticsearch在分配分片的时候要考虑一个或者多个awareness attribute。
xxxxxxxxxx
11cluster.routing.allocation.awareness.attributes: rack_id
用逗号分隔多个属性。
你也可以使用cluster-update-settings API来设置或者更新集群的awareness attributes。
基于上述的配置例子,如果你启动了两个节点并且都设置node.attr.rack_id
为rack_one
并且为每个index设置5个主分片,每个主分片设置一个副本分片,那么这两个节点都包含所有的主分片以及副本分片。
如果你增加了两个节点并且都设置node.attr.rack_id
为rack_two
,Elasticsearch会把分片移动到新的节点,ensuring(if possible)相同的副本分片不会在相同的机架上。
如果rack_two
失败并关闭了它的两个节点,默认情况下,Elasticsearch会将丢失的副本分片分配给rack_one
中的节点。为了防止特定分片的多个副本被分配到相同的位置,可以启用forced awareness。
默认情况下,如果一个位置失败了(one location fails),Elasticsearch将缺失的分片分配到剩余的位置。可能所有的位置都有足够的资源来存放主分片跟副本分片,也有可能某个位置无法存储所有的分片。
为了防止某个位置因为失败事件(event of failure)而造成负载过高(overload),你可以设置cluster.routing.allocation.awareness.force
使得副本分片不会被分配直到其他位置可以被分配。
比如说,如果你有一个awareness attribute 名为zone
并且在两个节点分别配置zone1
跟zone2
,那么在只有一个zone可用的情况,你可以使用forced awareness来防止Elasticsearch分配副本分片。
xxxxxxxxxx
21cluster.routing.allocation.awareness.attributes: zone
2cluster.routing.allocation.awareness.force.zone.values: zone1,zone2
为awareness attribute指定所有可能的值。
基于上述的配置例子,如果启动了两个节点并且设置node.attr.zone
的值为zone1
并且为每个index设置5个分片,每个分片设置一个副本分片,那么Elasticsearch会创建索引并且分配5个主分片但是不会有副本分片。只有某个节点设置node.attr.zone
的值为zone2
才会分配副本分片。
你可以使用cluster-level shard allocation filters来控制Elasticsearch从任何索引分配分片的位置。结合per-index allocation filtering和allocation awareness来应用集群级别(cluster wide)的filter。
Shard allocation filters可以基于自定义的节点属性或者内建的属性:_name
, _host_ip
, _publish_ip
, _ip
, _host
,_id
和_tier
。
cluster.routing.allocation
设置是动态的Dynamic,允许将live indices从一组节点上移动到其他组。只有在不破坏路由约定(routing constraint)下才有可能重新分配分片,比如说不会将主分片和它的副本分片分配到同一个节点上。
最常用的cluster-level shard allocation filtering用例是当你想要结束(decommission)一个节点。要在关闭节点之前将分片移出节点,您可以创建一个过滤器,通过其 IP 地址排除该节点:
xxxxxxxxxx
61PUT _cluster/settings
2{
3 "persistent" : {
4 "cluster.routing.allocation.exclude._ip" : "10.0.0.1"
5 }
6}
(Dynamic)将分配分片到一个节点,这个节点的{attribute}
至少是用逗号隔开的多个属性中的一个。
(Dynamic)只将分片分配到一个节点,这个节点的{attribute}
包含所有用逗号隔开的多个属性。
(Dynamic)不将分片分配到一个节点,这个节点的{attribute}
包含用逗号隔开的多个属性中的任意一个。
cluster allocation settings支持下面的内建属性:
_name | 根据node name匹配节点 |
---|---|
_host_ip | 根据host IP 地址(hostname关联的IP)匹配节点 |
_publish_ip | 根据发布的IP地址匹配节点 |
_ip | 根据_host_ip或者_publish_ip匹配节点 |
_host | 根据hostname匹配节点 |
_id | 根据node id匹配节点 |
_tier | 根据节点的data tier角色匹配节点 |
NOTE:
_tier
的过滤基于 node roles,只有部分角色是 data tier 角色,并且generic data role将会匹配任何的tier filtering。a subset of roles that are data tier roles, but the generic data role will match any tier filtering.
在指定attribute values时可以使用通配符,例如:
xxxxxxxxxx
61PUT _cluster/settings
2{
3 "persistent": {
4 "cluster.routing.allocation.exclude._ip": "192.168.2.*"
5 }
6}
通过下面的设置可以将整个集群设置为read-only:
(Dynamic) 让整个集群read only(索引不支持写操作),metadata不允许更改(创建或者删除索引)
(Dynamic) 与cluster.blocks.read_only
一样,但是允许删除索引来释放资源。
WARNING: 不要依赖这些设置来防止集群发生变更。任何有cluster-update-settings API 访问权限的用户都可以让集群再次read-write
基于集群中的节点数量,集群中分片的数量有一个soft limit。这是为了防止可能无意中破坏集群稳定性的操作。
IMPORTANT:这个限制作为一个安全网(safety net),不是一个推荐的大小。你集群中可以安全的支持准确的分片数量取决于你的硬件配置跟工作负载,但是在大部分case下,这个limit应该还不错,因为默认的limit是非常大的。
如果一个操作,比如创建新的索引,恢复snapshot index,或者打开一个关闭的索引会导致集群中的分片数量超过限制。那这个操作会失败并且给出shard limit的错误。
如果由于node membership的变化或者设置的变更使得集群已经超过了限制,所有创建或者打开索引的操作都会失败直到下文中将介绍的提高limit或者关闭删除一些索引使得分片的数量降到了limit以下。
对于normal indices(non-frozen),每一个non-frozen data node上cluster shard limit的默认值是1000,对于frozen indices,每一个frozen data node上的默认值是3000。所有打开的索引的主分片跟副本分片的数量都会纳入到统计中(count toward the limit),包括未分配的分片。例如5个主分片和2个副本的数量为15个分片。关闭的索引不会参与分片的统计。
你可以使用下面的方式动态的调整cluster shard limit:
(Dynamic) 限制集群中主分片跟副本分片的总数量。Elasticsearch使用下面的公式统计limit:
cluster.max_shards_per_node * number of non-frozen data nodes
关闭的索引不会纳入到统计中。默认是1000
。没有data node的集群是没有限制的。
超过上限后,Elasticsearch会reject创建更多分片的请求。比如集群的cluster.max_shards_per_node
的值是100
,并且三个data node就有300
的分片数量限制。如果集群中已经包含了296个分片,Elasticsearch会reject增加5个或者更多分片数量的请求。
注意的是frozen shard有他们自己独立的限制。
(Dynamic) 限制集群中主分片跟replica frozen shard的总数量。Elasticsearch使用下面的公式统计limit:
cluster.max_shards_per_node * number of frozen data nodes
关闭的索引不会纳入到统计中。默认是3000
。没有frozen data node的集群是没有限制的。
超过上限后,Elasticsearch会reject创建更多frozen shard的请求。比如集群的cluster.max_shards_per_node.frozen
的值是100
,并且三个frozen data node就有300
的分片数量限制。如果集群中已经包含了296个分片,Elasticsearch会reject增加5个或者更多frozen shard数量的请求。
NOTE: These setting do not limit shards for individual nodes. 可以使用设置cluster.routing.allocation.total_shards_per_node来限制每一个节点上的分片数量。
可以通过Cluster Settings API来存储以及查询用户自定义的集群元信息(User-defined cluster metadata)。可以用来存储任意的(arbitrary),很少更改(infrequently-changing)的关于集群的信息,而不需要创建索引来存储这些信息。使用以cluster.metadata
为前缀的任意的key来存储信息。例如,在cluster.metadata.administrator
这个key下存储管理员的email地址,如下所示:
xxxxxxxxxx
61PUT /_cluster/settings
2{
3 "persistent": {
4 "cluster.metadata.administrator": "sysadmin@example.com"
5 }
6}
IMPORTANT: User-defined cluster metadata不要存储敏感的或者机密信息。任何人都可以通过Cluster Get Settings API访问存储在User-defined cluster metadata的信息,并且会被记录在Elasticsearch日志中。
集群状态(cluster state)维护者index tombstone来显示的告知(denote)被删除的索引。集群状态维护tombstone的数量,通过下面的设置来进行控制:
(Static)当发生删除时,Index tombstones会阻止不属于集群的节点加入集群并重新导入索引,就好像delete was never issued。为了防止增长的太大,我们只保留最新的cluster.indices.tombstones.size
数量的删除,默认值是500。You can increase it if you expect nodes to be absent from the cluster and miss more than 500 deletes. We think that is rare, thus the default. Tombstones don’t take up much space, but we also think that a number like 50,000 is probably too big.
如果 Elasticsearch 遇到当前集群状态中不存在的索引数据,则这些索引被认为是dangling。 例如,如果你在 Elasticsearch 节点离线时删除超过 cluster.indices.tombstones.size
的索引,就会发生这种情况。
你可以使用Dangling indices API来进行管理。
这个设置用来控制日志,使用logger.
为前缀的key来动态的更新。发布下面的请求(issue this request)来提高indices.recovery
模块的日志等级为DEBUG
:
xxxxxxxxxx
61PUT /_cluster/settings
2{
3 "persistent": {
4 "logger.org.elasticsearch.indices.recovery": "DEBUG"
5 }
6}
Plugin可以创建一系列称为persistent task的任务。这些任务通常是long-lived并且存储在cluster state中,并且允许在一次full cluster restart后恢复(revive)这些任务。
每一次创建一个persistent task时,master node会负责将任务分配到集群中的一个节点。然后被分配的节点会pick up这个任务然后在本地执行。通过下面的设置来控制被分配的persistent task的运行:
(Dynamic)开启或者关闭persistent task的分配:
all - (default) 允许persistent task被分配到节点
none - 不允许分配任何类型的persistent task
这个设置不会影响已经执行的persistent task。只有最新创建的,或者必须要重新被分配的persistent task才会收到这个设置的影响。
(Dynamic)master node会自动的检查在cluster state发生重大变化(change significantly)后persistent tast是否需要被分配。然而,也会有其他的一些因素,比如说memory usage,这个会影响persistent task能否被分配但这不会引起cluster state的变更。这个设置控制了检查的间隔。默认是30秒。最小允许的时间为10秒。
(8.2)link
可以使用cluster update settings API动态更新集群中的CCR(cross-cluster replication)设置。
下面的设置可以用于在remote recoveries中限制数据传输速率:
用来限制每一个节点上inbound和outbound remote recovery traffic。由于这个设置是作用到每一个节点上,但是可能存在许多的节点并发的执行remote recoveries,remote recovery占用的流量可能比这个限制高。如果这个值设置的太高,那么会存在这么一种风险,即正在进行中的recoveries会过度消费带宽 ,使得集群变得不稳定。这个设置应该同时被leader和follower clusters使用。例如,如果在leader上设置了20mb
,leader将只能发送20mb/s
到follower,即使follower可以达到60mb/s
。默认值为40mb
。
下面的专家级设置(expert settings)用于管理remote recoveries时的资源消费。
控制每个recovery中并发请求文件块(file chunk)的数量。由于多个remote recoveries已经在并发运行,增加这个专家级设置可能只有助于没有达到总的inbound and outbound remote recovery traffic的单个分片的remote recovery,即上文中的ccr.indices.recovery.max_bytes_per_sec
。ccr.indices.recovery.max_concurrent_file_chunks
的默认值为5
。允许最大值为10
。
控制在文件传输时,follower请求的文件块的大小。默认值为1mb
。
控制recovery的活跃(activity)超时时间。这个超时时间主要是应用在leader集群上。在处理recovery期间,leader cluster必须打开内存资源提供数据给follower。如果leader在周期时间内没有接收到follower的接收请求,leader会关闭资源。默认值为60s
。
控制在remote recovery处理期间每一个网络请求的超时时间。某个单独的动作(individual action)超时会导致recovery失败。默认值为60s
。
Discovery and cluster formation受到下面设置的影响:
(Static))提供集群中master-eligible node的地址列表。可以是单个包含地址,用逗号隔开的字符串。每一个地址有host:port
或者host
的格式。host
可以是hostname(可以用DNS解析)、IPv4地址、IPv6地址。IPv6地址必须用{}包裹。如果hostname用DNS解析出多个地址,Elasticsearch会使用所有的地址。DNS基于JVM DNS caching进行查找(lookup)。如果没有指定port
,会有序检查下面的设置来找到port
:
transport.profiles.default.port
transport.port
如果没有设置上面的配置,则port
的默认值为9300
。discovery.seed_hosts
的默认值为["127.0.0.1", "[::1]"]
。见discovery.seed_hosts。
(Static))指定seed hosts provider的类型,用于获取启动发现程序(discovery process)时需要用到的seed nodes地址。默认情况为settings-based seed hosts provider,它包含了discovery.seed_hosts
中的seed node 地址。
(Static))指定Elasticsearch是否形成一个多节点的(multiple-node)的集群,默认值为multi-node
,意味着Elasticsearch在形成一个集群时会发现其他节点并且允许其他节点随后加入到这个集群。如果设置为single-node
,Elasticsearch会形成一个单节点(single-node)集群并且suppresses the timeout set by cluster.publish.timeout
。当你想要使用这个设置的时候,见Single-node discovery了解更多的信息
(Static))在全新的集群中初始化master-eligible node集合。默认情况下是空值,意味着这个节点想要加入到一个引导后(bootstrapped)的集群。集群一旦形成后需要移除这个设置。当重启一个节点或者添加一个新的节点到现有的集群中时不要使用这个设置。见cluster.initial_master_nodes。
Discovery and cluster formation受到下面专家级设置(expert settings)的影响,当然我们不推荐修改这些设置的默认值。
WARNING:如果你调整了集群中的这些设置,可能会无法正确的形成一个集群或者可能集群变得不稳定,或者无法处理(intolerant)对于一些故障。
(Static))尝试形成一个集群时,多长时间后仍然没有形成集群,开始记录未形成集群的警告日志的设置。默认值为10s
。如果在discovery.cluster_formation_warning_timeout
的时间内没有形成一个集群,那节点会记录一个包含master not discovered
的warnning message,它描述了当前discovery process当前的状态。
(Static))一个节点尝试新一轮discovery的时间间隔。默认值为1s
。
(Static))尝试连接每一个地址的连接等待时间。默认值为30s
。
(Static))尝试通过handshake识别remote node的等待时间。默认值为30s
(Static))在认为请求失败时,询问其peer后的等待时间。默认值为3s
。
(Static))节点尝试discover它的peers并开始记录为什么尝试连接失败的verbose message的时间。默认值为3m
。
(Static))DNS并发解析seed node的地址时允许的并发量。默认值为10
。
(Static))DNS解析seed note的地址的超时时间。默认值为5s
。
(Dynamic)控制voting configuration是否自动的去除(shed)不能担任voting的节点(departed node),只要它至少还包含3个节点。默认值为true
。如果设置为false
。voting configuration不会自动的进行收缩,你必须通过voting configuration exclusions API手动的移除不能担任voting的节点(departed node)。
(Static)) (未完成)
(8.2)link
field data cache中包含了field data和global ordinals,它们都是用来让某些域能够用于聚合。由于是on-heap的数据结构,所以很有必要监控缓存的使用情况。
构建cache中实体(entities)的开销是很昂贵的,所以默认情况下会保留载入到内存的entities。默认的cache大小是没有限制的,cache大小会不断增大直到达到field data circuit breaker设定的上限。这种行为可以配置。
如果设置了cache大小的上限,cache将会清除cache中最近更新的实体(If the cache size limit is set, the cache will begin clearing the least-recently-updated entries in the cache)。这个设置会自动的避免circuit breaker limit,代价就是需要重新构建cache。
如果达到了circuit breaker limit,后续会增加cache大小的请求将被阻止。在这种情况下你必须要手动clear the cache。
(Static)) field data cache的最大值。比如节点堆空间大小的38%
,或者是一个absolute value,12GB
。默认是没有限制。如果选择设置这个值,这个值应该小于Field data circuit breaker limit。
你可以使用nodes stats API和cat fielddata API来监控filed data的内存使用情况以及 field data circuit breaker。
(8.2)link
indexing buffer用来缓存新添加的文档,当缓冲区满后,缓存中的文档会被写入到一个段中并且存放到磁盘上。Indexing buffer的大小被节点上的所有分片共享。
下面的设置都是静态的必须在集群中的每一个节点上配置:
(Static)可以是百分比或者是字节单位的数值。默认是10%
意味着堆内存的10%会被分配给节点用于Indexing buffer,并且被节点上所有的分片共享。
(Static)如果index_buffer_size
指定为百分比,那这个设置用来指定为一个绝对最小值(absolute minimum)。默认是是48m
。
(Static)如果index_buffer_size
指定为百分比,那这个设置用来指定为一个绝对最大值(absolute maximum)。默认是无限制的。
当一个节点加入到集群,如果它发现本地数据目录中存在一些分片,这些分片在集群中的其他节点上不存在,那么就认为这些分片属于"dangling" index。你可以使用Dangling indices API列出,导入或者删除dangling index。
(8.2)link
任何时候在你启动了一个Elasticsearch的实例时,即你正在启动一个节点(Node)。相互连接的节点集合成为一个集群(cluster)。如果你运行了 一个单个节点的Elasticsearch,那么你拥有一个只有一个节点的集群。
默认情况下,集群中的每个节点都可以处理 HTTP and transport的传输。transport layer只用来处理节点之间的交互,HTTP layer用于REST clients 。
所有的节点都知道集群中的其他节点并且可以转发客户端的请求到合适的节点。
你可以在elasticsearch.yml
中设置node.roles
来定义一个节点的角色。如果你设置了node.roles
,这个节点只会被分配为你指定的角色。如果你不指定node.roles
,这个节点会被分配为下面的角色:
master
data
data_content
data_hot
data_warm
data_cold
data_frozen
ingest
ml
remote_cluster_client
transform
IMPORTANT:如果你设置了
node.roles
,你要保证你的集群需要你指定的这些角色。每一个集群需要有下面的角色:
master
(data_content和data_hot) 或者 data
一些Elastic Stack 功能同样要求指定下面的节点角色:
跨集群搜索(Cross-cluster search)和跨集群副本(Cross-cluster replication)需要
remote_cluster_client
角色Stack Monitoring和ingest pipeline需要
ingest
角色Fleet,Elastic Security应用,和transforms需要
transform
角色。remote_cluster_client
角色同样需要用于这些功能中的cross-cluster searchMachine learning功能,比如异常检测(anomaly detection)需要
ml
角色
随着集群的增长,特别是集群中有大规模的machine learning任务、continuous transforms,我们建议从专用的data node、machine learning node、transform node中分离出master-eligible节点。
Master-eligible node | 拥有master 角色的节点,使得节点有资格被选举为master node来控制整个集群 |
---|---|
Data node | 拥有data 角色的节点,data node保留数据并且执行相关操作例如CRUD、查询、聚合。一个拥有data 角色的节点可以添加任何其他特定的数据节点角色,例如hot 、warm等 |
Ingest node | 拥有ingest 角色的节点,ingest node可以对文档进行ingest pipeline使得可以在索引前transform或者丰富文档。对于繁重的ingest,使用专用的ingest node并且让拥有master 或者data 角色的节点不要有ingest 角色 |
Remote-eligible node | 拥有remote_cluster_client 角色的节点,使得这个节点有资格成为一个remote client |
Machine learning node | 拥有ml 角色的节点,如果你想要使用machine learning功能,你的集群中至少要有一个machine learning node。见Machine learning settings和Machine learning in the Elastic Stack了解更多信息 |
Transform node | 拥有transform 角色的节点。如果想要使用transform,你的集群中至少要有一个transform node。见Transforms settings和Transforming data了解更多信息 |
NOTE:Coordinating node 一些像查询请求或者块索引(bulk-indeing)的请求可能涉及不同data node上的数据。一次查询请求,例如,搜索请求分两个阶段执行,由接收客户端请求的节点进行协调 - coordinating node。
在scatter阶段,coordinating node将请求转发给持有数据的数据节点。 每个数据节点在本地执行请求并将其结果返回给coordinating node。 在收集(gather)阶段,协调节点将每个数据节点的结果减少为单个全局结果集。
每个节点都隐含的是一个coordinating node。 这意味着通过设置
node.roles
为空的角色列表的节点将作为coordinating node,并且不能被关闭这种设定。 因此,这样的节点需要有足够的内存和 CPU 才能处理收集阶段。
master node负责轻量级(lightweight)的集群范围(cluster-wide)的一些工作,比如创建、删除一个索引,跟踪哪些节点是集群的一部分以及决定给哪里节点分配分片。稳定的master node对于集群的健康是十分重要的。
一个不是voting-only的master-eligible node会在master election process中被选为master node。
IMPORTANT: master node必须有一个
path.data
目录,其内容在重启后仍然存在,跟data node一样,这个目录中存放了集群的元数据(cluster metadata)。集群元数据描述了如何读取存储在data node上的数据,所以如果丢失了集群元数据就无法读取data node上的数据。
满足被选举为master的节点为了能完成它的职责所需要的资源对于集群的健康是十分重要的。如果被选举为master的节点因为其他的工作导致超负荷了,那么集群将无法较好的运行。避免master node工作超负荷最可靠的方法就是将所有master-eligible node只配置为master
角色,让它们作为专用的master-eligible node(dedicated master-eligible node),让它们集中做好管理集群的工作。Master-eligible node可以跟coordinating nodes一样将客户端的请求路由到集群中的其他节点,但是你不应该让专用的master-eligible node做这些事情。
在一些小规模或者轻负载(lightly-loaded)的集群中,如果master-eligible node有其他的角色和职责也可以正常的运行,但是,一旦集群中包含多个节点,通常使用专用的master-eligible node是有意义的。
通过设置下面的配置来创建一个专用的master-eligible节点:
xxxxxxxxxx
11node.roles: [ master ]
voting-only master-eligible node是会参与master elections的节点,但是不会成为集群的master节点。特别在于一个voting-only node可以成为选举过程中的tiebreaker。
使用"master-eligible"这个词来描述一个voting-only node看起来有点让人困惑,因为这种节点是完全没资格成为master节点的。使用这个术语是因为历史的原因(This terminology is an unfortunate consequence of history):master-eligible node是那些参与选举、集群状态发布(cluster state publication)期间执行一些任务的节点,而voting-only node有着相同的工作职责(responsibility)只是他们不会被选举为master节点。
通过添加master
和voting_only
角色来配置一个master-eligible node为voting-only node。下面的例子创建了一个voting-onyl data node:
xxxxxxxxxx
11node.roles: [ data, master, voting_only ]
IMPORTANT:只有拥有
master
角色的节点才可以标记为拥有voting_only
角色。
高可用(HA:high availability)的集群要求至少有三个master-eligible node,他们中的至少两个节点不是voting-only node。这样的集群才能够在其中一个节点发生故障后选出一个master节点。
由于voting-only node不会被选举为master节点,所以相较于真正的master node,它们需要较少的堆以及较低性能的CPU。然而所有的master-eligible node,包括voting-only node,相较于集群中的其他节点,它们需要相当快速的持久存储以及一个可靠的低延迟的网络连接,因为它们处于publishing cluster state updates的关键路径(critical path)上。
Voting-only master-eligible node在集群中可能被分配其他的角色。比如说一个节点同时是data node或者Voting-only master-eligible node。一个专用的voting-only master-eligible node 在集群中是不会有其他的角色的。通过下面的方式来创建一个专用的voting-only master-eligible nodes:
xxxxxxxxxx
11node.roles: [ master, voting_only ]
data note保留了你索引的文档的分片。data note处理像CRUD、查询、聚合的操作。这些操作有I/O-, memory-, and CPU-intensive。监控这些资源以及工作负载大后增加更多的data node是非常重要的。
拥有专用的data node最主要的好处是将master和data角色分开出来。
通过下面的方式创建一个专用的data node:
xxxxxxxxxx
11node.roles: [ data ]
在多层部署架构(multi-tier)中,你可以根据为data node分配不同数据层对应的数据角色(data role):data_content
,data_hot
, data_warm
, data_cold
, 或者data_frozen
。一个节点可以属于多个层,但是已经拥有一个指定数据角色的节点不能有通用的data
角色(generic data role)。
Content data node属于content tier的一部分。存储在content tier上的数据通常是iterm的集合比如说产品目录(product catalog)或者文章归档(article archive)。跟时序数据不同的是,这些内容的价值随着时间的流逝相对保持不变的,所以根据这些数据的寿命(age)将它们移到性能不同的数据层是不合理的。Content data通常有长时间保留(retention)的要求,并且也希望无论这些数据的寿命的长短,总是能很快的检索到。
Content tier node会为查询性能做优化-优先优化IO吞吐使得可以处理复杂的查询,聚合并且能很快的返回结果。同时这类节点也用来索引,content data通常没有例如log和metric这种时序数据一样高的ingest rate。从弹性的角度(resiliency perspective)看,当前层的索引应该配置为使用一个或者多个副本(replica)。
Content tier是必须要有的(required)。系统索引以及其他不是data stream的索引都会被自动分配到content tier。
通过下面的方式创建一个专用的content node:
xxxxxxxxxx
11node.roles: [ data_content ]
hot data node是 hot tier的一部分。hot tier是Elasticsearch中时序数据的入口点(entry point),并且保留最近,最频繁搜索的时序数据。hot tier节点上的读写速度都需要很快,要求更多的硬件资源和更快的存储(SSDs)。出于弹性目的,hot tier上的索引应该配置一个或多个副本分片。
hot tier是必须要有的。data stream中新的索引会被自动分配到hot tier。
通过下面的方式创建一个专用的hot node:
xxxxxxxxxx
11node.roles: [ data_hot ]
warm data node是warm tie的一部分。一旦时序数据的访问频率比最近索引的数据(recently-indexed data)低了,这些数据就可以移到warm tier。warm tier通常保留最近几周的数据。允许更新数据,但是infrequent。warm tier节点不需要像hot tier一样的快。出于弹性目的,warm tier上的索引应该配置一个或多个副本分片。
通过下面的方式创建一个专用的warm node:
xxxxxxxxxx
11node.roles: [ data_warm ]
cold data node是cold tier的一部分。当你不再经常(regular)搜索时序数据了,那可以将它们从warm tier移到cold tier。数据仍然可以被搜索到,在这一层的通常会被优化成较低的存储开销而不是查询速度。
为了更好的节省存储(storage saveing),你可以在cold tier保留fully mounted indices的searchable snapshots。跟普通索引(regular index)不同的是,这些fully mounted indices不需要副本分片来满足可靠性(reliability),一旦出现失败事件,可以从底层(underlying)snapshot中恢复。这样可以潜在的减少一般的本地数据存储开销。snapshot仓库要求在cold tier使用fully mounted indices。Fully mounted indices只允许读取,不能修改。
另外你可以使用cold tier存储普通索引并且使用副本分片的方式,而不是使用searchable snapshot,这样会帮你在较低成本的硬件上存储较老的索引,但是相较于warm tier不会降低磁盘空间。
通过下面的方式创建一个专用的cold node:
xxxxxxxxxx
11node.roles: [ data_cold ]
frozen data node是frozen tier的一部分。一旦数据不需要或者很少(rare)被查询,也许就可以将数据从cold tier移到frozen tier,where it stays for the rest of its life。
frozen tier需要用到snapshot repository。frozen tier使用partially mounted indices的方式存储以及从snapshot repository中载入数据。这样仍然可以让你搜索frozen数据并且可以减少本地储存(local storage)和操作开销(operation cost)。因为Elasticsearch必须有时从snapshot repository中提取(fetch)数据,在frozen tier的查询速度通常比cold tier慢。
Ingest node可以执行pre-processing pipelines。由一个或者多个ingest processor组成。基于ingest processor执行的操作类型以及需要的资源,拥有一个专用的ingest node还是有意义的,使得这个节点只运行指定的任务。
通过下面的方式创建一个专用的Ingest node:
xxxxxxxxxx
11node.roles: [ ingest ]
如果你的节点不需要(take away)处理master职责(duty)、保留数据、pre-process文档的能力,那么你还剩下一个coordinating only node,只能处理路由请求、查询的reduce phase、以及分布式的块索引(bulk Indexing)。本质上coordinating only node表现为像一个智能的负载均衡节点。
在大规模的集群中将coordinating node角色从data node和master-eligible node中剥离(offload)出来能体现coordinating only nodes的益处。这些节点加入到集群中并且接收完整的cluster state,就像每一个其他的节点一样,他们使用cluster state将请求路由到合适的地方。
WARNING:集群中添加太多的coordinating only nodes会增加整个集群的负担(burden),因为被选举为master的节点必须等待从每一个节点更新后的cluster state的回应。不能过度夸大(overstate)coordinating only node的益处-data node也可以实现跟coordinating only nodes相同的目的(same purpose)
通过下面的方式创建一个专用的coordinating node:
xxxxxxxxxx
11node.roles: [ ]
一个remote-eligible node扮演一个cross-cluster client的角色以及连接remote clusters。一旦连接后,你可以使用cross-cluster search搜索远端的集群。你可以使用cross-cluster replication在集群间同步数据。
xxxxxxxxxx
11node.roles: [ remote_cluster_client ]
Machine learning node运行任务并且处理machine learning API的请求。见Machine learning settings查看更多的信息
通过下面的方式创建一个专用的machine learning node:
xxxxxxxxxx
11node.roles: [ ml, remote_cluster_client]
remote_cluster_client
是可选的,但是强烈建议配置进去。否则当使用machine learning jobs 或者 datafeed时,cross-cluster search会失败。如果在你的异常检测任务中使用corss-cluster search,在所有的master-eligible node上同样需要remote_cluster_client
这个角色。否则 datafeed无法开始,见Remote-eligible node。
Transform node运行transforms并且处理transform API的请求。见Transforms settings。
通过下面的方式创建一个专用的transform node:
xxxxxxxxxx
11node.roles: [ transform, remote_cluster_client ]
remote_cluster_client
是可选的,但是强烈建议配置进去。否则当使用transforms时,cross-cluster search会失败。见Remote-eligible node。
每一个data node在磁盘上维护下面的数据:
分配给节点的每一个分片的分片数据
分配在这个节点的每一个分片的索引元数据(index metadata),以及
集群范围(cluster-wide)的元数据,例如settings和index templates
同样的,每一个master-eligible node在磁盘上维护下面的数据:
集群中每一个索引的索引元数据,以及
集群范围(cluster-wide)的元数据,例如settings和index templates
每一个节点在启动时会检查数据路径的内容。如果发现了非预期(unexpected)的数据,节点将拒绝启动。这样就可以避免导入会导致红色的集群健康的unwanted dangling indices。更准确的说,如果在启动时发现磁盘上有分片数据但是这个节点没有data
角色,那么这个节点不会启动。如果在启动时发现磁盘上有索引元数据但是这个节点没有data
和master
角色,那么这个节点不会启动。
可以通过更改elasticsearch.yml
然后重启节点来修改节点的角色。这就是众所周知的 repurposing
一个节点。为了能满足上文中描述的对非预期的检查,在启动没有data
或者master
角色的节点前,你必须执行一些额外的步骤来为repurposing做准备。
如果你想要通过repurposing来移除一个data note的data
角色,你应该先通过allocation filter安全的将节点上的所有分片数据迁移到集群中的其他节点上。
如果你想要通过repurposing来移除data
和master
节点,最简单的办法是启动一个全新的节点,这个节点设置一个空的数据路径以及想要的节点角色。你会发现使用allocation filter可以安全的先将分片数据迁移到集群中的其他地方
如果没有办法按照这些额外的步骤实现你的目的,你可以使用elasticsearch-node repurpose工具来删除阻止节点启动的多余的数据(excess data)。
每个data node、master-eligible node都要访问一个数据目录,这个目录中存放了分片、索引和集群元数据。path.data
的默认值是$ES_HOME/data
但是可以在elasticsearch.yml
中配置一个全路径或者一个相对于$ES_HOME
的相对路径:
xxxxxxxxxx
11path.data: /var/elasticsearch/data
跟其他的节点设置一样,可以在命令行上指定:
xxxxxxxxxx
11./bin/elasticsearch -Epath.data=/var/elasticsearch/data
path.data
的内容在启动时必须存在,因为这是你数据存储的位置。Elasticsearch 要求文件系统像由本地磁盘支持一样运行,但这意味着只要远程存储正常运行,它就可以在配置正确的远程块设备(例如 SAN)和远程文件系统(例如 NFS)上正常工作,与本地存储没有什么不同。你可以在同一个文件系统上运行多个Elasticsearch节点,但是每个节点要有自己的数据路径。
Elasticsearch集群的性能常常受制于底层存储的性能,所以你必须保证你的存储能有可以接受的性能范围内。一些远程存储的性能很差,尤其是在 Elasticsearch 施加(impose)的那种负载下,所以在使用特定的存储架构之前,请确保仔细地对你的系统进行基准测试。
TIP:如果使用了
.zip
或者.tar.gz
的发行版,path.data
的值应该设置到Elasticsearch home目录以外的路径上,这样删除home目录时不会删除你的数据!RPM和Debian发行版已经为你做了这些工作。
IMPORTANT:不要修改数据目录中的任何东西或者运行可能会影响这个目录中内容的程序。如果一些不是Elasticsearch的操作修改了数据目录的内容,那么Elasticsearch可能会发生故障,报告出corruption或者其他data inconsistencies,或者工作正常但是轻微的丢失了一些你的数据。不要尝试做文件系统级别的数据目录的备份。因为没有可用的方法来恢复这类备份。而是应该用 Snapshot and restore做安全的备份。不要在数据目录做病毒扫描,病毒扫描会使得Elasticsearch不能正确的工作并且可能会修改数据目录的内容。数据目录不包含可执行文件,因此病毒扫描只会发现误报
更多的跟节点相关的设置可以在Configuring Elasticsearch 和 Important Elasticsearch configuration找到,包括:
(8.2)link
filter context中的查询结果缓存在node query cache中使得可以快速的查询,这属于每个节点上的查询缓存(query cache),由所有的分片共享。缓存使用了LRU eviction policy:当缓存满了以后,最近最少使用的查询结果会被踢出(evict),为新的查询查询让路。你不能查看(inspect)查询缓存的内容。
Term query以及在filter context使用外的查询没有缓存资格(eligible)。
默认情况下,缓存保留最多10000个query,以及占用最多10%的总内存。若要判断某个query是否有资格被缓存,Elasticsearch维护了一个query history来track occurrence。
缓存在每个段上进行,并且段中至少包含10000篇文档并且每个段中的文档数量至少是分片中文档总数的3%。由于是基于段的缓存,因此段的合并会使缓存的查询失效。
下面的设置是static
并且必须在集群中每个data node上配置:
(Static)为filter cache控制内存大小。可以是一个百分比的值,比如5%或者一个精确值,例如512mb
。默认值为10%
。
下面的设置属于index setting,可以在每一个索引上配置。只能在索引创建时或者一个closed index上设置。
(Static)控制是否开启查询缓存。可以是true
(默认值)或者false
。
(8.2)link
下面的expert setting用来管理全局的查询和聚合限制。
(Static integer)一个查询能包含的clause的最大数量。默认值为4096
。
这个设置限制了一颗query tree能包含的clause的最大数量。4096这个默认值已经是非常高了,通常来说该值是够用的。这个限制会作用于重写query(rewrite query),所以不仅仅是bool
query,所有会重写为bool query的query,例如fuzzy
query,都会有较高数量的clause。这个限制的目的是防止查询的范围变得很大,占用过多的CPU和内存。如果你一定要提高这个值,保证你已经竭尽全力尝试了所有其他的选项,否则就不要这么做。较高的值会导致性能降低以及内存问题,特别是在负载高或者资源较少的集群上。
Elasticsearch提供了一些工具来防止遇到这个clause数量上限的问题,例如在terms query中,它允许查询许多不一样的值,但是它只作为一个clause。或者是带有index_prefixes选项的text域,它会执行prefix query,这个query会膨胀为较高数量的term,但是只作为一个term query。
(Dynamic,integer)在一次响应中,aggregation buckets 的最大分桶数量。默认值为65535。
尝试返回超过这个限制的请求会返回一个错误。
(Static integer)bool query的最大深度。默认值为20
。
这个设置限制了bool query的嵌套深度。深度大的bool query可能会导致stack overflow。
(8.2)link
当一个查询请求运行在一个或者多个索引上时,每一个参与的分片会在本地执行查询然后将结果返回到coordinating note,节点会结合(combine)分片级别(shard-level)的结果到一个"全局的"的结果集中。
分片层的请求缓存模块会在每一个分片上缓存本地的结果。这允许经常使用(并且可能很重)的搜索请求几乎立即返回结果。请求缓存(request cache)非常适用于日志用例,因为这类数据只有最近的索引会持续更新,从旧的索引中获取的结果可以直接从缓存中返回。
IMPORTANT:默认情况下,请求缓存在
size=0
时仅仅缓存查询请求的结果。所以不会缓存hits
,但是它会缓存hits.total
, aggregations以及suggestions。大多数使用
now
(见 Date Math)的请求不能被缓存。使用脚本的查询使用了一些不确定的API调用不会被缓存,比如说
Math.random()
或者new Date()
。
The cache is smart。它可以跟非缓存的查询一样的近实时查询。
当分片refresh后文档发生了变更或者当你更新了mapping时,缓存的结果会自动的被废止。换句话说,你总是可以从缓存中获得与未缓存搜索请求相同的结果。
refresh的间隔时间越长意味着缓存的结果保留时间越长,即使文档已经发生了变化。如果缓存满了,基于LRU(least recently used)机制来丢弃缓存。
可以通过clear-cache API手动将缓存置为过期的(expired):
xxxxxxxxxx
11POST /my-index-000001,my-index-000002/_cache/clear?request=true
缓存默认开启,可以在创建一个新的索引时来关闭缓存:
xxxxxxxxxx
61PUT /my-index-000001
2{
3 "settings": {
4 "index.requests.cache.enable": false
5 }
6}
可以通过update-settings API来手动的开启或关闭缓存:
xxxxxxxxxx
21PUT /my-index-000001/_settings
2{ "index.requests.cache.enable": true }
request_cache
这个query-string参数可以用于在每一次请求中来开启或关闭缓存。如果设置了这个参数,会覆盖索引层(index-levele)的设置:
xxxxxxxxxx
111GET /my-index-000001/_search?request_cache=true
2{
3 "size": 0,
4 "aggs": {
5 "popular_colors": {
6 "terms": {
7 "field": "colors"
8 }
9 }
10 }
11}
请求中的size
如果大于0的话则不会缓存即使在索引设置中开启了缓存。要缓存这些请求,你需要使用的query-string参数。
使用完整的JSON计算出的hash值作为cache key。这意味着如果JSON发生了变更,比如说key的先后顺序发生了变化,那么对应的cache key就无法被识别。
TIP:大多数 JSON 库都支持规范模式(canonical mode),可确保 JSON的key始终以相同的顺序发出。这种规范模式可以在应用程序中使用,以确保始终以相同的方式序列化请求。
缓存在节点层进行管理,缓存大小的最大值默认是堆内存的1%。可以通过config/elasticsearch.yml
修改:
xxxxxxxxxx
11indices.requests.cache.size: 2%
同样的你可以使用indices.requests.cache.expire
为缓存结果设置一个TTL,但是并没有理由要这么做。因为过时的结果(stale result)会在refresh后自动的废止。这个设置只是为了completeness(This setting is provided for completeness' sake only)。
缓存的大小(字节)和evictions的数量可以通过indices-stats接口来查看:
xxxxxxxxxx
11GET /_stats/request_cache?human
或者通过nodes-stats接口查看:
xxxxxxxxxx
11GET /_nodes/stats/indices/request_cache?human
(8.2)link
一个节点会使用多个线程池来管理内存消费(memory consumption)。许多的线程池使用队列hold住pending中的请求而不是丢弃。
节点中有很多的线程池,下面介绍主要的几个线程池:
用于一般的操作(例如background node discovery)。线程池类型是scaling。
用于count/search/suggest操作。线程池类型是fixed。线程数量为int((# of allocated processors * 3) / 2) + 1。队列大小为1000
。
用于在search_throttled indices
上的count/search/suggest/get操作。线程池类型为fixed
,线程数量为1
,队列大小为100
。
用于轻量级的查询相关的协同操作(search-related coordination)。线程池类型为fixed
,线程数量为a max of min(5, (# of allocated processors) / 2),队列大小为1000
。
用于get操作,线程池类型为fixed
,线程数量为# of allocated processors,队列大小为1000
。
用于analyzer请求,线程池类型为fixed
,线程数量为1
,队列大小为16
。
用于单篇文档的 index/delete/update以及bulk的请求,线程池类型为fixed
,线程数量为# of allocated processors,队列大小为10000
。这个线程池的最大值是1 + # of allocated processors。
用于snapshot/restore请求,线程池类型为scaling,keep-alived的值为5m
以及a max of min(5, (# of allocated processors) / 2)。
用于读取snapshot repository metadata的请求,线程池类型为scaling,keep-alived的值为5m
以及a max of min(50, (# of allocated processors) / 3)。
用于segment warm-up的操作,线程池类型为scaling,keep-alived的值为5m
以及a max of min(5, (# of allocated processors) / 2)。
用于refresh的操作,线程池类型为scaling,keep-alived的值为5m
以及a max of min(10, (# of allocated processors) / 2)。
用于列出分片状态(list shard state)的操作,线程池类型为scaling,keep-alived的值为5m
以及a default maximum size of 2 * # of allocated processors。
用于列出分片存储(list shard store)的操作,线程池类型为scaling,keep-alived的值为5m
以及a default maximum size of 2 * # of allocated processors。
用于flush和translog fsync
的操作,线程池类型为scaling,keep-alived的值为5m
以及a max of min(10, (# of allocated processors) / 2)。
用于force merge操作,线程池类型为fixed,线程数量为1
,队列大小为unbounded
。
用于集群管理,线程池类型为scaling,keep-alived的值为5m
以及a default maximum size of 5。
用于读取系统索引的操作,线程池类型为fixed,keep-alived的值为5m
以及a default max of min(5, (# of allocated processors) / 2)。
用于写入系统索引的操作,线程池类型为fixed,keep-alived的值为5m
以及a default max of min(5, (# of allocated processors) / 2)。
用于读取关键系统索引(critical system indices)的操作,线程池类型为fixed,keep-alived的值为5m
以及a default max of min(5, (# of allocated processors) / 2)。
用于写入关键系统索引(critical system indices)的操作,线程池类型为fixed,keep-alived的值为5m
以及a default max of min(5, (# of allocated processors) / 2)。
用于watch executions。线程池类型为fixed,以及a default max of min(5 * (# of allocated processors) , 50),队列大小为50
。
线程池的设置是static,通过编辑elasticsearch.yml
更改。下面的例子中更改了write
线程池中的线程数量:
xxxxxxxxxx
31thread_pool:
2 write:
3 size: 30
下文中介绍的是线程池的类型以及对应的参数:
fixed
类型的线程池中有固定数量的线程,以及一个队列(通常是有界的),当线程池中没有可用线程时,队列会hold住请求。
size
参数控制了线程的数量。
queue_size
控制了队列中的请求数量,当没有可用线程时,队列会hold住请求。默认情况下,该值为-1
意味着队列是无界的。但一个新的请求到来时,如果队列已满则abort这个请求。
xxxxxxxxxx
41thread_pool:
2 write:
3 size: 30
4 queue_size: 1000
scaling
类型的线程池中拥有动态数量的线程。线程数量跟工作负载成正比(proportional)。线程数量在参数core
和max
之间变化。
keep_alive
参数用于决定当线程池中的线程没有任何工作时,呆在线程池中的最大时间。
xxxxxxxxxx
51thread_pool:
2 warmer:
3 core: 1
4 max: 8
5 keep_alive: 2m
处理器(processor)的数量会被自动的检测。线程池的会基于处理器的数量自动的设置。在有些情况下,覆盖(override)处理器的数量是很有用的。可以显示的(explicit)设置node.processors
。
xxxxxxxxxx
11node.processors: 2
以下的情况要显示的覆盖设置node.processors
:
If you are running multiple instances of Elasticsearch on the same host but want Elasticsearch to size its thread pools as if it only has a fraction of the CPU, you should override the node.processors setting to the desired fraction, for example, if you’re running two instances of Elasticsearch on a 16-core machine, set node.processors to 8. Note that this is an expert-level use case and there’s a lot more involved than just setting the node.processors setting as there are other considerations like changing the number of garbage collector threads, pinning processes to cores, and so on.
Sometimes the number of processors is wrongly detected and in such cases explicitly setting the node.processors setting will workaround such issues.
若要检查检查到的处理器的数量,使用nodes info AP带上os
这个flag。
(8.2)link
根据你安装Elasticsearch时使用的安装包,以及你正在使用的操作系统,系统设置的配置位置略有不同。
当使用.zip
或者.tar.gz
的安装包时,可以通过下面的方式配置系统设置:
在ulimit中临时设置
当使用RPM或者Debian发行版时,大多数的系统设置在system configuration file中设置,然而在使用systemd的系统中,要求在systemd configuration file中指定system limit。
在linux系统中,ulimit
用于临时更改资源限制(resource limit)。Limits通常需要使用root用户进行设置,然后切换到普通用户启动Elasticsearch。例如,将文件句柄(file handler)的最大数量设置为65,536(ulimit -n),你可以按照下面的方式进行设置:
xxxxxxxxxx
31sudo su
2ulimit -n 65535
3su elasticsearch
第1行,切换到root用户
第2行,设置打开的文件最大数量(max number of open files)
第3行,切换到普通用户来启动Elasticsearch
这个新的限制(new limit)只适用于当前会话(current session)
你可以通过ulimit -a
查询(consult)当前目前所有的limit
在linux系统中,可以通过编辑文件/etc/security/limits.conf
为linux的某个系统用户设置persistent limits。如果要为elasticsearch
这个系统用户设置可以打开的文件最大数量为65,535,在文件中添加一行下面的内容:
xxxxxxxxxx
11elasticsearch - nofile 65535
这个变更只有在elasticsearch
这个用户下次打开一个新的session时才会生效。
NOTE: Ubuntu and
limits.conf
在Ubuntu中,由init.d
启动的进程会忽略limits.conf
文件,如果需要让这个文件生效,可以编辑/etc/pam.d/su
然后注释下面这一行的内容:# session required pam_limits.so
当使用RPM或者Debian安装包时,可以在系统配置文件中指定系统变量:
RPM | /etc/sysconfig/elasticsearch |
---|---|
Debian | /etc/default/elasticsearch |
然而system limits需要通过systemd来指定。
当在使用systemd的系统上使用RPM或者Debian安装包时,system limits需要通过systemd来指定。
systemd service file(/usr/lib/systemd/system/elasticsearch.service
)中包含了默认的limit。
你可以新增一个文件名为/etc/systemd/system/elasticsearch.service.d/override.conf
(或者你可以执行sudo systemctl edit elasticsearch
,它会在默认编辑器中自动打开文件),在这个文件中做如下的变更:
xxxxxxxxxx
21[Service]
2LimitMEMLOCK=infinity
完成更改后,运行下面的命令来reload units:
xxxxxxxxxx
11sudo systemctl daemon-reload
(8.2)link
大多数的操作系统会为文件系统缓存(file system cache)尽可能多的使用内存并且急切的(eagerly)将unused application memory交换出去(swap out)。这会导致部分JVM堆甚至executable page被交换到磁盘上。
Swapping对性能、节点稳定影响是非常大的,无论如何(at all cost)都要避免。这会导致垃圾回收的时间达到分钟级别而不是毫秒级别,使得节点的响应时间变慢甚至与节点的断开连接。在弹性分布式系统中,让操作系统杀死节点反而更有效。
有三种方法关闭swapping。较好的方法(prefer option)是完全的关闭swapping。如果不能用这个方法,那么基于你的环境选择最小化swappiness还是内存锁定。
通常Elasticsearch是一个box中唯一运行的服务,并且通过JVM参数来控制内存的使用,就没有必要开启swapping。
在linux系统中,你可以运行下面的命令临时关闭swapping:
xxxxxxxxxx
11sudo swapoff -a
这个操作不需要重启Elasticsearch。
若要永久关闭,你需要编辑文件/etc/fstab
,然后将所有包含swap
的内容都注释。
在Windows上,可以通过System Properties → Advanced → Performance → Advanced → Virtual memory
达到相同的目的。
要确保Linux系统上另一个可用的选项:sysctl的vm.swappiness
的值是1
。这个选项会降低kernel进行swap的趋势,在正常情况下(normal circumstances)不会进行swapping,并且允许在紧急情况下运行将整个系统进行swapping。
另一种方式是通过在Linux/Unix系统上使用mlockall或者是Windows系统上的VirtualLock,将进程地址空间锁定到RAM,防止Elasticsearch堆内存被swapping。
NOTE: 一些平台在使用了memory lock后仍然会swap off-heap memory。为了防止swap off-heap memory,转而尝试disable all swap files。
在elasticsearch.yml
中设置bootstrap.memory_lock
为true
来开启memory lock:
xxxxxxxxxx
11bootstrap.memory_lock: true
WARNING:如果尝试分配比可用内存更多的内存量,
mlockall
可能会导致JVM或者shell session退出。
在启动Elasticsearch之后,你可以通过下面这个请求输出的mlockall
的值检查是否应用了设置:
xxxxxxxxxx
11GET _nodes?filter_path=**.mlockall
如果你看到mlockall
的值为false
,那么意味着mlockall
请求失败了。你可以在日志中看到包含Unable to lock JVM Memory
的更详细的信息。
在Linux/Unix系统上最有可能导致失败的原因是运行中的Elasticsearch没有权限来lock memory。可以通过下面的方式授权:
.zip
and .tar.gz
在启动Elasticsearch前切换到root用户并执行ulimit -l unlimited,或者在/etc/security/limits.conf
中设置memlock
为unlimited
。
xxxxxxxxxx
31# allow user 'elasticsearch' mlockall
2elasticsearch soft memlock unlimited
3elasticsearch hard memlock unlimited
RPM and Debian
在systemd configuration中将LimitMEMLOCK
设置为infinity
另一个导致mlockall
可能的原因是the JNA temporary directory (usually a sub-directory of /tmp) is mounted with the noexec option,可以使用ES_JAVA_OPTS
环境变量为JNA指定一个临时的目录来解决:
xxxxxxxxxx
21export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djna.tmpdir=<path>"
2./bin/elasticsearch
或者在配置文件jvm.options中设置这个JVM标志。
(8.2)link
NOTE:File Descriptors仅仅适用于Linux以及MacOs,在Windows平台上运行Elasticsearch可以忽略。在 Windows 上,JVM 使用仅受可用资源限制的 API
Elasticsearch会使用很多file descriptors 或者 file handles。文件描述符用完可能是灾难性的,并且很可能会导致数据丢失。要确保将open files descriptors的数量提高到65,536或者更高用于Elasticsearch的运行。
对于.zip
和.tar.gz
的安装包,在Elasticsearch启动前使用root用户执行ulimit -n 65535
,或者在/etc/security/limits.conf
设置nofile
的值为65535
。
在MacOs平台上,你必须要使用JVM参数-XX:-MaxFDLimit
让Elasticsearch使用更高的file descriptors限制。
RPM和Debian已经默认将file descriptors的最大值设置为65535并且不需要进一步的配置。
你可以使用Nodes stats API检查每一个节点上的max_file_descriptors
:
xxxxxxxxxx
11GET _nodes/stats/process?filter_path=**.max_file_descriptors
(8.2)link
Elasticsearch默认使用mmapfs存储索引文件。默认情况下操作系统会将mmap count限制的太低导致OOM的异常。
在Linux下,你可以使用root通过下面的命令来提高上限:
xxxxxxxxxx
11sysctl -w vm.max_map_count=262144
可以在/etc/sysctl.conf
中更新vm.max_map_count
来永久的设置该值。在重启后使用sysctl vm.max_map_count
命名来验证刚才的变更。
RPM跟Debian安装包会自动进行配置。不需要进行额外的配置。
(8.2)link
Elasticsearch会使用线程池用于不同类型的操作。重要的是当有需要时就会创建新的线程。保证Elasticsearch能创建的线程数量至少可以有4096个。
在启动Elasticsearch前切换到root设置ulimit -u 4096,或者在/etc/security/limits.conf中将nproc
设置为4096。
在systemd
下运行的service会自动的为Elasticsearch进程设置线程数量。不需要额外的配置。
(8.2)link
Discovery and cluster formation负责节点发现,选举master,形成集群,以及每一次发生变更时集群状态的发布。
下面的processes和settings是discovery and cluster formation的 一部分:
Discovery是当master未知时,节点之间用来相互发现的步骤,例如一个节点刚刚启动或者当上一个master node发生故障时
Elasticsearch如何基于quorum-based voting mechanism来做出决策,即使一些节点发生了故障
Elasticsearch在节点加入以及离开集群时如何自动的更新voting configuration
当Elasticsearch集群第一次启动时Bootstrapping a cluster是必须。在development node中,如果没有配置discovery settings,这将由节点本身自动执行。由于auto-bootstrapping是inherently unsafe,在production mode中要求节点显示配置(explicitly configure)bootstrappping。
Adding and removing master-eligible nodes
建议在集群中设置一个小规模的并且固定数量的master-eligible node,只通过添加或者移除master-ineligible node来扩大或者缩小集群。然而也有一些情况需要将一些master-eligible node 添加到集群,或者从集群中移除。 这块内容描述的是添加或者移除master-eligible node的过程,包括在同一时间移除超过一半数量的master-eligible node时额外必须要执行的步骤。
Cluster state publishing描述的是被选举为master的node更新集群中所有节点的集群状态的过程
Elasticsearch执行健康检查来检测以及移除有故障的节点
让用户通过设置来影响(influence)discovery,cluster formation,master election和fault detection processes
(8.2)link
Discovery是cluster formation module发现其他节点并形成一个集群的过程。这个过程发生在当你启动一个Elasticsearch节点或者当一个节点认为master node发生故障并且等到发现master node或者选出新的master node后继续运行时。
这个过程和上一次已知的集群中的master-eligible node的地址一起,开始于一个或者多个seed hosts providers中提供的seed address列表。这个过程有两个阶段:首先,通过连接每一个地址来尝试明确节点是否连接并且验证是否为master-eligible node。然后如果成功了,它会共享它已知的master-eligible node的remote node并且等待响应。然后该节点探测(prove)它刚刚发现的所有新节点,请求它们的对等节点(peer),等等。
如果当前节点不是master-eligible node,那它会继续处理直到它发现了被选举为master的node。如果没有发现master node那么这个节点将在discovery.find_peers_interval
后重试,默认值是1s
。
如果当前节点是master-eligible node,那它会继续处理直到它要么发现了一个master node,要么已经发现了足够多masterless master-eligible node并完成master的选举。如果这两个都没有发生,则在discovery.find_peers_interval
后重试,默认值是1s
。
一旦一个master被选举出来,通常情况下它会一直是master node,直到它被故意(deliberate)停止。如果falult detection发现集群发生了故障,也有可能作为master并停止。如果一个节点不是master node,它则继续discovery的过程。
大多数情况下,discovery和选举的过程会很快完成。并且master node在很长的一段时间内都是会master。
如果你的集群没有一个稳定(stable)的master,许多的功能不能正确工作。那么Elasticsearch会报出错误给客户端并记录日志。你必须在解决其它问题前先处理master node的不稳定问题。master node选举出来之前或者master node稳定前将无法解决其他任何的问题。
如果你有一个稳定的master node但是一些节点不能发现它或者加入,这些节点会报出错误给客户端并记录日志。在解决其它问题前你必须先解决这些节点无法加入到集群的障碍(obstacle)。节点不能加入集群前将无法解决其他任何问题。
如果集群在超过好几秒后都没有选举出master,说明master不稳定或者其他节点无法发现或者加入join a stable master。那Elasticsearch会在日志中记录其原因。如果这个问题超过好几分钟还存在,Elasticsearch会在日志中记录额外的日志。若要正确的处理discovery和选举问题,可以收集并分析所有节点上最新的5分钟内的日志。
下面的内容介绍了一些常见的discovery和选举问题。
当一个节点赢的选举,日志中会包含elected-as-master
的信息并且所有的节点会记录一条包含master node changed
的信息来标识最新赢的选举的master node。
如果没有选出master node并且没有节点赢得选举,所有的节点会重复的在日志中记录问题:org.elasticsearch.cluster.coordination.ClusterFormationFailureHelper
。默认情况下,每10秒发生一次。
master的选举只会涉及master-eligible node,所以这种情况下集中查看master-eligible node的日志。这些节点的日志会说明master选举的要求,比如用于discovery的相关节点。
如果日志显示Elasticsearch不能从quorum中发现足够多的节点。你必须解决阻止Elasticsearch发现缺失节点的原因。缺失的节点需要用于重新构造(reconstruct)cluster metadata。没有cluster metadata,你集群中的数据是没有意义的(meaningless)。cluster metadata存储在集群中master-eligible node的子集中。如果不能发现quorum ,那么缺失的节点是拥有cluster metadata的节点。
保证有足够多的节点来形成quorum并且每个节点能相互通过网络联系到对方。如果选举问题持续了好几分钟,Elasticsearch会额外的报出网络连接的细节。如果你不能启动足够多的节点来形成quorum,那么启动一个新的集群并且从最新的snapshot中恢复数据。参考Quorum-based decision making 了解更多信息。
如果日志显示Elasticsearch已经发现了 a possible quorum of nodes。那么集群不能选出master的原因通常是其中的节点不能发现quorum。检查其他master-eligible node上的日志并且保证他们已经发现了足够多的节点来形成一个quorum。
当一个节点赢得了选举,它的日志中会包含elected-as-master
的信息。如果重复出现这个日志,说明选举出的节点不稳定。在这种情况下,集中在master-eligible node中的日志中查看为什么选举出的胜利者后来又停止成为master并且又触发另一个选举的原因。
如果选举出的master node是一个稳定的节点,但是某个节点不能发现并加入到集群,它会在日志中使用ClusterFormationFailureHelper
重复的报出日志。其他受到影响的节点和选举为master的节点上可能会有一些关于这个问题的额外的日志。
如果某个节点加入到了集群但是Elasticsearch认为它出了故障并随后将再次从集群中移除。见Troubleshooting an unstable cluster了解更多信息。
默认情况下,cluster formation module提供了两个seed hosts provider来配置seed node列表:settings-based和file-based。可以扩展为支持云环境以及通过discovery plugins的其他形式的seed hosts provider。seed hosts provider使用discovery.seed_providers
进行配置,这个是settings-base 这种provider的默认方式。这个设置接受一个不同的provider的列表,允许你能用多种方式来为你的集群找到seed hosts。
每一个seed hosts provider提供(yield)seed node的IP地址或者hostname。如果返回的是hostname,那么需要使用DNS来查找对应的IP地址。如果一个hostname对应了对个IP地址,那么Elasticsearch会尝试找到所有的地址。如果hosts provider没有显示的(explicit)给出节点的TCP port,则会隐式的(implicit)使用port range中的第一个:transport.profiles.default.port
或者transport.port
(如果没有设置transport.profiles.default.port
)。通过DSN查找IP地址的并发数量由discovery.seed_resolver.max_concurrent_resolvers
控制,默认值是10
。超时时间由discovery.seed_resolver.timeout
控制,默认值是5s
。注意的是DNS查找IP地址受限于JVM DNS caching。
Settings-based seed hosts provider使用了节点设置来配置一个静态的seed nodes的地址列表。这些地址可以是hostname或者是IP地址。使用hostname时会在每一次discovery时去查找对应的IP地址。
下面使用了discovery.seed_hosts静态设置:
xxxxxxxxxx
41discovery.seed_hosts:
2 - 192.168.1.10:9300
3 - 192.168.1.11
4 - seeds.mydomain.com
第3行,将默认使用transport.profiles.default.port
,如果没有配置transport.profiles.default.port
则使用transport.port
第4行,如果这个hostname对应了多个IP地址,Elasticsearch会尝试连接每一个IP地址
File-based seed hosts provider通过外部的文件来配置hosts列表。这个文件发生变更后,Elasticsearch就会重新加载,所以不需要重启节点就可以使用变更后的seed nodes的地址。例如运行在Docker容器中的Elasticsearch就可以很方便的在节点启动时,如果给定的IP地址无法连接时就可以动态的提供。
若要开启file-based的discovery,那么在elasticsearch.yml
中配置file
即可:
xxxxxxxxxx
11discovery.seed_providers: file
然后按照下面的格式在$ES_PATH_CONF/unicast_hosts.txt
中创建一个文件。任何时刻在unicast_hosts.txt
文件中发生的变更都会被Elasticsearch捕获并使用新的hosts列表。
注意的是file-based discovery 插件增强了elasticsearch.yml
中的unicast hosts list:如果在discovery.seed_hosts
中有合法的seed address,那么Elasticsearch会使用这些地址并额外使用unicast_hosts.txt
中的地址。
unicast_hosts.txt
文件中每一行是一个node entry。每一个node entry由host(hostname或者IP地址)和一个可选的transport port 组成。如果指定了port,必须是写在host后面并且用:
分隔。如果没有指定port,默认使用transport.profiles.default.port
,如果没有配置transport.profiles.default.port
则使用transport.port
。
例如,下面的unicast_hosts.txt
中有四个node参与discovery,其中一些使用了默认的端口号:
xxxxxxxxxx
5110.10.10.5
210.10.10.6:9305
310.10.10.5:10005
4# an IPv6 address
5[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
可以使用hostname来代替IP地址,但是需要上文描述的DNS。IPv6的地址必须要给定端口号。
你可以在文件中添加注释, 所有的注释必须以#
开头
EC2 discovery plugin使用AWSAPI来 查找seed node。
Azure Classic discovery plugin使用Azure Classic API来查找seed node。
GCE discovery plugin 使用GCE API来查找seed node。
(8.2)link
选举出master node和变更集群状态是两个基本的任务,需要所有的master-eligible node一起工作执行。重要的是即使一些节点发生了故障也要让这些工作具有鲁棒性。Elasticsearch中达到这个鲁棒性的方式是:考虑每一个从quorum
中接受到成功的响应。quorum
即集群中的master-eligible node集合。只需要一部分节点响应的好处在于在一些节点发生故障后也不会影响集群继续工作。quorum是经过谨慎选择的,这样集群中不会出现裂脑(split brain)的场景:集群被划分为两块,每一块会作出与另一块不一样的决策。
Elasticsearch允许你向正在运行中的集群添加或者移除master-eligible node。在很多场景中只要按需简单的启动或者节点即可。见Adding and removing nodes。
通过更新集群中的voting configuration使得在添加/移除节点时,Elasticsearch能维护一个最佳的容错能力(Elasticsearch maintains an optimal level of fault tolerance)。voting configuration是master-eligible的集合,它们的响应会被计数用来对选举出新的master和提交(commit)新的集群状态做出决策。只有voting configuration中的超过半数才能做出决策。通常情况下,voting configuration跟当前集群中所有的master-eligible集合是相同的,然而在有些情况下会有不同。
为了保证集群仍然可用(remain available),你必须不能在同一时间(at the same time)停止一半或者更多的voting configuration中的节点。只要超过一半的voting node是可用的,集群就能正常的工作。例如,如果有3个或者4个master-eligible node,集群可以容忍一个不可用的节点。如果2个或者更少的master-eligible node,他们必须都是可用的。
一个节点加入/离开集群时,选举为master的节点必须发布(issue)集群状态的更新,调整(adjustment)voting configuration,这个过程可能会花费一点时间。在移除更多节点之前等待调整结束是非常重要的。
Elasticsearch在启动阶段以及当master node发生故障时使用选举的处理方式来达成一致选出master node。任何的master-eligible都可以开始一个选举,通常来说第一次选举都会成功(normally the first election that takes place will succeed)。只有当两个节点碰巧同时开始选举时,选举才会失败,所以每个节点上的选举都是随机安排的,以降低这种情况发生的概率。节点会重试选举,直到选举出master node。backing off on failure,使得选举会最终的成功。The scheduling of master elections are controlled by the master election settings。
许多的集群维护任务包括临时的关闭一个或者多个节点然后重新启动它们。默认情况下,如果其中一个master-eligible node下线了,Elasticsearch仍然可用。比如在rolling upgrade期间。如果多个节点停止并且再次启动,Elasticsearch会自动的进行恢复,例如在full cluster restart期间。上述说到的场景中,不需要使用APIs来做出额外的措施,because the set of master nodes is not changing permanently。
(8.2)link
每一个Elasticsearch集群中都有一个voting configuration,通过master-eligible nodes集合的投票计数来作出一些决策,例如选举出新的master或者提交一个新的集群状态。决策只有在voting configuration 中节点大多数都响应后(超过半数)可以通过。
通常情况下voting configuration和当前集群中所有的master-eligible node集合相同。然而在某些情况下可能会不同。
IMPORTANT:为了保证集群仍然可用(remain available),你必须不能在同一时间(at the same time)停止一半或者更多的voting configuration中的节点。只要超过一半的voting node是可用的,集群就能正常的工作。例如,如果有3个或者4个master-eligible node,集群可以容忍一个不可用的节点。如果2个或者更少的master-eligible node,他们必须都是可用的。
在某个节点加入或者离开集群时,Elasticsearch会自动的对voting configuration作出对应的变更来保证集群尽可能的具有弹性(resilient)。非常重要的一点是:你从集群中移除更多节点之前,要等待调整(adjustment)完成,见Adding and removing nodes.。
当前的voting configuration存储在集群状态中,你可以按照以下的方式来查看当前的内容:
xxxxxxxxxx
11GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config
NOTE:当前的voting configuration不需要跟集群中的所有的可用的master-eligible node集合相同。改变(alert)voting configuration会涉及进行投票,所以节点加入或者离开集群时会花一点时间来调整configuration。同样的,也会存在most resilient configuration包含不可用的节点或者不包含可用的节点。在这种情况下,voting configuration就会跟集群中的master-eligible node不相同。
规模大(large)的voting configuration 通常更具有弹性。所以Elasticsearch更喜欢(prefer to)在master-eligible node加入到集群后把他们添加到voting configuration中。同样的,如果一个在voting configuration中的节点离开了集群并且集群中有另一个不在voting configuration中的master-eligible node,那么会去交换这两个节点。voting configuration的大小没有发生变化但是提高了弹性。
节点离开集群后,从voting configuration中移除节点不是一件简单的事情。不同的策略有不同的好处跟缺点,所以正确的选择取决于集群如何被使用。你可以通过cluster.auto_shrink_voting_configuration setting来控制voting configuration是否要自动的收缩(shrink)。
NOTE:如果
cluster.auto_shrink_voting_configuration
设置为true
(默认值,推荐值)。那么集群中会至少有3个master-eligible node。Elasticsearch仍然可以处理集群状态的更新,只要除了其中一个maste-eligible node,其他的所有节点都是健康的。
在某些情况下,Elasticsearch能够容忍多个节点的丢失, but this is not guaranteed under all sequences of failures。如果cluster.auto_shrink_voting_configuration
设置为false
。你必须手动的去voting configuration中移除离开集群的节点(departed node)。使用voting exclusions API 来达到想要的弹性等级。
无论怎么配置,Elasticsearch都不会受到裂脑导致不一致的困扰。cluster.auto_shrink_voting_configuration
这个设置只会只会影响在一些节点发生故障后的可用性问题,以及影响节点离开/加入集群时 administrative task的执行。
正常来说集群中应该有奇数个master-eligible node。如果是偶数个,Elasticsearch会将其中一个排除在voting configuration以外来保证奇数个。这种omission不会降低集群的容错能力。事实上还有略微提升:如果集群受到网络分区的影响,将其划分为大小相等的两部分,那么其中一部分将包含大多数voting configuration,并能够继续运行。如果所有的master-eligible node的投票都进行了统计,那么任何一方都不会包含严格多数的节点,因此集群将无法做任何处理(make any progress)。
例如,如果在集群中有4个master-eligible node并且voting configuration包含这四个节点。任何quorum-based的决策都要求至少三个投票。这意味着这个集群可以容忍单个master-eligible node的丢失。如果集群被两等分,没有一半可以获得三个master-eligible node,集群就不会做任何处理。如果voting configuration只有三个master-eligible node,集群仍然可以容忍丢失一个节点,但是quorum-based的决策要求3个投票节点中的2个。即使发生了分裂,其中一半会包含3个投票节点的2个节点,所以这一半仍然是可用的。
当一个全新的集群第一次启动,必须选出第一个master node。要完成这个选举,需要知道用于投票计数的master-eligible集合。这个初始化的voting configuration即bootstrap configuration
并且在cluster bootstrapping process中设置。
重要的一点是bootstrap configuration
明确指定了在第一次选举中参与的节点。 It is not sufficient to configure each node with an expectation of how many nodes there should be in the cluster. It is also important to note that the bootstrap configuration must come from outside the cluster: there is no safe way for the cluster to determine the bootstrap configuration correctly on its own。
如果boostrap configuration没有正确设置,当你启动一个全新的集群时,会有形成两个不同集群的风险。这种情况会导致数据丢失:很有可能在你注意到这个问题前已经启动了2个集群并且不可能在随后合并这两个集群。
NOTE:To illustrate the problem with configuring each node to expect a certain cluster size,想象一下启动一个三个节点的集群,每一个节点知道自己将成为三个节点集群中的一员。三个节点的大多数是2,所以正常情况下前两个启动的节点能发现对方并且形成一个集群,并且第三个节点会在随后很短的时间内加入它们。然而想象下如果错误当启动了四个节点而不是三个。在这种情况下,就会有足够的节点来形成两个集群。当然,如果每一个节点是手动启动的,那不大可能启动太多的节点。如果使用了自动化编排(orchestrator),这当然有可能会发生这种情况。特别是编排器不具备弹性(resilient)而导致网络分区的错误。
最初的quorum只有在整个集群最开始启动的时候需要。加入到一个已经建立好的集群的节点可以安全的从被选举为master节点上获取所有的信息。注意的是之前作为集群一部分的节点将在重新启动时会将所有需要的信息存储到磁盘中。
(8.2)link
最开始启动Elasticsearch时要求一个集群中的一个或者多个初始化的master-eligible node集合,需要显示的定义,即cluster bootstrapping
。仅要求在集群第一次启动时:已经加入到一个集群的节点会将信息存储在它们的数据目录中用于full cluster restart并且新加入到集群的节点会从集群中被选举master的节点上获取信息。
最初的master-eligible node集合定义在cluster.initial_master_nodes setting中。配置中要包含每一个master-eligible node的下面其中一个条目:
节点的node name
如果没有设置node.name
则要求有节点的hostname。因为node.name
默认就是节点的hostname。你可以使用fully-qualified hostname或者bare hostname,取决于depending on your system configuration。
如果无法使用node.name
,则使用节点的transport publish address的IP地址。通常是network.host对应的IP地址,但是this can be overridden
节点的publish address的IP地址跟端口号。如果无法使用node.name
并且多个节点共享同一个IP地址,可以使用的格式为:IP:PORT
。
在你启动一个master-eligible node时,你可以通过命令行或者elasticsearch.yml
的方式提供这个设置。集群形成之后,将这个设置从每一个节点中移除。不能对master-ineligible node,已经加入集群的master-eligible node以及重启一个或者多个节点配置这个设置。
技术上来讲只在集群中的单个master-eligible node上设置cluster.initial_master_nodes
就足够了并且只在设置中提及这个单个节点。但是会在集群完全形成前缺乏容错能力。因此最好使用三个master-eligible node进行引导,每一个节点中都配置了包含三个节点的cluster.initial_master_nodes
。
WARNING:你必须在每一个节点上设置完全相同的
cluster.initial_master_nodes
,使得在引导期间只会形成一个集群,避免数据丢失的风险。
对于拥有三个master-eligible node(node name是 master-a, master-b and master-c)的集群,配置如下:
xxxxxxxxxx
41cluster.initial_master_nodes:
2 - master-a
3 - master-b
4 - master-c
跟其他的节点设置一样,也可以通过命令行的方式指定the initial set of master nodes 来启动Elasticsearch:
xxxxxxxxxx
11bin/elasticsearch -E cluster.initial_master_nodes=master-a,master-b,master-c
cluster.initial_master_nodes
列表中使用的node name必须和节点的属性node.name
完全一样。默认情况下node name被设置为机器的hostname,这个值在你的系统配置中可能不是fully-qualified。如果每一个node name是fully-qualified domain name,例如master-a.example.com
,那你在cluster.initial_master_nodes
列表中也必须使用fully-qualified domain name。如果你的node name是bare hostname (without the .example.com suffix) ,那你在cluster.initial_master_nodes
列表中也必须使用bare hostname。如果你同时使用了fully-qualified 和 bare hostnames,或者其他无法匹配node.name 和 cluster.initial_master_nodes的值,那集群无法成功形成并会看到下面的日志信息:
xxxxxxxxxx
41[master-a.example.com] master not discovered yet, this node has
2not previously joined a bootstrapped (v7+) cluster, and this
3node must discover master-eligible nodes [master-a, master-b] to
4bootstrap a cluster: have discovered [{master-b.example.com}{...
这个消息显示了node name:master-a.example.com
和 master-b.example.com
以及cluster.initial_master_nodes
中的值:master-a
和master-b
。日志中明显的指出它们无法完全匹配。
cluster.name这个设置能让你创建多个彼此相互隔离的集群。节点之间在第一次相互连接时会验证集群名。Elasticsearch只会形成一个所有节点的集群名都相同的集群。默认值是elasticsearch
,不过建议修改这个值来体现出集群的逻辑名称。
默认情况下,每一个节点在第一次启动时会自动的引导(bootstrap)自己进入一个单节点的集群。如果配置了下面任意的一个设置,自动引导会被替代:
discovery.seed_providers
discovery.seed_hosts
cluster.initial_master_nodes
若要添加一个节点到现有的一个集群中,那么配置discovery.seed_hosts
或者其他相关的设置,这样新的节点就可以发现集群中现有的master-eligible节点。若要引导一个多节点的集群,配置上文中section on cluster bootstrapping描述的cluster.initial_master_nodes
。
一旦Elasticsearch的节点加入到一个现有的集群,或者引导出一个集群后,他不会加入到其他的集群。Elasticsearch不会将两个不同的已经形成的集群进行合并,即使你随后尝试配置所有的节点到一个节点中。这是因为没法在不丢失数据的情况下合并不同的集群。你可以通过GET /
在每一个节点上获取集群的UUID来检查形成的不同集群。
如果你想要添加一个节点到现有的集群中而不是引导出不同的单节点集群,那你必须:
关闭节点
通过删除data folder的方式来完全擦除(wipe)节点
配置discovery.seed_hosts
或者 discovery.seed_providers
以及其他相关的discover 设置
重启节点并且验证下节点是否加入到集群而不是形成自己的单节点集群
如果你是要形成一个新的多节点集群而不是引导出多个单节点集群,那你必须
关闭所有的节点
通过删除每一个节点的data folder的方式来完全擦除(wipe)所有的节点
按照上文描述的方式来配置cluster.initial_master_nodes
配置discovery.seed_hosts
或者 discovery.seed_providers
以及其他相关的discover 设置
重启所有的节点并验证它们形成了单个集群
(8.2)link
master node是集群中唯一可以对集群状态(cluster states)做出变更的节点。master node一次处理一批集群状态的更新。计算变更请求并更新集群状态到集群中的所有节点。每一次的发布开始于master向集群中所有的节点广播更新后的集群状态。每一个节点都响应确认,但未应用最新接收的状态。一旦master收集到足够的来自master-eligible node的确认,这个新的集群状态被认为是提交(commit)了,然后master node广播另一个消息让节点应用提交的集群状态。每一个节点收到这条消息后,应用更新后的状态,然后发送一个确认给master。
master允许在有限的时间内完成集群状态更改到发布给所有的节点。定义在cluster.publish.timeout
设置中,默认值30s
。从publication开始算时间。如果在新的集群状态提交前达到了这个时间,集群状态的变更会被reject然后master会认为自己出现了故障。然后开始新的选举。
如果在达到cluster.publish.timeout
之前新的集群状态提交了,master会认为这次变更成功了。master会等待所有节点应用更新状态后的确认或者等待超时,然后开始处理并发布下一次的集群状态更新。如果master没有收到一些确认(比如一些节点还没有确认他们已经应用了当前的更新)这些节点被认为是它们的集群状态落后于master最新的状态。默认值是90s
。如果仍然没有成功的应用集群状态更新,那么它会被认为发生了故障并且从集群中移除。
发布的集群状态的更新内容通常是跟上一次状态的差异,这样能减低时间以及网络带宽。例如为集群状态中部分索引的更新mappings时,只要节点上有上一次的集群状态,那么就可以只发布这些索引更新对应的差异到集群中的节点上。如果一个节点缺失了上一个集群状态,比如说重新加入到了集群,master会发送完整的集群状态到这个节点,使得这个节点后续能接收差异更新。
NOTE:Elasticsearch是基于点对点的系统,节点之间相互直连。high-throughput的APIs(index,delete,Search)通常不会跟master node交互。master node负责全局的集群状态并且当节点加入或者离开时重新分配分片。每次集群状态发生变化后,最新的状态会被发布到集群中的节点上
(8.2)link
被选举为master的节点会周期性的检查集群中的每个节点来保证它们仍是连接的并且健康的。每一个节点同样周期性的检查master node的健康。这些检查分别被称为follower checks
和leader checks
。
Elasticsearch允许这些检查偶尔的出现失败或者超时的问题并且不采取任何行动。只有在连续多次检查(consecutive check)失败后才会认为这个节点发生了故障。你可以通过cluster.fault_detection.* settings来控制故障检测的行为。
如果master node检测到某个节点失去了连接,这种情况会被视为立即失败(immediate failure)。master会绕过(bypass)超时和重试这些设置,并将这个节点从集群中移除。同样的,如果某个节点检测到master node失去了连接,这种情况也会被视为立即失败。这个节点会绕过(bypass)超时和重试这些设置,尝试discovery阶段来尝试找到/选举一个新的master。
另外,每一个节点会周期性的往data path中写入一个小文件然后删除它来验证data path是否健康。如果节点发现它的data path不健康,随后会从集群中移除直到data path恢复。你可以通过monitor.fs.health settings来控制这个行为。
如果某个节点在一个合理的时间内无法应用更新后的集群状态,master node也会将其从集群中移除。超时时间默认是2分钟,这个时间从更新集群状态开始。参考Publishing the cluster state了解更多信息。
一般情况下,节点只有在故意关闭(deliberately shutdown)时才离开集群。如果某个节点意外的(unexpectedly)离开集群,解决这个问题是非常重要的。集群中的节点意外的离开集群会造成集群不稳定并且会产生一些问题。比如说:
集群的健康可能是黄色或者红色
一些分片可能会初始化并且其他的分片可能会失败
查询,索引以及监控可能会失败并且在日志中抛出异常
索引.security
可能会不可用,阻塞集群的访问
master node可能会由于频繁的集群状态更新变的忙碌
若要解决集群中的问题,首先要保证集群中有一个stable master,优先于其他的问题,集中精力关注意外退出的节点。直到集群中有一个稳定的master node以及稳定的节点成员才有可能解决其他的问题。
诊断数据(Diagnostics)和统计数据在一个不稳定的集群中通常是没有参考价值的。这些工具只是实时的在某个时间给出集群状态的视图。应该查看一段时间内集群的行为模式(pattern of behavior)。特别要关注master node上的日志,当某个节点离开集群时,master node的日志中会有以下类似的信息(为了可读性添加了换行符)
xxxxxxxxxx
71[2022-03-21T11:02:35,513][INFO ][o.e.c.s.MasterService ]
2 [instance-0000000000] node-left[
3 {instance-0000000004}{bfcMDTiDRkietFb9v_di7w}{aNlyORLASam1ammv2DzYXA}{172.27.47.21}{172.27.47.21:19054}{m}
4 reason: disconnected,
5 {tiebreaker-0000000003}{UNw_RuazQCSBskWZV8ID_w}{bltyVOQ-RNu20OQfTHSLtA}{172.27.161.154}{172.27.161.154:19251}{mv}
6 reason: disconnected
7 ], term: 14, version: 1653415, ...
这个消息说的是master node(instance-0000000000)上的MasterService
正在处理一个node-left
的任务。并列出了被移除的节点以及移除的原因。其他的节点可能有类似的日志,但是细节较少:
xxxxxxxxxx
51[2020-01-29T11:02:36,985][INFO ][o.e.c.s.ClusterApplierService]
2 [instance-0000000001] removed {
3 {instance-0000000004}{bfcMDTiDRkietFb9v_di7w}{aNlyORLASam1ammv2DzYXA}{172.27.47.21}{172.27.47.21:19054}{m}
4 {tiebreaker-0000000003}{UNw_RuazQCSBskWZV8ID_w}{bltyVOQ-RNu20OQfTHSLtA}{172.27.161.154}{172.27.161.154:19251}{mv}
5 }, term: 14, version: 1653415, reason: Publication{term=14, version=1653415}
集中关注master node上MasterService
中抛出的日志,它包含更多的细节。如果你无法查看到来自MasterService
的日志,检测下面的内容:
你正在查看的是被选举为master的节点上的日志
日志记录的时间段是正确的
日志等级需要INFO
节点在开始/结束 follow一个master node时会记录包含master node changed
的日志,你可以使用这些信息来观察一段时间内的view of the state of the master 。
节点重启的会先离开集群然后再次加入到集群中。重新加入后,MasterService
会记录它正在处理node-join
的任务。你可以从master的日志中得知节点重启的信息,因为node-join
相关日志描述的是节点的joining after restart
。在较老的Elasticsearch版本中,你可以通过查看node-left
和node-join
中的"ephemeral" ID来判断节点的重启。每次节点的启动,这个 ephemeral ID各不相同。如果某个节点意外的重启,你需要查看这个节点的日志了解它为什么关闭了。
如果节点没有重启,你应该在node-left
日志中查看节点离开集群(departure)的原因。有下面三个可能的原因:
disconnected
:master node到被移出集群的节点之间的连接关闭了
lagging
:master发布了集群状态的更新,但是被移出集群的节点没有在允许的时间内应用这次更新。默认情况下是2分钟。参考Discovery and cluster formation settings了解更多信息
followers check retry count exceeded
:master node往节点连续多次发送了健康检查,这些