Elasticsearch Guide 7.17
- 介绍
- Set up Elasticsearch
- Installing ES
- Configuring ES
- Important system configuration
- Bootstrap Checks
- Bootstrap Checks for X-Pack
- Starting Elasticsearch
- Stopping Elasticsearch
- Discovery and cluster formation
- Add and remove nodes in your cluster
- Full-cluster restart and rolling restart
- Remote clusters
- Set up X-Pack
- Configuring X-Pack Java Clients
- Plugins
- Upgrade Elasticsearch
- Index modules
- Mapping
- Text analysis
- Index templates(7.8开始,旧版本的查看legacy template document)
- Data streams
- Ingest pipelines
- Aliases
- Search your data
- Query DSL
- Aggregations
- EQL
- SQL
- Scripting
- Data management
- ILM: Manage the index lifecycle
- Autoscaling
- Monitor a cluster
- Roll up or transform your data
- Set up a cluster for high availability
- Snapshot and restore
- Secure the Elastic Stack
- Watch (商业功能,需要license)
- Command line tools
- How to
介绍
扩展性与可恢复性
- 一般每个分片数据为几GB到几十GB,
- 避免分片过多,分片树与堆空间成比例,一般1GB堆空间不大于20个分片。
Cross-cluster replication (CCR),主备集群,主机群不可用时可以使用备用集群
client
Java Transport Client
在7.0时就deprecated,推荐使用新的Java High Level REST Client
Java High Level REST Client
从7.15开始deprecated,推荐使用新的Java client
,底层会委托给http client比如 Java Low Level REST Client
处理传输层的东西:http连接池、重试、节点发现等等。
https://www.elastic.co/guide/en/elasticsearch/client/index.html
兼容性:
The Elasticsearch Java client is forward compatible; meaning that the client supports communicating with greater or equal minor versions of Elasticsearch. Elasticsearch language clients are only backwards compatible with default distributions and without guarantees made.
Set up Elasticsearch
Installing ES
es是一个java应用,提供了启动脚本,可以直接启动,不允许使用root用户。启动es:./bin/elasticsearch -d -p pid
,-d后台运行,-p生成pid文件。配置文件里的参数都有使用-E
参数配置,一般集群级别的放在配置文件里,节点级别的参数放在命令行上。
es启动后所有使用的目录都在$ES_HOME
里面,默认是解压后的目录,删除的话直接删除目录即可。建议修改默认的配置目录、数据目录和日志目录,避免删除。
Directory layout of archives
Configuring ES
es有比较好的默认配置,只需要配置一点,而且大部分配置都可以通过 cluster update settings api配置
配置文件应该包含节点本身的一些具体配置,如node.name
,或者节点需要加入集群需要的配置cluster.name
、network.host
es有三个配置文件:
elasticsearch.yml for configuring Elasticsearch,里面的配置也可以使用$读取环境变量
jvm.options for configuring Elasticsearch JVM settings
log4j2.properties for configuring Elasticsearch logging
配置文件位置可以通过环境变量修改:ES_PATH_CONF=/path/to/my/config ./bin/elasticsearch
,
动态配置,可以通过api修改,有两种:persistent
,transient
(不推荐),后者重启后不再生效。优先级:
Transient setting
Persistent setting
elasticsearch.yml setting
Default setting value
静态配置:只有当es没有启动或者已经停止后才可以修改,且需要修改所有相关节点
重要的es配置
虽然es需要很少的配置就可以使用,但是在生产环境上使用前需要考虑以下重要配置。$ES_HOME
有可能在es升级时被删除
# 存储es数据和日志的目录 设置在ES_HOME之外
path:
# 不要修改或备份这个目录下的任何东西,否则可能导致数据不一致或者es失败,es也无法从这个目录恢复任何备份,备份的话使用snapshot-restore,不要对这个目录进行病毒扫描
# 多路径已经deprecated了 如果之前的旧集群配置了多路径 则参考官方说明进行数据迁移
data: /var/data/elasticsearch
logs: /var/log/elasticsearch
# 集群名称 节点加入到集群需要使用,多个环境不要用相同的名称,避免加入错误的集群。
cluster.name: logging-prod
# 节点名称 很多api的响应里都有 默认是机器的主机名
node.name: prod-data-2
# es绑定的地址 默认是回环地址 127.0.0.1 and [::1] 一般单节点不需要修改 集群需要修改
# 如果配置了就会认为是生产模式,会增加一些启动校验
network.host: 192.168.1.10
# 默认es会绑定可用的本地回环地址 同一个server内组成集群的时候会扫描9300-9305端口
# 这里配置集群中有资格为主节点的地址
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com # 如果解析到多个ip地址都会进行尝试
- [0:0:0:0:0:ffff:c0a8:10c]:9301
# ???集群第一次启动时使用?开发模式下 没有discovery settings时 使用这个来自动启动 否则不要使用
# 第一次启动成功后删除这个配置 重启或者添加新节点 不要使用这个配置
cluster.initial_master_nodes:
- master-node-a
- master-node-b
- master-node-c
ES_TMPDIR
,配置es临时目录,避免被服务器定期清除
es数据备份的唯一支持的方式是使用snapshots,不支持通过备份文件的方式恢复。
Secure settings
配置敏感信息,必须使用es的命令行工具进行配置,每个节点必须保持相同,修改那些可加载的配置可以不用重启es,需要执行一个重新加载请求。
Circuit breaker settings
防止某些操作导致OOM
## Parent circuit breaker
# Parent circuit breaker是否考虑实际的内存 或者考虑child circuit breaker保留的内存 默认true
indices.breaker.total.use_real_memory: true
# 多少开始进行断路保护,默认情况下 如果前者为false 70% 否则95%的jvm堆内存
indices.breaker.total.limit
## Field data circuit breaker 字段缓存数据超过定义的大小时
## Request circuit breaker 每个请求的使用的内存超过一定限制
## In flight requests circuit breaker 当前正在进行的请求的内存占用,
## Accounting requests circuit breaker 内存中所有的请求内存统计,包括请求结束但是没有释放的内存,比如lucenne segment
## Script compilation circuit breaker 限制一定时间内脚本行数编译
## Regex circuit breaker 对正则表达式的要求
Cluster-level shard allocation and routing settings
分片分配发生在初始化恢复、副本分配、rebalancing或者添加、删除节点时。主节点决定哪个分片分配到哪个节点以及什么时候移动分片以保持平衡。由很多配置来控制分片分配的过程
Cross-cluster replication settings
跨集群的副本配置
Discovery and cluster formation settings
节点发现和集群信息配置
Field data cache settings
字段数据缓存配置,字段数据缓存包括字段数据和全局的顺序,以支持特定字段类型的聚合,因为这些时在堆上的数据结构,所以有必要进行监控
Index lifecycle management settings in Elasticsearch
索引生命周期管理相关的配置,ILM是什么,参考文档
Index management settings
索引相关的配置,比如是否自动创建索引
Index recovery settings
索引恢复相关配置,比如重新创建分片时数据恢复的速率
Indexing buffer settings
索引缓存,存储新索引的数据,当填满的时候就写一个segment,被这个节点上的所有分片划分进行使用。
License settings
许可配置
Local gateway settings
本地网关存储了集群的状态,当整个集群重启的时候分享数据。每一个master节点都要配置,控制一个新的master在它恢复集群状态和集群数据之前应该等待多久(只有当整个集群重启时有效)
Logging
Machine learning settings
Node
一个es实例就是一个Node,Node集合就是es集群,每个节点都处理http和transport流量,前者被rest client使用,后者节点间通信使用。
所有节点都知道集群中的其他节点,可以转发客户端的请求给合适的节点。
可以为节点指定角色
master
data
data_content
data_hot
data_warm
data_cold
data_frozen
ingest
ml
remote_cluster_client
transform
Networking
每个es节点都有两个接口,客户端发送请求使用http接口,节点通信使用transport接口,
Node query cache settings
使用filter查询的结果会缓存,所有分片共用。使用LRU策略。term查询和filter之外的查询都不缓存。
默认缓存会持有持有10000条,以及堆内存的10%,为了确定是否一个查询有资格缓存,es会维护一个查询历史来追踪。
缓存时基于segment的,segment至少有10000条数据,并且至少占用分片总数的3%。分段合并会使缓存失效。
Search settings
专家配置,管理全局搜索和聚合的限制。
Security settings in Elasticsearch
默认basic or trial license下是不开启的,需要使用配置xpack.security.enabled
Shard request cache settings
当对一个索引或者多个索引请求时,每一个分片在本地执行搜索并且返回局部结果到协调节点,在把这些分片级别的结果汇总为全局结果。
分片界别的请求缓存模块在每个分片上缓存局部结果,这让频繁使用的请求几乎立刻返回结果。
Snapshot and restore settings
快照和恢复相关配置
Transforms settings in Elasticsearch
不需要配置,默认开启
Thread pools
一个节点使用多个线程池来管理内存
Watcher settings in Elasticsearch
创建watcher,发送邮件通知等
Advanced configuration
不推荐修改,可能会降低集群性能和稳定性,大多数情况下使用默认配置即可。
Important system configuration
理想情况下,es应该独占一台服务器,使用所有的服务器资源,需要配置操作系统允许es获取更多的资源
开发模式和生产模式:默认es启动是开发模式,但是只要配置了一些配置,如network.host
就会自动设置为生产模式,并且一些警告会变成异常,防止启动es
Configuring system settings
最大es可以打开的文件数,临时生效ulimit -n 65535
,永久生效/etc/security/limits.conf
,elasticsearch - nofile 65535
Disable swapping
swapping对性能、节点稳定性都不好,应该避免使用,可能导致垃圾回收几分钟,可能导致节点响应非常慢甚至与集群断开连接。
通常es是服务器上运行的唯一服务,内存使用由jvm控制,因此没有必要使用swap。临时关闭sudo swapoff -a
,不需要重启es,永久生效:需要注释/etc/fstab
里包含swap的配置
vm.swappiness确保是1,正常情况下减少内核swap,但是在紧急情况下可以swap
在elasticsearch.yml
中开启bootstrap.memory_lock: true
防止es堆内存swap out,检查是否生效curl -X GET "localhost:9200/_nodes?filter_path=**.mlockall&pretty"
如果没有成功可能是没有权限,在启动es之前添加权限/etc/security/limits.conf
:
# allow user 'elasticsearch' mlockall
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
File Descriptors
es要使用很多的文件描述符或者文件句柄,用尽可能导致数据丢失,需要增加到65536或者更高。配置ulimit -n 65535
或者修改配置文件/etc/security/limits.conf
设置nofile 65535
Virtual memory
es默认使用mmapfs
目录存储索引,操作系统默认的显示可能太低,临时修改sysctl -w vm.max_map_count=262144
,永久生效修改配置文件/etc/sysctl.conf
,重启后验证sysctl vm.max_map_count
Number of threads
es使用很多线程池来执行不同的操作,需要保证无论什么时候es都能创建线程,临时修改ulimit -u 4096
,永久生效配置/etc/security/limits.conf
中nproc
为4096
DNS cache settings
es使用security manager 运行,如果有security manager ,jvm默认一直缓存positive主机名解析,缓存negative主机名10s,es修改的默认行为,缓存postive主机名60s,缓存negative主机名10s,可以通过配置修改。
Ensure JNA temporary directory permits executables
es使用Java Native Access (JNA),以及libffi来执行一些依赖平台的本地代码,在linux中,这些库在运行时会被放在临时目录下,然后映射到es的地址空间里,这就需要它的文件不能挂载在noexec的文件系统上。
默认es在/tmp下创建自己的临时目录,但是有的系统/tmp是noexec的这就导致JNA和libffi无法正常工作。
为了解决这些问题,可以配置/tmp删除noexec配置,或者配置环境变量ES_TMPDIR
TCP retransmission timeout
tcp包重传,大多数linux发行版会重传15次,指数时间back off,15次会花费900s。对于高可用集群,这个配置太过
sysctl -w net.ipv4.tcp_retries2=5
修改tcp重传为5次,最多超时13s,永久生效需要修改/etc/sysctl.conf
重启后验证sysctl net.ipv4.tcp_retries2
。注意,这会修改节点上的所有tcp通信。
es也会有自己的健康检查,间隔时间比tcp重传要短一些,Since these are application-level health checks their timeouts must allow for application-level effects such as garbage collection pauses. You should not reduce any timeouts related to these application-level health checks.
另外必须保证网络基础设施不会干涉节点之间的长连接。
Bootstrap Checks
es启动前会检查各项配置。
开发模式下不检查(http和transport默认绑定回环地址时),生产模式下检查。如果节点要加入集群,必须配置非回环地址,且不是单节点模式(discovery.type=single-node
),单节点模式会选自己为主节点,不会加入其它集群。使用jvm配置es.enforce.bootstrap.checks=true
可以强制开启检查
堆大小检查
默认自动根据节点角色和总内存进行配置,最小堆和最大堆要相同,避免resize导致gc暂停时间长。如果开启了bootstrap.memory_lock,可能导致resize的内存没有lock。
文件描述符检查
es需要使用很多文件描述符
Memory lock check
开启内存锁来防止内存数据交换
Maximum number of threads check
es进程能够创建的最大线程数,至少4096
最大文件大小
es的segment和translog可能很大,最好不限制单个文件大小
Maximum size virtual memory check
es和lucene使用mmap
映射es的索引,需要保证es有不限的地址空间
Maximum map count check
虚拟映射区域不限制
Client JVM check
不使用client jvm模式
Use serial collector check
不使用serial垃圾回收器
System call filter check
防止执行任意的系统调用被外部攻击
OnError and OnOutOfMemoryError checks
避免jvm退出时执行任意命令
Early-access check
jdk必须是release
G1GC check
jdk8u40之前的版本会导致es索引损坏
All permission check
保证不会授权java.security.AllPermission
Discovery configuration check
确保不会在默认配置下进行discovery。至少要配置以下配置中的一个:
discovery.seed_hosts
discovery.seed_providers
cluster.initial_master_nodes
集群第一次启动后要删掉cluster.initial_master_nodes
,重启或者添加节点时也不要使用,配置discovery.seed_hosts or discovery.seed_providers
,如果不需要集群,则配置discovery.seed_hosts: []
关闭discovery
Bootstrap Checks for X-Pack
Starting Elasticsearch
./bin/elasticsearch
./bin/elasticsearch -d -p pid
Stopping Elasticsearch
# 查看es的pid
$ jps | grep Elasticsearch
14542 Elasticsearch
$ ./bin/elasticsearch -p /tmp/elasticsearch-pid -d
$ cat /tmp/elasticsearch-pid && echo
15516
$ kill -SIGTERM 15516
严重错误退出:比如oom,会记录日志
Discovery and cluster formation
发现节点、选举master、组成集群、发布集群状态
Discovery
通过这个过程,集群信息模块找到其他的节点组成一个集群,当es启动时或者节点认为master已经挂掉时执行这个过程,直到找到master节点或者已经选举出了新的master
节点来自于seed host provider提供的seed addresses,以及上一个集群中有master资格的节点。过程分两个阶段:1,每个节点都检测这些seed address是否可以连通,并且识别是否是有master资格的节点;2,如果成功的话,将所有自己已知的有master资格的节点信息分享给这些节点,并且这些节点在响应中给出他们已知的有master资格的节点。然后节点再检测这些新发现的有master资格的节点。
如果当前节点不是有master资格的节点,那么就一直执行discovery过程,直到找到master,重试间隔默认1s,discovery.find_peers_interval=1s
如果当前节点是有master资格的节点,一直执行discovery过程,直到找到master或者找到足够多的有master资格的节点进行一次选举,如果这个过程没有很快发生,会进行重试,重试间隔默认1s,discovery.find_peers_interval=1s
discovery.seed_providers
,默认是settings-based,使用yml里配置的seed hosts;还有file-based,使用单独的一个配置文件,其他云环境的使用插件实现。
# settings-based
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11 # 没有端口的使用transport.profiles.default.port配置的第一个端口,fallback到transport.port配置的端口
- seeds.mydomain.com # 解析的所有ip地址都会尝试连接
# file-based 使用unicast_hosts.txt 也会查找discovery.seed_hosts里面的节点
discovery.seed_providers: file
$ES_PATH_CONF/unicast_hosts.txt
:
10.10.10.5
10.10.10.6:9305
10.10.10.5:10005
# an IPv6 address
[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
Quorum-based decision making
选举出master节点、改变集群状态是有master资格节点必须同时执行的两个基本任务,即使有节点失败这些动作也必须具有鲁棒性,es通过半数以上的响应来确定当前动作是否成功。优点就是允许节点失败。有master资格节点需要谨慎选择,避免出现脑裂。
es允许添加或者删除有master资格的节点。
当节点添加或者删除时,es通过更新集群的投票配置维护一个最优的错误容忍水平,投票配置当选举一个新的master或者提交一个新的集群配置时,有master资格节点的一个子集的响应数,半数以上响应才算成功。通常投票配置与有master资格的节点集合相同,有些情况也不一样。
为了确保集群可用,不能同时停止投票配置节点半数或半数以上的节点。
在节点加入或离开集群时,master必须发布集群状态更新来调整投票配置,需要花费一点时间,在删除其他节点之前需要等待完成。
Master elections:es在启动或者master节点失败时使用选举过程进行选举,任意一个有master资格的节点都可以发起一次选举,正常情况下,一次选举就会成功。只有当两个节点几乎同时发起选举时会失败,选举在每个节点以随机调度的方式发起,尽可能避免发生同时发起。节点在master选出之前会一直重试。
Voting configurations
Each Elasticsearch cluster has a voting configuration, which is the set of master-eligible nodes whose responses are counted when making decisions such as electing a new master or committing a new cluster state. Decisions are made only after a majority (more than half) of the nodes in the voting configuration respond.
Usually the voting configuration is the same as the set of all the master-eligible nodes that are currently in the cluster. However, there are some situations in which they may be different.
查看投票配置:GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config
如果cluster.auto_shrink_voting_configuration=false
(默认true),需要使用api手动移除掉投票配置中的一些节点。这个配置仅仅影响节点失败、节点添加及节点离开的管理任务的可用性。
偶数个有master资格的节点时,es会删掉一个,这样可以提高可用性。
当一个集群第一次启动时,需要指定启动配置,也就是一开始的投票配置是哪些节点。只配置有几个节点是不够的,需要配置是哪些个节点。启动配置必须来自于集群外部,因为集群自己没有安全的方法能确定这些配置。如果没有正确配置,可能会启动多个集群。
只有在最一开始的时候需要指定quorum,新的节点加入集群后会从master获取到所有的信息,已经加入集群的节点会存储所有重启需要的所有信息到磁盘。
Bootstrapping a cluster
集群第一次启动需要初始的有master资格的集合, cluster.initial_master_nodes
,配置在命令行或者yml里,每个配置的有master资格的节点都要相同,在集群组成后,需要删除,其他没有master资格的节点、有master资格但是加入现有集群的节点、重启一个或多个节点时都不要设置这个配置。
配置节点名称、节点主机名、transport的ip地址,transport的IP:PORT
cluster.initial_master_nodes:
- master-a
- master-b
- master-c
bin/elasticsearch -E cluster.initial_master_nodes=master-a,master-b,master-c
cluster.name
,es只会在集群名称相同时进行组成集群。默认elasticsearch
,如果在一个节点上启动了多个es,无须配置就可以自动组成一个集群,这是在开发模式下。
以下配置中任何一个配置后,就不会开启开发模式:
discovery.seed_providers
discovery.seed_hosts
cluster.initial_master_nodes
可以通过查看ip:9200中的uuid判断是否属于同一个集群,如果不是且要组成同一个集群,则关闭所有节点,删除data目录,配置cluster.initial_master_nodes
,然后重启所有节点,验证组成了同一个集群。
Publishing the cluster state
只有master节点可以改变集群状态,一次更新一批集群状态,当响应中有超过一半的有master资格的节点,则master提交当前的改变并且广播告诉其他节点可以应用新的集群状态。
master发布集群状态后允许一定的超时,cluster.publish.timeout
,默认30s(从publish开始计算),如果超时还没有收到半数以上的有master资格的节点确认信息(也就是commit之前),那么本次变更失败,当前master节点失败,尝试重新选举master。
如果在超时30s之前已经commit了本次变更,那么就认为是成功的,等待其他节点响应确认apply的响应或者直到30s超时。如果仍有一些没有响应确认apply了,master节点会继续等待cluster.follower_lag.timeout
,默认90s,如果仍然超时没有响应,则master将该节点从集群中移除。
es是一个peer-to-peer的系统,节点之间直接通向,高吞吐的那些api不直接与master交互,master的主要职责是维护全局的集群状态,包括当节点加入或移除时的分片重分配。
集群状态更新的性能是节点上存储速度以及节点之间网络通信的可靠性和延迟的函数,确保存储和网络性能足够好来满足性能目标。
Cluster fault detection
master周期的检查所有节点,确保可连接并且是健康的,所有节点也周期的检查master。
es允许这些检查偶尔失败,只有当连续失败多次之后才会认为错误。相关配置cluster.fault_detection.*
,master节点检查错误会移除错误的节点,节点检查master错误会重新进行discovery(查找master节点或者发起一次选举)。
另外,每个节点也会周期的写一个小文件到data目录,验证data路径是健康的。如果data目录不健康节点会从集群中移除,直到data目录恢复,相关配置monitor.fs.health
master也会移除那些更新集群状态超时的节点(默认120s,30s+90s)
Add and remove nodes in your cluster
如果要添加一个节点到多master-eligible的集群中,除了配置cluster.name
,还需要配置discovery.seed_hosts
,以便能够找到集群的所有节点。
推荐有一个小的固定数量的有master资格的节点。
添加有master资格的节点时,会向集群发送join请求,可能会加入到投票配置里。
如果一次停止一半或一半以上的有master资格的节点,集群将不可用。最好一次移除一个,并且等待集群自动调整完成(投票配置、错误容忍水平,也就是副本及分片节点重分配)。
如果只有两个有master资格的节点,仍然想移除其中的一个,可以手动将一个节点从投票配置中移除,这样停止这个节点就不会有问题了。当然,也可以手动移除多个节点,然后shutdown他们,就不用一个一个shutdown了
# Add node to voting configuration exclusions list and wait for the system
# to auto-reconfigure the node out of the voting configuration up to the
# default timeout of 30 seconds
POST /_cluster/voting_config_exclusions?node_names=node_name
# Add node to voting configuration exclusions list and wait for
# auto-reconfiguration up to one minute
POST /_cluster/voting_config_exclusions?node_names=node_name&timeout=1m
# voting exclusions list是存储在集群状态里的,可以通过api查看
GET /_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions
voting exclusions只有在需要移除超过一半或一半以上的有master资格的节点时使用,其他时候不需要使用。
voting exclusion是有限制的,cluster.max_voting_config_exclusions
,默认10,因为这个是有数量限制的,所以需要清除,正常情况下,一般是es集群需要维护的时候使用,在维护完要清除掉。正常情况下应该voting exclusion应该没有任何节点。
# Wait for all the nodes with voting configuration exclusions to be removed from
# the cluster and then remove all the exclusions, allowing any node to return to
# the voting configuration in the future.
# 会等所有节点删除这个配置 同步新的投票配置(跟其他修改集群状态的流程相同)
DELETE /_cluster/voting_config_exclusions
# Immediately remove all the voting configuration exclusions, allowing any node
# to return to the voting configuration in the future.
# 直接删除 不等新的投票配置同步
DELETE /_cluster/voting_config_exclusions?wait_for_removal=false
Full-cluster restart and rolling restart
整个集群重启:
- 因为关掉一个节点,这个节点上的副本分片会在超时后移动到别的节点上,默认1分钟,为了避免1分钟内无法全部停止节点,可以关闭副本分配
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}
- 停止索引数据,执行flush,将那些在主分片上还没有复制到副本上的数据同步,这个api已经被deprecated,8.0已经移除
POST _flush/synced
- 关掉所有节点,执行必要的操作
- 重启节点,可以先启动有master资格的节点,查看进度:
GET _cat/health
GET _cat/nodes
- 等所有的节点都加入,并且集群是yellow状态
- 重新开启副本分配,并查看进度
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
}
}
GET _cat/health
GET _cat/recovery
滚动重启,与整个集群类似:
- 关闭副本分配
- 停止不必要的数据,可以加速后续副本恢复,执行flush
POST /_flush
- 停止这个节点,执行必要的操作
- 重启节点,查看日志是否加入了集群
GET _cat/nodes
- 重新开启副本分配,并查看进度
- 重复以上步骤,分别重启其他节点
Remote clusters
TODO
Set up X-Pack
es stack扩展,默认安装es的时候,x-pack也安装了,使用所有的x-pack特性有30天试用期,需要订阅
Configuring X-Pack Java Clients
使用x-pack功能,客户端需要有相关的依赖
Plugins
增强es的基本功能,如添加定制的mapping类型,参考:https://www.elastic.co/guide/en/elasticsearch/plugins/7.17/index.html
Upgrade Elasticsearch
es支持不中断服务的情况下滚动更新,也可以全部重启直接更新
Index modules
创建索引及控制索引所有相关方面的模块。
索引配置,可以针对每个索引进行配置。
- 静态配置:只有当创建索引或者索引关闭后才可以配置
- 动态配置:可以使用api动态修改
Changing static or dynamic index settings on a closed index could result in incorrect settings that are impossible to rectify without deleting and recreating the index. ???
静态索引配置:
# 每个索引的分片数,默认1,只能在创建的时候配置,最大1024,避免错误创建导致集群不稳定,可以通过export ES_JAVA_OPTS="-Des.index.max_number_of_shards=128"修改限制
index.number_of_shards
# 和前面的一起确定数据被存到哪个分片,默认值取决于前者
index.number_of_routing_shards
Analysis
将string转化为term,添加到倒排索引中,以便能够检索
Index Shard Allocation
这个模块提供每个索引的设置来控制分片如何分配到节点
Index-level shard allocation filtering
索引级别的分片分配,可以指定某个索引的数据都分配到某些节点
Delaying allocation when a node leaves
一个节点离开后,maste节点会提升其他节点上的副本分片(之前主分片在离开节点上的)为主节点。然后分配缺失的副本数到其他节点上。最终会rebalance集群中所有的分片。
默认会等待1m后进行副本分片的重新分配(需要拷贝副本分片的所有数据),index.unassigned.node_left.delayed_timeout
。如果重新分配过程中,之前的节点恢复,那么重新分配过程会被取消。
Index recovery prioritization
索引分片恢复有优先级,index.priority
越大越优先,后创建的优先,index名称排序靠后优先
Total shards per node
集群级别的分配器(主分片)试图将一个索引尽可能的分片到多个节点,但是也取决于有多少分片和索引、索引多大。
单个索引在单个节点最多分配的分片(包括主分片和副本分片)index.routing.allocation.total_shards_per_node
,默认无限制
不管索引,集群层面限制cluster.routing.allocation.total_shards_per_node
Index-level data tier allocation filtering
索引层面的数据绑定,比如index.routing.allocation.include._tier_preference to data_warm,data_hot
,如果data_warm节点挂了,那么索引就会被relocate到data_hot
Index blocks
用于限制索引的操作,比如读、写、元数据操作,限制某个索引只读、只读允许删除、不允许读、不允许写、不允许读写元数据。如何关闭?
Mapper
这个模块是类型映射定义的注册中心,详细参考mapping模块:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping.html
Merge
一个es分片对应一个Lucene索引,一个Lucene索引会分成很多段,段是实际存储数据的,段不可变,小的段会周期性的合并来保持索引的大小。
index.merge.scheduler.max_thread_count
,单个分片合并时最大线程数,如果是机械硬盘,设置为1,固态硬盘默认即可。
Similarity module
打分、排名模型,定义了文档匹配的得分,相似性是针对每个字段的,映射可以定义每个字段的不同相似性。一般默认的就足够了。
Slow Log
对每个分片查询性能的日志,默认不开启,可以分别记录query和fetch阶段。可以与请求级别的耗时进行对比
也可以查看索引性能的日志。
Store
对索引数据的实际如何存储进行配置,不建议修改
Translog
es的flush过程是做一次Lucene提交,并开启新的事务。Lucene事务提交是非常昂贵的操作。flush是后台自动执行的,不会让translog太大
The data in the translog is only persisted to disk when the translog is fsynced and committed. In the event of a hardware failure or an operating system crash or a JVM crash or a shard failure, any data written since the previous translog commit will be lost.
translog提交之前的数据可能会丢失。默认index.translog.durability=request
,每一个索引、删除、更新、bulkrequest都会在translog在主节点及每个副本节点提交成功之后返回。如果配置为async
,则每个间隔刷新一次index.translog.sync_interval
。事务日志默认最大为512mb,超过会进行一次Lucene提交,避免分片恢复时花费太长时间重放translog
History retention
es有时需要重放操作,比如分片离线时,重放一些操作比重新拷贝整个分别要更容易。
在Lucene级别,只有两个写操作,创建新文档和删除文档,更新文档通过原子化操作创建新文档和删除旧文档实现。es使用软删除来保留Lucene中的删除记录以便后续能够重放。
使用shard history retention
租约机制来追踪将来需要重放的操作。分片失败的时候会停止更新租约,这样的es就会保留此后的所有操作以将来进行重放。但是租约只持续一段时间,如果分片没有很快恢复,它的租约可能会失效,避免由于分片一直没有恢复,es要一直保留所有的操作。租约失效之后,es就可以删除历史操作。如果分片在租约失效之后恢复,那么它就需要从主分片拷贝整个分片。默认租约12h
软删除默认是开启的,也可以在创建索引或者静态配置中关闭。即使关闭了软删除,有时也可以从translog拷贝缺失的操作进行恢复。
关掉之后,跨集群复制就不起作用了。
租约保证了Lucene索引合并期间软删除是保留的,如果软删除在复制到其他节点之前已经合并了,那么接下来的过程会失败由于leader不完整的历史。意思是合并完软删除操作就删掉了?
Index Sorting
当创建一个新的索引时,可以配置每个分片的里面的segment是怎么排序的,默认Lucene没有使用任何排序,
如果有排序的话,在search的时候,可能会提前终止匹配,避免每个文档都进行匹配。
Indexing pressure
索引数据到es会以内存和cpu的形式增加系统负载,每个索引操作包括coordinating, primary, and replica
阶段。索引压力可以来自索引请求或者内部机制,比如分片恢复、跨集群复制,如果太多索引操作同时进行,集群会变得饱合,进而影响其他操作,比如搜索、集群协调、后台处理。
为了防止这些问题,es内部会监控索引负载,当负载超过一定的限制后,新的索引会被拒绝。
indexing_pressure.memory.limit
默认堆大小的10%,限制未完成的索引请求大小。
索引阶段的一开始,es会计算每个索引请求使用的字节数,直到索引的最后阶段才会释放。
coordinating or primary stage
阶段:当未完成的coordinating, primary, and replica indexing
字节数超过配置的限制,节点就会拒绝新的索引工作。
replica stage
阶段:未完成的replica indexing
字节数超过1.5倍配置的限制,节点就会解决新的索引工作。这种设计意味着,随着节点上的索引压力越来越大,它们自然会停止接受coordinating和primary工作,转而接受未完成的的replica工作。
可以通过node stats api检索索引压力指标
indexing_pressure.memory.limit
,超过这个配置,拒绝coordinatoing和primary操作,超过1.5倍,拒绝新的replica操作。
Mapping
mapping是定义一个文档和它的字段如何存储和索引的过程。
mapping除了定义字段的类型,还包含源数据,如_source
。
Dynamic mapping
es会对文档中的新字段自动创建mapping。dynamic templates
可以根据匹配条件定义定制的mapping
Explicit mapping
可以指定每个字段的类型,比如string字段是否被认为是全文本、哪个字段包含数字、日期、日期的格式、定制规则来控制动态添加的字段。
runtime fields
可以改变schema而不用reindex,但是搜索性能会变慢
Settings to prevent mapping explosion
一个索引定义太多字段会导致mapping爆炸,进而导致oom及难以恢复的情况,可以设置mapping的相关配置进行限制。
Dynamic mapping
Index templates
可以配置新索引默认的mapping、setting和别名
Dynamic field mapping
字符串类型,如果可以通过date检测(默认开启),则定义为date类型,如果通过numeric检测(默认关闭),则是float或者long类型,否则是text和text.keyword类型
默认的date时间检测格式是[ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
,前者是严格的ISO格式。动态mapping时,可以关闭字段的date检测mappings."date_detection": false
。可以动态调整date检测的时间格式,mappings."dynamic_date_formats": ["MM/dd/yyyy"]
默认的numeric检测是关闭的,如果开启,可以检测字段中是字符串的数字格式
Dynamic templates
除了默认的mapping,允许更好的控制es如何映射字段。可动态mapping可以通过指定参数为true或runtime。动态模板则可以基于匹配用来动态的添加字段,以对每个字段设置是否开启自动映射。
匹配类型,将某一个类型的都映射为某个类型。匹配路径,将某些字段合并映射为一个新字段copy_to
模板变量:如将所有类型的数据都不进行doc_values存储,mappings."doc_values": false
,这是使用mappings"type": "{dynamic_type}"
模板指定该字段原来的类型,同样,使用{name}
表示字段名
例子:
- 结构化搜索:默认es映射string为text及一个keyword字段,如果只进行keyword搜索,不进行文本分析,则可以匹配所有string类型,只匹配为keyword类型,反过来,如果只进行文本分析,则可以只匹配为text类型。以及配置runtime的一些自定义mapping
- 如果从来不使用得分进行排序,可以关闭norms,节省空间
mappings."norms": false
- 时间序列的数据,如果有些字段只用来聚合但是从来不用来过滤,可以关闭这些字段的索引节省空间和提高索引速度
mapping."index": false
Explicit mapping
创建索引时指定mapping,或者向存在的索引添加新字段的mapping。
除了支持的mapping参数,不能改变现有字段的mapping,否则会导致已经索引的数据无效。
Runtime fields
查询数据时使用的字段,可以用来定义字段而不改变实际索引的数据的schema
Field data types
每个字段都有field data type, or field type
Metadata fields
每个文档都有与之相关联的元数据字段,如_index
。一些元数据的行为可以在创建mapping类型的时候定制
Mapping parameters
所有的mapping参数解释,Field data types
中使用的
Mapping limit settings
限制field mappings的数量,防止mapping爆炸。
Removal of mapping types
每个文档的_type
字段包含了类型名称,7.x被deprecated
Text analysis
TODO
Index templates(7.8开始,旧版本的查看legacy template document)
有两种 index templates and component templates
,组件模板是可以复用的构建mapping、settings、alias构建模块,当使用组件模板构建索引模板的时候,并不直接应用于索引。索引模板可以包含一组组件模板集合,也就是指定一组mapping、settings、alias
- 组合模板优先于传统模板,如果没有组合模板匹配索引,传统模板仍然可以匹配
- 如果索引创建时指定了setting也匹配了索引模板,前者的配置优先于后者
- 索引模板中的配置优先于组件模板的配置
- 如果data stream或者索引匹配多个索引模板,使用高优先级的
避免索引模式冲突,es有内建的索引模板,优先级是100
有模拟api,可以模拟一个索引或者模板实际的效果。
Data streams
存储只追加的时间序列数据到多个索引里,适合日志、事件、指标和其他持续产生的数据。管理data stream可以使用ILM
data stram由一个或多个隐藏的、自动生成的索引组成,data stream需要匹配索引模板来配置索引的mapping和setting。
每个文档都要有@timestamp
字段,date或date_nanos类型,如果没有在index模板中指定,则默认date类型。
读请求或读所有的索引,写请求会写到写索引里。不能向其他索引添加数据,也无法执行其他的clone/delete/freeze/shrink/split操作。
使用rollover可以创建新的写索引。建议使用ILM自动rollover,如果需要的话,也可以手动rollover。
Append-only
data stream是被设计为存在的数据比较少的场景,对已经存在的文档,data stream不能使用更新和删除请求,使用update by query和delete by query。不过可以执行更新和删除请求到后面的索引。如果需要更新和删除索引中的数据,可以使用别名。
Set up a data steam
- 创建IML policy
- 创建组件模板
- 创建索引模板
Ingest pipelines
在数据索引前执行一些处理逻辑,比如删除字段、提取数据、增加字段。
Enrich your data
适合不经常改变的数据,配置数据源
Processor reference
查看所有内置的processor,
Aliases
一组data stream或者索引的别名,但是两者不能同时定义相同别名。
alias api可以在一个原子操作里完成多个操作
Search your data
TODO
Query DSL
TODO
Aggregations
TODO
EQL
TODO
SQL
TODO
Scripting
TODO
Data management
存储在es的数据一般有两种:
- 内容:希望搜索的item的集合,比如产品目录
- 时间序列数据:持续产生的带有时间戳的数据,比如日志
Data tiers
同样角色的节点集合
ILM: Manage the index lifecycle
根据配置的ILM,根据性能、自愈性和保留需求自动管理索引。
- 当索引达到指定大小或者指定文档数量时创建新索引
- 每天、每周、每月创建索引并归档之前的
- 删除旧索引,以保持数据保留标准
ILM可以出发的actions:
- rollover,当索引达到指定大小或者指定文档数量时创建新的写索引
- shrink,减少主分片的数量
- force merge,触发强制merge来减少索引分片的segment
- freeze,freeze索引,使其只读
- delete,删除索引,
Concepts
ILM定义了5个索引生命周期阶段:
Hot: The index is actively being updated and queried.
Warm: The index is no longer being updated but is still being queried.
Cold: The index is no longer being updated and is queried infrequently. The information still needs to be searchable, but it’s okay if those queries are slower.
Frozen: The index is no longer being updated and is queried rarely. The information still needs to be searchable, but it’s okay if those queries are extremely slow.
Delete: The index is no longer needed and can safely be removed.
Phase transitions:后一个阶段的最小时间必须大于前一个阶段
Phase execution
Automate rollover
使用ILM自动rollover索引,如果不使用data stream也可以管理时间序列数据。(data steam更新和删除数据只能使用udpate/delete by query api。使用索引别名管理一组索引即可。)
data stream和索引别名有什么区别?都是自动更新写索引,其他索引只读,别名管理需要手动创建第一个写索引, TODO
Index lifecycle actions
移动分片、删除索引、强制merge、freeze索引、迁移索引、索引只读、rollover、searchable snapshot、设置优先级、shrink、unfollow、删除索引前等待snapshot完成。
Autoscaling
是为非直接使用设计的( Elasticsearch Service, Elastic Cloud Enterprise, and Elastic Cloud on Kubernetes.),直接使用不支持。
Monitor a cluster
TODO
Roll up or transform your data
TODO
Set up a cluster for high availability
es集群高可用
Snapshot and restore
备份集群、使用快照恢复集群
Secure the Elastic Stack
TODO
Watch (商业功能,需要license)
监听数据变化,执行必要的操作。
https://www.elastic.co/cn/subscriptions
Command line tools
es自带的一些命令行工具
How to
一些官方指导
一般推荐
不要返回大结果集:es是设计为搜索引擎,擅长返回满足query的top文档,不擅长大的工作负载,比如检索所有符合query的文档,如果是这样,使用scroll api
避免大文档:默认http.max_content_length
是100MB,超过这个显示es会拒绝索引,Lucene限制是2GB。即使查询不返回_source
,但是实际查询的时候需要fetch_id
,获取这个字段的时候如果文档很大会导致cost很大,这是由于文件系统缓存工作方式问题导致。
一般问题方法
- Mixing exact search with stemming
- Getting consistent scoring:
- 同一个query不同请求下的得分可能是不同的,如果一个分片有多个副本,查询是轮训多个副本的,因为每个分片的实际数据可能不同(es删除是标记删除,已经删除的数据可能也被统计在内)。解决办法:可以使用search中的preference参数,指定一个string的用户id,确保同一个用户的请求总是查询相同的分片,score更多时候是一致的。
- 相关性看起来是错的,得分大部分来自于索引统计,可以使用
dfs_query_then_fetch
参数,先收集所有分片的索引统计,在计算得分
- Incorporating static relevance signals into the score
Tune for indexing speed
- Use bulk requests,使用bulk request一般会比单文档索引有更好的性能,这个需要在一台服务器单个shard下做测试,但是每个bulk请求也不要太大,比如几十MB,即使索引性能更好,同时有太多的请求会占用较多的内存。
- Use multiple workers/threads to send data to Elasticsearch,单线程无法最大化使用es的索引能力,可以使用多线程更好的利用es资源,同时也可以减少fsync的消耗。
- 如果客户端返回了
TOO_MANY_REQUESTS (429)
,表示es无法保持当前的索引速度,多少线程才是最优的也是需要测试,逐渐增加线程数,直到es的IO和cpu都饱合了
- 如果客户端返回了
- Unset or increase the refresh interval,refresh时如果有索引请求正在处理,会降低索引速度。默认情况下,Elasticsearch 每秒定期刷新一次索引,但仅限于在过去 30 秒内收到一个或多个搜索请求的索引。如果请求不是很频繁,可以增加
index.refresh_interval
,减少刷新次数,可能会增加索引速度。 - Disable replicas for initial loads,如果有大量数据需要一次性加载到es,可以先把
index.number_of_replicas
调整为0,加载完成后再调整为原来的值。 - Disable swapping,关闭内存交换
- Give memory to the filesystem cache,使用至少节点的一半内存给文件系统缓存使用
- Use auto-generated ids,如果使用自己定义的id,es需要检查这个id在当前分片中是否存在,如果使用自动生成的id,可以避免检查,从而提高索引速度,索引越大,检查需要的时间就越大
- Use faster hardware,使用更快的硬件,如SSD
- Indexing buffer size,如果节点需要索引很多数据,确保
indices.memory.index_buffer_size
足够大,最多512MB,这个是每个分片的缓冲区。es默认会使用10%的整堆大小作为所有分片的共同缓冲区。 - Use cross-cluster replication to prevent searching from stealing resources from indexing,使用两个es集群,读写分离。
Tune for search speed
- Give memory to the filesystem cache,使用至少节点的一半内存给文件系统缓存使用
- Avoid page cache thrashing by using modest readahead values on Linux,search会导致很多随机IO读,当底层存储设备有很高的预读时,会导致有很多不必要的IO,特别是文件使用memory mapping时
- Use faster hardware,使用SSD、更高的CPU
- Document modeling,设计文档结构让搜索操作足够简单
- Search as few fields as possible
- Pre-index data,比如一直搜索的是一个范围的数据,可以将每个数据增加一个字段,指明该数据的范围,查询这个keyword新字段
- Consider mapping identifiers as keyword,并不是所有的数值类型都适合使用numeric类型,es为range查询优化了数值类型。但是对于term查询,keyword类型比numeric类型更快。如果数值不进行range查询,将字段设置为keyword一般查询会更快。如果不确定使用哪个,可以使用
multi-field
将字段映射为两种类型 - Avoid scripts,避免使用基于脚本的排序、聚合、script_score查询
- Search rounded dates,查询时使用近似时间以利用缓存
- Force-merge read-only indices,对于一些不在写的索引进行强制合并为一个segment
- Warm up global ordinals
- Warm up the filesystem cache
- Use index sorting to speed up conjunctions
- Use preference to optimize cache utilization
- Replicas might help with throughput, but not always
Tune for disk usage
- Disable the features you do not need,比如有些字段不索引可以关闭,比如text字段如果不使用评分可以使用
match_only_text
- Don’t use default dynamic string mappings,默认会把string字段作为text和keyword,如果只需要其中一个,这就比较浪费了
- Watch your shard size,大分片存储数据更高效,但是也有缺点,如恢复的话需要时间更长
- Disable
_source
,如果不需要原数据,可以不使用这个字段 - Use best_compression,存储数据使用压缩
- Force merge,大的segment存储数据更有效,减少segment的数量
- Shrink index,减少分片的数量
- Use the smallest numeric type that is sufficient,使用更小的数据类型,节约存储
- Use index sorting to colocate similar documents,排序后压缩,提高压缩比
- Put fields in the same order in documents,由于多个doc一起压缩,更有可能找到更长的重复string
- Roll up historical data,由于存储成本,可以存储一定比例的历史数据
Fix common cluster issues
Error: disk usage exceeded flood-stage watermark, index has read-only-allow-delete block
超过磁盘阈值(默认95%),索引只读。此时需要查看分片分配情况GET _cat/shards?v=true
es会自动将一些分片从达到阈值的节点上移走,如果要立即恢复,可以提高阈值,并且恢复写操作。解决办法:增加节点或者删除不使用的索引
Circuit breaker errors
es使用断路保护来防止jvm内存使用完,如果es评估一个操作会超过断路保护,就会停止操作返回错误。默认是95%jvm内存,如果内存持续超过85%就需要优化减少内存占用。
根据错误码或日志中的错误信息诊断短路保护原因。429
,data too large,是请求数据超过默认的100MB了
防止断路保护错误:减少jvm内存压力、避免使用text类型字段的fielddata功能、清除field cache
High CPU usage
es使用线程池管理cpu资源来处理并发操作
检查cpu高的原因:查看热点线程
解决办法:增加节点、拆分大的bulk request和multi-search,取消长时间执行的search
High JVM memory pressure
检查内存高的原因:查看gc日志
解决办法:减少分片数量,避免开销大的search、防止mapping爆炸(不要定义太多的字段)、拆分大的bulk request和multi-search、增加内存
Red or yellow cluster status
检查集群状态不健康的原因:查看未分配分配及原因
默认es不会向一个磁盘超过low disk watermark(默认85%)的节点分配分片
jvm内存占用太高如果触发了断路保护也会导致分片分配停止。
Size your shards
一个集群有太多索引和分片会导致集群响应效率低下,极端情况下可能导致集群不稳定
创建一个分片策略
最好的方法就是进行基准测试,因为不同的环境、不同的数据、不同的集群大小都不相同。
Sizing considerations
需要考虑的东西:
- 执行search时,每个分片都会有一个thread执行
- 每个索引和分片都有一定的资源占用,大多数情况下,少量的大分片比大量的小分片使用更少的资源
- es会自动平衡分片的节点位置
Best practices
- 删除索引,而不是删除文档,因为后者并不会立刻是否资源直到segment合并,前者会
- 使用data stream和ILM管理时间序列数据,优点就是自动rollover(自动创建写索引)、自动删除索引、容易改变分片策略如想要降低分片数、或者更多的分片数、更少的索引数、索引间隔更短。也就是每个新的索引都是一个改变当前策略的机会。
- 每个分片大小在10GB-50GB,太大则恢复慢,
- 1GB堆内存最多20个分片(不用包括那些几乎不怎么使用的系统分片)
- 避免一个节点有太多分片,可以使用参数强制控制
index.routing.allocation.total_shards_per_node
- 避免不必要的mapped field,es默认会自动为文档中的每个字段创建mapping,每个mapped的字段相对应的数据结构都存储在磁盘上,来进行高效的在该字段上进行search、检索、聚合。每个mapped的字段都会在内存中。
Reduce a cluster’s shard count
如果集群的分片已经太多了,可以用下面的方法减少
- 如果使用ILM的话使用
max_primary_shard_size
而不是max_age
避免创建空索引或者小分片。如果必须使用max_age
,可以增加索引的创建间隔,比如将每天创建一个索引改成每周或者每月 - 删除空索引和不使用的索引
- 强制在非高峰时段下合并不再写的索引,合并segment可以减少分片占用资源、提高search速度。注意合并操作会占用较多资源
- 如果索引不再写,可以减少分片数,使用shrink api
- 合并小索引,如daily的索引合并的到monthly的索引中,这样就可以删除原索引了
Troubleshoot shard-related errors
Use Elasticsearch for time series data
使用data stream实现
本文来自博客园,作者:Bingmous,转载请注明原文链接:https://www.cnblogs.com/bingmous/p/18164028