(1.4)elasticsearch集群基础

学习笔记:参考转自:阮一鸣丨Elasticsearch 核心技术与实战

【1】集群身份认证与用户

【1.1】数据安全性的基本需求

  1. 身份认证:鉴定用户是否合法
  2. 用户鉴权:指定哪个用户可以访问哪个索引
  3. 传输加密
  4. 日志审计:一些免费的方案如下
    • 设置 Nginx 方向代理
    • 安装免费的 Security 插件:Search Guard / ReadOnly Rest
    • X - Pack 的 Basic 版本
      • 从 ES6.8 & ES7.0 开始,Security 纳入 x-pack 的 Basic 版本中,免费试用一些基本的功能

【1.2】Authentication - 身份验证

(1)认证体系的几种类型

  • 提供用户名或者密码
  • 提供秘钥或者 Kerberos 票据

(2)Realms:X-Pack 中的认证服务

  • 内置 Realms (免费):File / Native (用户名密码都保存在 ES )
  • 外部 Realms (收费): LDAP / Active Directory / PKI / SAML / Kerberos

【1.3】RBAC - 用户鉴权

什么是 RBAC: Role Based access Control ,定义一个角色,并分配一组权限。

权限包括索引级,字段及,集群级的不同操作。然后通过将角色分配给用户,是的用户拥有这些权限

(1)用户 (2)角色 (3)角色允许的操作的权限 (4)所有的权限

【1.4】使用 Security Api 创建用户

image-20210429170635330

【1.5】实际配置密码登录

修改 ES 配置文件

#行2必须开,如果开了行2那行3也必须开,所以都要开,否则如果只设置了一个则无法启动
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

然后进入配置:

[root@node01 elasticsearch-7.7.0]# bin/elasticsearch-setup-passwords interactive
future versions of Elasticsearch will require Java 11; your Java version from [/opt/app/jdk1.8.0_181/jre] does not meet this requirement
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N]y
 
 
Enter password for [elastic]: 
Reenter password for [elastic]: 
Enter password for [apm_system]: 
Reenter password for [apm_system]: 
Enter password for [kibana]: 
Reenter password for [kibana]: 
Enter password for [logstash_system]: 
Reenter password for [logstash_system]: 
Enter password for [beats_system]: 
Reenter password for [beats_system]: 
Enter password for [remote_monitoring_user]: 
Reenter password for [remote_monitoring_user]: 
Changed password for user [apm_system]
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [beats_system]
Changed password for user [remote_monitoring_user]
Changed password for user [elastic]

验证:

curl --user elastic:123456 -X GET http://uathd02:9200/noah/_doc/1?pretty

【1.6】整合 kibana 使用密码登录连接 ES

vim /opt/app/kibana-7.7.0-linux-x86_64/config/kibana.yml 

elasticsearch.username: "kibana"
elasticsearch.password: "123456"

重启kibana 生效

【2】集群内部节点间的加密通讯

【2.1】为什么要加密通讯

加密数据:避免数据抓包,敏感信息泄露

验证身份:避免 impostor Node 假冒节点(加入集群以获取节点、集群状态等信息数据)

【2.2】为节点创建证书

TLS: TLS 协议要求 Trusted Certificate Authority ( CA ) 签发的 X.509 的证书

证书认证的不同级别:

  • Certificate -- 节点加入需要使用相同的 CA 签发的证书
  • Full Verification -- 节点加入集群需要相同 CA 签发的证书,还需要验证 Host name 或 IP 地址
  • No Verification -- 任何节点都可以加入,开发环境中用于诊断目的
#(1)生成 CA 单位文件
bin/elasticsearch-certutil
  # 后续敲2下回车,使用默认文件,使用空密码
  # 然后在当前目录下就创建了一个  elastic-stack-ca.p12 的文件
#(2)利用 CA 单位文件创建证书
bin/elasticsearch-certutil cert -ca eelastic-stack-ca.p12
  # 利用ca文件生成 证书,继续敲2下回车,空密码=》默认文件名
  # 然后在当前目录下就创建了签发的证书 elastic-certificates.p12
#(3)把证书放入到 $ES_HOME/config/certs   certs目录是手动创建的,记得要给权限啊
mkdir -p $ES_HOME/config/certs
chown -R es:es $ES_HOME/config/
cp elastic-certificates.p12  $ES_HOME/config/certs

【2.3】配置节点间的通讯

上面弄好之后,我们就需要修改一下配置文件,使用

xpack.security.transport.ssl.enabled:true
xpack.security.transport.ssl.verification_mode: certificate 
xpack.security.transport.ssl.keystore.path: $ES_HOME/config/certs/elastic-certificates.p12 
xpack.security.transport.ssl.truststore.path: $ES_HOME/config/certs/elastic-certificates.p12

【3】集群与外部间的安全通信

【3.1】配置 ES for Https

配置参数

同样也是这些,主要是 ,1,3,4行

xpack.security.transport.ssl.enabled:true
xpack.security.transport.ssl.verification_mode: certificate 
xpack.security.transport.ssl.keystore.path: $ES_HOME/config/certs/elastic-certificates.p12 
xpack.security.transport.ssl.truststore.path: $ES_HOME/config/certs/elastic-certificates.p12

也可以在启动命令上使用 -E 参数来添加;

  • 如 bin/elasticsearch -E node.name=node_1 -E cluster.name=my_es ......

  • 配好,重启 ES 服务器后,我们访问 http:192.168.175.131:9201 发现无法访问,访问被禁止了;

  • 我们使用 https:192.168.175.131:9201 后发现,是可以的;但会有一个警告,提示 Not Secure,因为我们是用的本地CA颁发的证书

【3.2】Kibana 连接 ES HTTPS

运行:

  • openssl pkcs12 -in elastic-certificates.p12 -cacerts -nokeys -out elastic-ca.pem
  • cp elastic-ca.pem $ES_HOME/config/certs/
  • chown -R es:es $ES_HOME/config/certs
elasticsearch.host: ["https://<your_elasticsearch_host>:9200"]
elasticsearch.ssl.certificateAuthorities: /path/to/your/elastic-ca.pem    
#就是之前上面 openssl 生成的文件,然后复制到es目录下,这个目录就指定 $ES_HOME/config/certs/elastic-ca.pem
elasticsearch.ssl.verificationMode: certificate

【3.3】使用 Https 访问 kibana

bin/elasticsearch-certutil ca --pem

image-20210430170534323

生成了一个 .zip 文件,我们解压后生成了,ca.crt 以及 ca.key ,拷贝到 $KIBANA_HOME/config/certs 目录下

image-20210430170556691

编辑 kibana.yml 文件

server.ssl.enabled: true
server.ssl.certificate: config/certs/ca.crt
server.ssl.key: config/certs/ca.key

重启 kibana 即可

测试:

  • 用 http + 地址 访问 kibana 是不行的
  • 用 https + 地址访问 就可以了

【4】常见的 ES 集群部署方式

【4.1】节点角色

Master eligible / Data / Ingest / Coordinating / Machine Learning

image-20210501162452030

【4.2】水平扩展:Coordinating only node

当系统中有大量的复杂查询及聚合的时候,增加 Coordinating 节点,增加查询的性能

  img

【4.3】读写分离

  img

【4.4】ES 集群中部署 Kibana

  img

【4.5】异地多活

  img

【4.6】Rack Awareness 跨机架架构,防止断电丢失

image-20210501173115762

ES的节点可能分布在不同的机架上

  • 当一个机架断电,可能会同时丢失几个节点
  • 如果一个索引相同的主分片和副本分片,同时在这个机架上,就有可能导致数据的丢失
  • 通过 Rack Awareness 的机制,就可以尽可能避免将同一个索引的主副分片同时分配在一个机架的节点上

**如何解决?通过 node.attr.my_rack_id=rack1 **

image-20210501173403812

这样达到的效果就是,如下图,主分片和副本分片 会分布到不同的机架上,一个机架断电,数据可以恢复

image-20210501173437747

如何确保必须要有2个以上的机架定义呢?

如下图,我们可以通过 cluster.routing.allocation.awareness.force.zone.values 来指定多个 node.attr.my_rack_id 的定义;

如果该参数设置了 rack1,rack2 ,但在 ES 集群中发现只有一个 rack1,那么就不会分配副本分片

image-20210501173604613

部署后,结果信息如下:确实是达到了效果

image-20210501173945824

【5】Hot 节点 & Warm 节点 架构

【5.1】为什么要 Hot 节点 & Warm 节点 架构?

  • 数据通常不会有 Update 操作;适用于 Time Based 索引数据(什么管理周期),同时数据量比较大的场景
  • 引入 Warm 节点,第配置大容量的机器存放老数据,以降低部署成本

两类数据节点,不同的硬件配置:

  • Hot 节点(通常使用 SSD ):索引不断有新文档写入。通常使用 SSD
  • Warm 节点(通常使用 HDD):索引不存在新数据的写入;同时也不存在大量的数据查询

【5.2】如何配置?

image-20210501165844034

实际配置如图:

image-20210501165858732

重启 es 后生效

【5.3】数据操作时如何分配到 hot / warm 节点?

核心参数是: "index.routing.allocation.require.my_node_type": "hot"

image-20210501170006568

注意,如果设置了这个,并维持了集群,那么如果 number_of_replicas 为1,那么必定要有2个或以上的 hot 标签,否则就无法保证数据的安全性和高可用性;是会报错,且集群监控状态变黄的

【5.4】如何把 旧数据迁移到 warm 节点

image-20210501172310759

【5.5】Rack Awareness 跨机架架构,防止断电丢失

image-20210501173115762

ES的节点可能分布在不同的机架上

  • 当一个机架断电,可能会同时丢失几个节点
  • 如果一个索引相同的主分片和副本分片,同时在这个机架上,就有可能导致数据的丢失
  • 通过 Rack Awareness 的机制,就可以尽可能避免将同一个索引的主副分片同时分配在一个机架的节点上

**如何解决?通过 node.attr.my_rack_id=rack1 **

image-20210501173403812

这样达到的效果就是,如下图,主分片和副本分片 会分布到不同的机架上,一个机架断电,数据可以恢复

image-20210501173437747

如何确保必须要有2个以上的机架定义呢?

如下图,我们可以通过 cluster.routing.allocation.awareness.force.zone.values 来指定多个 node.attr.my_rack_id 的定义;

如果该参数设置了 rack1,rack2 ,但在 ES 集群中发现只有一个 rack1,那么就不会分配副本分片

image-20210501173604613

部署后,结果信息如下:确实是达到了效果

image-20210501173945824

【5.6】Shard Filtering

Shard filtering

  • "node.attr" - 标记节点
  • "index.routing.allocation" - 分配索引到节点

image-20210501174338304

【6】分片的设计及管理

【6.1】单个分片

  • ES 7.0 开始,创建一个索引时,默认只有一个主分片(更低版本默认是5个主分片)
    • 单个分片,查询算分,聚合不准的问题都可以得以避免
  • 单个索引,单个分片的时候,集群无法实现水平扩展
    • 即新增的节点,无法实现水平扩展

【6.2】两个分片

多个节点,如果新增节点,集群会自动将分片移动,这叫 分片自动重新平衡

image-20210501182059968

【6.3】如何设置分片数

  • 当分片数 > 节点数
    • 一旦集群中有新的数据节点加入,分片就可以自动进行分配
    • 分配在重新分配时,系统不会有 downtime
  • 多分配的好处,一个索引如果分配在不同的节点,多个节点可以并行执行
    • 查询可以并行执行
    • 数据写入可以分散到多个机器

案例1:

  • 每天 1GB 的数据,一个索引一个主分片,一个副本分片
  • 需要保留半年,接近 360GB 的数据量

案例2:

  • 5个不同的日志,每天创建一个日志索引。每个日志索引创建 10 个主分片
  • 保留半年数据
  • 5 * 10 * 30 * 6 = 90000

分片过多带来的副作用

  • Shard 是 ES 实现水平扩展的最小单位
  • 过多设置分片数会带来一些潜在的问题
    • 每个分配是一个 Lucene 的额索引,会使用机器的资源。过多的分片会导致额外的性能开销
      • Lycene Indices / File descriptors / RAM / CPU
      • 每次搜索的请求,需要从每个分配上获取数据,且最后传输整合到 Coordinating 节点,增加负担
      • 分片的 Meta 信息由 Master 节点维护。过多,会增加管理的负担。经验值,控制分片总数在10 W 以内

【6.4】如何确定分片数?

如何确定主分片数?

  • 从存储的物理角度看
    1. 日志类应用,单个分片不要大于 50GB
    2. 搜搜类应用,单个分片不要超过20 GB
  • 为什么要控制分片存储大小
    1. 提高 update 的性能
    2. Merge 时,减少锁需要的资源
    3. 丢失节点后,具备更快的恢复速度 / 便于分片在集群内 Rebalancing

如何确定副本分片数

  • 副本是主分片的拷贝
    1. 提高系统的可用性:相应查询请求,防止数据丢失
    2. 需要占用和主分片一样的资源
  • 对性能的影响
    1. 副本会降低数据的索引速度(如写入、更新、删除):有积分副本就会有几倍的 CPU 资源消耗在索引上
    2. 会减缓对主分片的查询压力,但是会消耗同样的内存资源
      • 如果机器资源充分,提高副本数,可以提高整体查询的 QPS

调整分片总数设定,避免分配不均

ES 默认的分片策略会尽量保证节点上的分片大致相同

  • 扩容的新节点没有数据,导致新索引几种在新的节点
  • 热点数据过于几种,可能会产生新的问题

可以通过, 设置

index.routing.allocation.total_shards_per_node: 1  #设置每个索引在每个节点上可分配的主分片数
cluster.routing.allocation.total_shards_per_node: 1   

比如设置成 1,那就每个索引的主节点分配,就只能在1个节点上出现1个

【7】ES 集群的容量规划

【7.1】容量规划的因素

  • 一个集群总共需要多少个节点? 一个索引需要设置几个分片?
    • 规划上需要保持一定的余量,当负载出现波动,节点出现丢失时,还能正常运行
  • 做容量规划师,一些需要考虑的因素
    • 机器的软硬件配置
    • 单挑文档的尺寸 / 文档的总数据量 / 索引的总数据量(Time base 数据保留的时间) / 副本分片数
    • 文档是如何写入的 ( Bulk 的尺寸 )
    • 文档的复杂度,文档是如何进行读取的( 怎么样的查询和聚合 )

【7.2】评估业务的性能需求

  • 数据吞吐及性能需求
    • 数据写入的吞吐量,每秒要求写入多少数据?
    • 查询的吞吐量?
    • 单挑查询可接受的最大访问时间?
  • 了解你的数据
    • 数据的格式,数据的 Mapping
    • 实际的查询 和 聚合长的是什么样的

【7.3】常见用例

  • 搜索:固定大小的数据集
    • 搜索的数据集增长相对比较缓慢
  • 日志:基于时间序列的数据
    • 使用 ES 存放日志与性能指标。数据每天不断写入,增长速度较快
    • 结合 Warm Node 做数据的老化处理

【7.4】硬件配置

  • 选择合理的硬件,数据节点尽可能使用 SSD
  • 搜索等性能要求较高的场景,建议 SSD
    • 按照1:10 的比例配置内存和硬盘
  • 日志类和查询并发第的场景,可以考虑使用机械键盘存储
    • 按照 1:50 的比例配置内存和硬盘
  • 单节点数据建议控制在 2TB以内,最大不建议 超过 5TB
  • JVM 配置机器内存的一般, JVM 内存配置不建议超过 32 GB

【7.5】部署方式

  • 如果有大量的 pipeline 要处理,则可以配置几个 Ingest 专用节点,并且做好响应的自动平衡配置
  • 如果考虑可靠性高可用(数据节点超过3台),建议部署3台 专用的 Master 几点
  • 如果要复杂的查询、较高的QPS、聚合查询等,建议设置几个专用的 Coordinating 节点

【容量规划案例】固定大小的数据集

  • 一些案例:唱片信息库 / 产品信息
  • 一些特性
    • 被搜索的数据集很大,但是增长相对比较慢(不会有大量的写入)。更关心搜索和聚合的读取性能
    • 数据的重要性与时间范围无关。关注的是搜索的相关度
  • 估算索引的数据量,然后确定分片的大小
    • 单个分片的数据不要超过20GB
    • 可以通过增加副本分片,提高查询的吞吐量

【拆分索引】

  • 如果业务上有大量的查询是基于一个字段进行 Filter,该字段又是一个数量有限的枚举值
    • 例如订单所在的地区
  • 如果在单个索引有大量的数据,可以考虑将索引拆分成多个索引(比如,每个地区创建一个索引)
    • 查询性能可以得到提高
    • 如果要对多个索引进行查询,可是可以在查询中指定多个索引得以实现
  • 如果业务上有大量的查询是基于一个字段进行 Filter,该字段数值并不固定
    • 可以启用 Routing 功能,按照 Filter 字段的值,分不到集群中不同的 shard,降低查询时,相关的 shard,高CPU利用率

【容量规划案例】基于时间序列的数据

  • 相关的用案
    • 日志 / 指标 /安全相关的 Events
    • 舆情分析
  • 一些特性
    • 每条数据都有时间戳;文档基本不会被更新(日志和指标数据)
    • 用户更多的会查询近期的数据,对旧的数据查询相对较少
    • 对数据的写入性能要求较高

【创建基于时间序列的索引】

  • 创建 time - based 索引

    • 在索引的名字中增加时间信息
    • 按照 每天 / 每周 / 每月的分时进行划分
  • 带来的好处

    • 更加合理的组织索引,例如随着时间推移,便于对索引做的老化处理
      • 利用 Hot & Warm Architecture
      • 备份和删除以及删除的效率高 (delete by query 执行速度慢,底层也不会立刻释放空间,而 Merge 时才会释放资源)
  • 基于 Dete math 的方式实现

    • 容易使用
    • 如果时间发生变化,需要重新部署代码
      • <logs-{now/d}> | logs-2021.05.04
      • <logs-{now{YYYY.MM}}> | logs-2021.05.04
      • <logs-{now/w}> | logs-2021.05.04
      • \ POST /<logs-{now/d}>/_search

      • POST /%3Clogs-%7Bnow%2Fd%7D%3E/_search #上面那行需要做转义操作
  • 基于 Index Alias ,索引别名

    • 创建索引,每天 / 每周 / 每月

    • 在索引的名字中增加时间信息

    • POST _aliases
      {
      	"actions":[
      		{
      			"add":{
      				"index":"logs_2019-06-27"
      				"alias":"logs_write"
      			}
      		},
      		{
      			"remove":{
      				"index":"logs_2019-06-26"
      				"alias":"logs_write"
      			}
      		}
      	]
      }
      
      
      #别名创建其他方法 demo
      PUT /a
      {
      	"aliases":{
      		"now_info":{}
      	}
      }
      

【集群扩容】

  • 增加 Coordinating / ingest Node
    • 解决 CPU 和 内存开销问题
  • 增加数据节点
    • 解决存储的容量问题
    • 为避免分片分布不均的问题,要提前监控磁盘空间,提前清理数据或增加节点(70%)

【8】生成环境配置与上线清单

【8.1】开发模式、生产模式

  • 开发模式:必须使用 localhost,或使用 single-node 单节点模式。可以使用 localhost加入集群

  • 生产模式:必须使用实际IP 或 0.0.0.0,不能使用 localhost/127.0.0.1等回环地址;也不能使用 single-node 模式

  • 参数:(这两种模式核心实际区别就是,是否启动时需要做 bootstrap checks,启动检查)

  • http.host: localhost
    transport.bind_host: localhost
    discovery.type: single-node
    
  • 官网话术:

    • 默认情况下,Elasticsearch绑定到用于HTTP传输(内部)通信的环回地址。对于下载和使用Elasticsearch以及日常开发来说,这是很好的选择,但是对于生产系统则没有用。要加入集群,Elasticsearch节点必须可以通过传输通信到达。要通过非环回地址加入集群,节点必须将传输绑定到非环回地址,并且不能使用单节点发现。因此,如果Elasticsearch节点无法通过非环回地址与另一台机器形成集群,则认为该节点处于开发模式,如果它可以通过非环回地址加入集群,则该节点处于生产模式。

【8.2】bootstrap checks 启动检查

image-20210504164836221

【8.3】JVM 设定

  • 从ES 6 开始,只支持 64位的 JVM
    • 配置 config / jvm.options
  • 避免修改默认配置
    • 将内存 Xms 和 Xmx 设置成一样,避免 堆调整大小时引发停顿(heap resize)
    • Xmx 设置不要超过物理内存的 50%,剩下的需要交给 lucene;
      • 单个节点上,Xmx 最大内存建议不要超过 32G 内存;
      • 因为在内存少与32G的时候,会使用一个内存对象指针压缩的机制;超过32G 就不会使用,可能会引起性能的下降
      • 生成环境,JVM 必须使用 Server 模式
      • 关闭 JVM 的 Swapping

【8.4】 ES 集群的API设定

  • 静态设置和动态设置

    • 静态配置文件尽量简洁:按照文档设置所有相关系统参数。elasticsearch.yml 中尽量只写必备参数
  • 其他的设置项可以通过 API 动态进行设定,动态设置分 transient(临时的、当前的)和 persistent(永久的)两种,都会覆盖 elasticsearch.yml 中的设置

    • Transient 在群集重启后会丢失
    • Persistent 在群集重启后不会丢失
  • 优先级如下:

    1. Transient Settings
    2. Persistent Settings
    3. Command-line Settings
    4. Config file Settings
  • 使用案例

  • PUT /_cluster/settings?flat_settings=true
    {
      "transient" : {
        "indices.recovery.max_bytes_per_sec" : "20mb"
      }
    }
    

【最佳实践】网络

  • 单个集群不要跨数据中心进行部署(不用使用 WAN)
  • 节点之间的 时延(hops) 越少越好
  • 如果有多快网卡,最好将 transport 和 htpp 绑定到不同的网卡,并设置不同的防火墙 Rules
  • 按需要,为 Coordinating Node 或 Ingest Node 配置负载均衡

【最佳实践】内存设定

  • 内存大小要根据 Node 需要存储的数据来进行估算
    • 搜索类的比例建议: 1:16
    • 日志类: 1:48 - 1:96 之间
  • 总数据量 1T ,设置一个副本 = 2T 总数据量(假设设置的一个节点最大内存为31GB)
    • 如果搜索类,每个节点 31G内存 * 16 = 496 G,加上预留空间。所以每个节点最多 400G 数据,最少需要 5个数据节点
    • 如果是日志类,每个节点 31G内存 * 50 = 1550 GB,2个数据节点即可

【最佳实践】存储

  • 推荐使用 SSD,使用本地存储。避免使用 SAN NFS / AWS /Azure filesystem
  • 可以在本地指定多个 "path.data",以支持使用多快磁盘
  • ES本身提供了很好的 HA 机制;无需使用 RAID 1/5/10
  • 可以在 Warm 节点上使用 机械音频(Spinning disk) ,但是需要关闭 并行发生Merges(Concurrent Merges)
    • Index.merge.scheduler.max_thread_count: 1
  • 优化(trim) 你的 SSD

【最佳实践】服务器硬件

  • 建议使用中等配置的机器,不建议使用过于强劲的硬件配置
  • 不建议在一台服务器上运行多个节点

【最佳实践】集群优化参数配置

(1). 阈值限流

  • 为 迁移(Relocation) 和 恢复(Recovery ) 设置限流,避免过多并行线程同时执行,对集群产生性能影响
  • Recovery
    • Cluster.routing.allocation.node_concurrent_recoveries: 2
  • Relocation
    • Cluster.routing.allocation.cluter_concurrent_rebalance: 2

(2).关闭 Dynamic Indexes

从长远的角度来看,是需要禁用它的,避免后续字段太多,索引体积庞大且混乱

  • 可以考虑关闭动态索引创建

    • PUT _cluster/settings
      {
      	"persistent":{
      		"action.auto_create_index":false
      	}
      }
      
  • 或可以通过模板设置白名单的方式,只允许符合某些命名规范的才能动态索引创建

【最佳实践】集群安全设定

  • 为 ES 和 kibana 配置安全功能
    • 打开 Authentication & authorization
    • 实现索引和字段级别的安全控制
  • 节点间通信加密
  • Enable HTTPS
  • Audit logs

【9】监控 ES 集群

【9.1】ES status 相关的API

  • Node Stats:_nodes/stats
  • Cluster Stats:_cluster/stats
  • Index Stats:_index_name/_stats
  • 全文状态:
    • _cat/

【9.2】ES Task/Thread API

  • 查看 Task 相关的 API
    • Pending Cluster Tasks API: GET _cluster/pending_tasks
    • Task Management API: GET _tasks(可以用了 cancel 一个 Task)
  • 监控 Thread Pools
    • GET _nodes/thread_pool
    • GET _nodes/stats/thread_pool
    • GET _cat/thread_pool?v
  • ES _cat 查看 ES 全局信息
    • /_cat/allocation
      /_cat/shards
      /_cat/shards/{index}
      /_cat/master
      /_cat/nodes
      /_cat/tasks
      /_cat/indices
      /_cat/indices/{index}
      /_cat/segments
      /_cat/segments/{index}
      /_cat/count
      /_cat/count/{index}
      /_cat/recovery
      /_cat/recovery/{index}
      /_cat/health
      /_cat/pending_tasks
      /_cat/aliases
      /_cat/aliases/{alias}
      /_cat/thread_pool
      /_cat/thread_pool/{thread_pools}
      /_cat/plugins
      /_cat/fielddata
      /_cat/fielddata/{fields}
      /_cat/nodeattrs
      /_cat/repositories
      /_cat/snapshots/{repository}
      /_cat/templates
      /_cat/ml/anomaly_detectors
      /_cat/ml/anomaly_detectors/{job_id}
      /_cat/ml/trained_models
      /_cat/ml/trained_models/{model_id}
      /_cat/ml/datafeeds
      /_cat/ml/datafeeds/{datafeed_id}
      /_cat/ml/data_frame/analytics
      /_cat/ml/data_frame/analytics/{id}
      /_cat/transforms
      /_cat/transforms/

【9.3】慢查询

  • 支持将分片上,Search 和 Fetch 阶段的慢查询写入文件
  • 支持为 Query 和 Fetch 分别定义阈值
  • 索引级的动态设置,可以按需设置,或者通过 Index Template 统一设置
  • Slog log 文件通过 log4j2.properties 配置
PUT my_index/
{
	"settings":{
		"index.search.slowlog.threshold"
			"query.warn":"10s",
			"query.info":"3s",
			"query.debug":"2s",
			"query.trace":"0s",
			"fetch.warn":"1",
			"fetch.info":"600ms",
			"fetch.debug":"400ms",
			"fetch.trace":"0s",
	}
}

【9.4】如何创建监控 Dashboard

  • 开发 ES plugin ,通过读取相关的监控 API,将数据发送到 ES,或者 TSDB
  • 使用 Metricbeats 搜集相关指标
  • 使用 kibana 或 grafana 创建 dashboard
  • 可以开发 ES Exporter,通过 Prometheus 监控 ES 集群

【10】诊断集群的潜在问题

【10.1】集群运维面临的问题

  • 用户集群数量太多,业务场景差异大
  • 使用与配置不当,优化不够
    • 如何让用户更加高效和正确的使用 ES
    • 如何让用户更全面的了解自己集群的使用状况
  • 发现问题之后,需要防患于未然

【10.2】集群绿色的意义

  • 绿色只是其中一项指标。显示分片是否已经正常
  • 监控指标多并且分散
    • 指标的含义不够明确直观
  • 稳定分析定位的门槛较高
    • 需要具备专业知识

【10.3】为什么要诊断集群的潜在问题

  • 防患于未然,避免集群崩溃
    • Master 节点 / 数据节点 宕机 -- 负载过高,导致节点失联
    • 副本丢失,导致数据可靠性受损
    • 集群压力过大,数据写入失败
  • 提升集群性能
    • 数据节点负载不均衡(避免单节点瓶颈) / 优化分片,segment
    • 规范操作方式(利用别名 / 避免 Dynamic Mapping 引发过多字段,对索引的合理性进行管控)

【10.4】eBay diagnostic tool

  • 集群监控状态,是否有节点丢失
  • 资源使用合理性
    • CPU、内存、磁盘 使用状况分析 / 是否存在节点负载不平衡 / 是否需要增加节点
  • 业务操作合理性
    • 集群状态变更频率,是否在业务高峰期有频繁操作
    • 慢查询监控与分析
  • 索引合理性
    • 索引总数不能过大
    • 副本分片尽量不要设置为 0
    • 主分片尺寸检测
    • 索引的字段总数(Dynamic Mapping 关闭)
    • 索引是否分配不均
    • 索引 Segment 大小诊断分析
    • 数据节点之间的负载偏差是否过多
    • 冷热数据分片是否正确(丽日,cold 节点上的索引是否设置成只读)

【10.5】 阿里云 EYOU 诊断工具

image-20210504185002376

【11】集群状态变红、变换 问题处理

【11.1】集群健康度

  • 分片监控

    • 红:至少有一个主分片没有分配
    • 黄:至少有一个副本没有分配
    • 绿:主副本分片全部正常分片
  • 索引健康:最差的分片的状态

  • 集群健康:最差的索引的状态

    image-20210504185944581

【11.2】Health 相关的 API

API 名称 作用描述
GET _cluster/health 集群的状态(检查节点数量)
GET _cluster/health?level=indices 所有索引的监控状态(查看有问题的索引)
GET _cluster/health/my_index 单个索引的监控状态(查看具体的索引)
GET _cluster/health?level=shards 分片级别的索引
GET _cluster/allocation/explain 返回第一个未分配 Shard 的原因

【案例1】集群状态变红

测试数据过程:

PUT mytest
{
	"settings":{
		"number_of_shards":3,
		"number_of_replicas":0,
		"index.routing.allocation.require.box_type":"hott"
	}
}

#分析过程
#(1)上面的操作操作后,下面操作发现集群变红
	GET _cluster/health/
#(2)查看索引级别,找到变红的索引,直接搜索 red 关键字
	GET _cluster/health?level=indices
#(3)Explain 查看变红的原因
	GET _cluster/allocation/explain
#(4)通过上面(3)的查看,发现最后deciders 下写着
	node does not match index setting [index.routing.allocation.require] filters [box_type:"hott"]
#(5)由(4)中报错得知,说是无法匹配这个 box_tpe(这个也是我们自己定义的) 对应的 hott,我们去 _cat/nodeattrs查看
	GET _cat/nodeattrs
#(6)发现确实没有 hott 的标签,只有 hot 的标签,那么是它写错了,所以导致索引无法分配主分片
#(7)删除索引,集群变绿。重新创建搜因,并且制定正确的 routing box_type,索引创建成功。集群转成绿色,且持续绿色
  • 症状:集群状态变红(主分片无法分配)
  • 分析:通过 allocation Explain API 发现,创建索引失败,因为无法找到标记了相应 box_type 的节点
  • 解决:删除索引,集群变绿。重新创建搜因,并且制定正确的 routing box_type,索引创建成功。集群转成绿色,且持续绿色

【案例2】集群状态变黄

测试数据过程:

PUT mytest
{
	"settings":{
		"number_of_shards":3,
		"number_of_replicas":1,
		"index.routing.allocation.require.box_type":"hot"
	}
}
#分析过程
#(1)上面的操作操作后,下面操作发现集群变红
	GET _cluster/health/
#(2)查看索引级别,找到变红的索引,直接搜索 red 关键字
	GET _cluster/health?level=indices
#(3)Explain 查看变红的原因
	GET _cluster/allocation/explain
#(4)通过上面(3)的查看,发现最后行deciders 下写着
	the shard cannot be allocated to the same node on which a copy of the shard already exists
#(5)查看节点属性,发现确实是只有一个 hot 标签的节点
	GET _cat/nodeattrs
  • 症状:集群状态变黄(副本分片无法分配)
  • 分析:通过 _cluster/allocation/explain API 发现无法再相同的节点上创建副本
  • 解决:将索引的副本数设置为0,或者通过增加节点 并且 节点的 box_type 为 hot

【11.3】分片没有被分配的一些原因

  • index_create :创建索引导致。在索引的全部分片分配完成之前,会有端在的 Red,不一定代表有问题

  • cluster_recovery:集群重启阶段,会有这个问题

  • index_reopen:open 一个之前 Close 的索引

  • dangling_index_imported:一个节点离开集群期间,有索引被删除。

    这个节点重新返回时,会导致 Dangling 的问题(再删一次即可)

  • https://www.elastic.co/guide/en/elasticsearch/reference/7.11/cat-shards.html

【11.4】集群状态变化=》常见问题与解决办法

  • 集群变红,需要检查是否有节点离线。如果有,通常通过重启离线的节点可以解决;
  • 由于配置导致的问题,需要修复相关的配置(例如我们2个案例中错误的 box_type,错误的副本数)
    • 如果是测试用的索引,可以直接删除
  • 因为磁盘空间限制,分片规则(shard filtering)引发的,需要调整规则或者增加节点
  • 对于节点返回集群,导致的 dangling 变红,可以直接删除引起 dangling 的索引

【11.5】集群 red & yellow 问题总结

  • red & yellow 是集群运维中常见的问题

  • 除了集群故障,一些创建,增加副本等操作,都会导致集群短暂的 Red 和 Yellow,所以监控和报警是需要设置一定的演示

  • 通过检查节点数,使用 ES 提供的相关的 API,找到真正的原因

  • 可以指定 Move 或者 Reallocate 分片

  • #使用 reroute API,把一个分片移到另外一个节点
    POST _cluster/reroute
    {
    	"commands":[
    	{
    		"move":{
    			"index":"index_name",
    			"shard":0,
    			"from_node":"node_name_1",
    			"to_node":"node_name_2"
    		}
    	}
    	]
    }
    
    #另外一种办法
    POST _cluster/reroute?explain
    {
    	"commands":[
    	{
    		"allocate":{
    			"index":"index_name",
    			"shard":0,
    			"node":"need_move_to_node_name"
    		}
    	}
    	]
    }
    

【12】提高 ES 集群写性能

【12.1】提高写入性能的方法

  • 写性能优化的目标:增大写吞吐量(Events Per Second),越高越好

  • 客户端:多线程,批量写

    • 可以通过性能测试,确定最佳文档数量
    • 多线程:需要观察是否有 Http 429 返回,实现 Retry 以及线程数量的自动调节
  • 服务器端:单个性能问题,往往是多个因素造成的。需要先分解问题,在单个节点上进行调整并且结合测试,尽可能压榨硬件资源,以达到最高吞吐量

    • 使用更好的硬件。观察 CPU / IO Block
    • 线程切换 / 堆栈状况

【12.2】服务端优化写入性能的一些手段

  • 降低 IO 操作
    • 使用 ES 自动生成的文档ID / 一些相关的 ES 配置,如 Refresh Interval
  • 降低 CPU 和 存储开销
    • 减少不必要的分词 / 避免不需要的 doc_values / 文档的字段尽量保证相同的顺序,可以提高问的压缩率
  • 尽可能做到 写入和分片的负载均衡,实现水平扩展
    • 请求的平均分散 Shard Filtering / Write Load Balancer
  • 调整 Bulk 线程池 和 队列
  • 优化写入性能
    • ES 的默认设置,已经综合考虑了数据可靠性,搜搜的实时性质,写入速度,一般不要盲目修改
    • 一切优化,都要基于高质量的数据建模

【12.3】文档建模的最佳实践参考

(1)关闭无关的功能

image-20210505180236931

  • 只需要聚合不需要搜索,Index 设置成 False
  • 不需要算分,Norms 设置成 false
  • 不要对字符串使用默认的 dynamic mapping。字段数量过多,会对性能产生较大的影响
  • Index_options 控制在创建倒排索引时,哪些内容会被添加到倒排索引中。优化这些设置,一定程序可以节约CPU
  • 考虑关闭 _source(会影响reindex 和 update,慎重),减少 IO 操作;(适合指标型数据)

(2)针对性能的取舍

  • 如果需要追求极致的写入速度,可以牺牲数据的可靠性以及搜索实时性以换取性能
    • 牺牲可靠性:将副本分片设置为0,写完再调整回去
    • 牺牲搜索实时性:增加 Refresh Interval 时间
    • 牺牲可靠性:修改 Translog 的配置

【12.4】数据写入的过程

  • Refresh(可优化点)
    • 当数据写入时,数据会同时写入 index buffer 以及 Translog 中,以 refresh_interval 为间隔时间,定期情况 buffer,生成存于文件系统缓存中的 segment,并且开放查询,以提升搜索的实时性
    • 优化:降低 Refresh 的频率
      • 增加 refresh_interval 的数值。默认为 1s ,如果设置成 -1,会禁止自动 refresh
        • 避免过于频繁的 refresh,而生成过多的 segment 文件
        • 但是会降低搜索的实时性
      • 增大静态配置参数: indices.memory.index_buffer_size
        • 默认是 JVM 的 10%,超过则会自动触发 refresh
  • Translog(可优化点)
    • Segment 没有写入磁盘,即使发生了宕机,重启后数据也能恢复,ES 6.0 后,默认配置是每次请求都会落盘
    • 优化
      • 降低写磁盘的频率,但会降低容灾能力
        • index.translog.durability:默认是 request,每个请求都会落盘。设置成 async,异步写入
        • index.translog.sync_interval:默认 1s 一次,设置为 60S,每分钟执行一次
        • index.translog.flush_threshod_size:默认 512Mb,可以适当调大。当 translog 超过该值,会触发 flush
  • Flush(很难优化)
    • 文件系统缓存中的 segment 落盘 / 更新 commit point 并且写入磁盘。 ES 自动完成,优化点不多
    • 删除旧的 translog 文件
    • 默认 30m 一次,或者 translog(默认 512M )满

【12.5】分片设置

  • 副本在写入时为0,完成后再增加
  • 合理设置主分片数,确保均匀分配在所有数据节点上
    • index.routing.allocation.total_shards_per_node: 1 #限定每个索引在每个节点上可分配的主分片数
    • 5 个节点的集群,索引有5个主分片,一个副本,应该如何设置?
      • (5+5)/ 5 = 2
      • 生成环境中,要适当调大这个数字,避免有节点下线时,分片无法正常迁移

【12.6】Bulk,线程池 和 队列大小

  • 客户端
    • 单个 bulk 请求体的数据量不要太大,官方建议大约 5-15 mb
    • 写入端的 bulk 请求超时要足够长,建议 60s 以上
    • 写入段尽量将数据轮询请求到不同节点
  • 服务端
    • 索引创建属于计算密集任务,应该使用固定大小的线程池来配置。来不及处理的放入队列,线程数应该配置成 CPU 核心数 + 1 ,避免过多的上下文切换
    • 队列大小可以适当增加,不要过大,否则占用的内存会成为 GC 的负担

【12.7】索引设置的实践案例

image-20210505184543034

POST test7
{
  "settings": {
    "index":{
      "refresh_interval":"30s",
      "number_of_shards":"5"
    },
    "routing": {
      "allocation": {
        "total_shards_per_node": 3
      }
    },
    "translog":{
      "sync_interval":"30s",
      "durability":"async"
    },
    "number_of_replicas": 0
  }
  ,
  "mappings": {
    "dynamic":false
    , "properties": {}
  }
}

【13】提高 ES 集群读性能

【13.1】尽量 去范式化/非规范化 数据

  • ES != 关系型数据库
  • 极可能 去范式化/非规范化(Denormalize ) 数据,从而获取最佳的性能
    • 使用 Nested 类型的数据。查询速度会慢几倍
    • 使用 Parent / Child 关系。查询速度会慢几百倍

【13.2】数据建模

  • 尽量将数据先行计算好后,再保存到 ES 中。尽量避免查询时的 script 计算
  • 尽量使用 Filter Context ,利用缓存机制,减少不必要的算分
  • 结合 profile ,explain API 分析慢查询的问题,持续优化数据模型
    • 严禁使用 * 开头通配符的 Terms 查询

【13.3】查询优化案例

案例:(可以针对语句使用 profile 以及 explain 来 查看运行原理,或者说相当于执行计划吧)

  • 避免查询时使用脚本

    • image-20210505193309283
  • 使用 filter

    • image-20210505193354262
  • 聚合文档消耗内存,使用 filter bucket 替代 query scope

    • image-20210505193537278
  • 避免使用通配符查询

    • image-20210505193653006

    【13.4】优化分片

    • 避免 Over sharing
      • 一个查询需要访问每一个分片,分片过多,会导致不必要的查询开销
    • 结合应用场景,控制单个分片的尺寸
      • Search:20GB
      • Logging:40GB
    • Force-merge Read-only 索引
      • 使用基于时间序列的索引,将只读的索引 进行 force merge,减少 segment 数量(以及内存的开销)

【14】Lucene index 及 segment 段合并优化

【14.1】Lucene index 原理

  • 在 Lucene 中,单个倒排索引文件被称为 Segment. Segment 是自包含的,不可变更的,多个 Segments 汇总一起,称为 Lucene 的 Index,其实对应的就是 ES 中的 Shard;

  • 当有新文档写入时,会生成新的 Segment。查询时会同时查询所有的 Segments,并且对结果汇总。

  • Commit Point:Lucene 中有一个文件,用来记录所有的 Segments 信息,叫做 Commit Point

  • .del :删除文档的信息,保存在 .del 文件中,检索的都是会过滤掉 .del 文件中记录的 Segment

  • Segment 会定期 Merge,合并成一个,同时删除已删除文档

    image-20210505195324781

【14.2】Merge 优化

  • ES 和 Lucene 会自动进行 Merge 操作

  • Merge 曹邹相对比较重,需要优化,降低系统的影响

  • 优化点1:

    • 可以将 Refresh interval 调整到分钟级别 / indices.memory.index_buffer_size(默认是 10% )
    • 尽量少的文档更新操作
  • 优化点2:

    • 降低最大分段大小,避免较大的分段继续参与 Merge,节省系统资源(最终会导致有多个分段)
    • index.merge.policy.segments_per_tier,默认为 10,越小需要越多的合并操作
    • index.merge.policy.max_merged_segment,默认为 5GB,超过此大小以后,就不再参与后续的合并操作
  • 优化点3:

    • 当 index 不再有写入操作的时候,建议对其进行 force merge(以及 read_only 设置)

      • 可以提升查询速度,减少内存开销

      • POST my_index/_forcemerge?max_num_segements=1
        GET _cat/segment/my_index?v
        
    • 最终分成几个 segments 比较更合适?

      • 越少越好,理论上可以直接 force merge 成 1个,但是, force merge 会占用大量的网络、IO、CPU
      • 如果无法估计影响,无法很好的预估时间,就考虑增大最终的分段数,把较大的segment 不参与 merge操作
        • 通过设置,shard 的大小 / index.merge.policy.merged_segment 的大小

【15】ES中的缓存机制

【15.1】缓存分类

image-20210505201014371
image

  • ES 的缓存主要分为三大类
    • Node query Cache(Filter Context)
    • Shard Query Cache(Cache Query 的结果)
    • Fileddata Cache
  • 后面这个 indexing buffer 就很明显了吧,就是写入缓冲 以及 热 segments

【15.2】Node query Cache(Filter Context)

  • 每一个节点都有一个 Node Query 缓存
    • 该节点的所有 分片共享,只缓存 filter Context 相关内容
    • Cache 采用 LRU(最近最少使用淘汰) 算法
  • 静态配置,需要设置到每个 Data Node 上
    • Node Level : indices.queries.cache.size:"10%"
    • Index Level : index.queryies.cache.enabled: true

【15.3】Shard Query Cache(Cache Query )

分片查询缓存

  • 缓存每个分配上的查询结果
    • 只会缓存设置了 size=0 的查询对应的结果。如下图
      • image-20210505204310956
    • 不会缓存 hits(查询结果中的字段,它包含了所有查询的具体结果、元数据)。
    • 但是会缓存 (聚合结果)aggregations 和 suggestions(联词提示,自动补全提醒)
  • cache key
    • LRU 算法,将整个 Json 查询串作为 key,与 Json对象的顺序关联
  • 静态配置
    • 数据节点: indices.requests.cache.size: "1%"

image-20210505203517263

【15.4】Fielddata cache

  • 除了 Text 类型,默认都采用 doc_values。节约了内存
    • Aggregation 的 Global ordinals 也保存在 Fielddata cache 中
  • Text 类型的字段需要打开 Fileddata 才能对其进行聚合、排序
    • Text 经过分词,排序和聚合的效果不佳,建议不要轻易使用
  • 配置
    • 可以控制 indices.fielddata.cache.size,避免产生 GC (默认无限制)

【15.5】缓存失效

  • Node Query Cache
    • 保存的是 Segment 级缓存命中的结果。 Segment 被合并后,缓存会失效
  • Shard Requests Cache
    • 分片 Refresh 的时候,Shard Requests Cache 会失效。如果 Shard 对应的数据频繁发生变化,该缓存的效率会很差
  • Fileddata Cache
    • Segment 被合并后,会失效

【15.6】管理内存的重要性

  • ES 搞笑运维依赖于内存的合理分配
    • 可用内存一般分配给 JVM ,一般留给操作系统,缓存索引文件
  • 内存问题,引发的问题
    • 长时间GC,影响节点,导致集群响应缓慢
    • OOM,导致丢节点

【15.7】诊断内存的状况

image-20210505205115418

【15.8】常见的内存问题【案例】

(1)案例1:Segments 过多

  • Segments 个数过多,导致 Full GC
  • 现象:集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行 Full GC
  • 分析,查看 ES 的内存使用,发现 Segments.memory 占用很大空间
  • 解决:通过 force merge,把 Segments 合并成一个。
  • 建议,对于不在写入和更新的索引,可以将其设置成只读。同时,进行 force merge 操作。如果问题依然存在,则需要考虑扩容。此外,对索引进行 force merge,还可以减少对 global_ordinals 数据结果的构建,减少对 fielddata cache 的开销

(2)案例2:Fielddata cache 过大

  • Fielddata cache 过大,导致 full GC
  • 现象:集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行 Full GC
  • 分析:查看 ES 的内存使用,发现 fielddata.memory.size占用很大空间。同时数据不存在写入和更新,也执行过 segments merge
  • 解决:将 indices.fielddata.cache.size 设置小,重启节点,堆内存恢复正常
  • 建议:Fielddata cache 的构建比较重,ES 不会主动释放,所以这个值应该设置的保守一些。如果业务上确实有所需要,可以增节点扩容解决

(3)案例3:复杂的嵌套聚合

  • 复杂的嵌套聚合,导致集群 Full GC
  • 现象:节点响应缓慢,持续进行 Full gc
  • 分析:导出 dump 分析。发现内存中有大量 Bucket 对象,查看日志,发现复杂的嵌套聚合
  • 解决:优化聚合
  • 建议:在大量数据集上进行嵌套聚合查询,需要很大的堆内存在完成。如果业务场景确实需要。则需要增加硬件进行扩展。同时为了避免这类查询影响到整个集群,需要设置 Circuit Break 和 search.max_buckets 的数据

【15.9】什么是 Circuit Breaker 熔断器

image-20210505210756754

统计信息:

image-20210505210847163

【16】ES 集群运维建议

【16.1】集群的生命周期

  • 预上线
    • 评估用户的需求及使用场景 / 数据建模 / 容量规划 / 选择合适的部署架构 / 性能测试
  • 上线
    • 监控流量 / 定时检查潜在问题(防患于未然,发现索引错误的使用方式,及时扩容增加机器)
    • 对索引进行优化(index lifecycle management ),检测是否存在不均衡而导致有部分节点过热
    • 定期数据备份 / 滚动升级
  • 下家前监控流量,实现 Stage Decommission

【16.2】部署的建议

  • 根据实际场景选部署方式和配置
    • 搜索类
    • 日志/指标
  • 部署要考虑,反亲和性
    • 尽量将机器分散在不同的机架。例如,3台 Master 节点必须分散在不同的机架上
    • 善于使用 shard filtering 进行配置(比如 hot wam)

【16.3】使用规范

  • Mapping
    • 禁用 dynamic mapping
    • 多使用 index template
  • 设置 slowquerylogs
    • 例如:错误的将网址映射成 keyword,然后用通配符查询。应该使用 Text 并结合 URL 分词器
    • 禁用 * 开头的 查询
  • 记得定期备份
  • 定期滚动更新,升级版本

【16.4】ES 版本,ES升级

(1)ES版本

  • ES 的版本格式是 X.Y.Z
    • X:major
    • Y:minor
    • Z:patch
  • ES 可以使用上一个主版本的索引
    • 比如 7.x 可以使用 6.x / 7.x ,但不支持使用 5.x
    • 5.x 可以使用 2.x

(2)ES升级

  • 滚动升级 Rolling upgrade

    • 不会宕机,具体操作看官网咯
  • 全体升级、重启,Full Cluster Restart

    • 集群在更新期间不可用

    • 升级更快,操作更简单

    • 具体操作:

      image-20210505213425269

【16.5】运维常用命令

#(1)迁移节点
#使用 reroute API,把一个分片移到另外一个节点
POST _cluster/reroute
{
	"commands":[
	{
		"move":{
			"index":"index_name",
			"shard":0,
			"from_node":"node_name_1",
			"to_node":"node_name_2"
		}
	}
	]
}

#另外一种办法
POST _cluster/reroute?explain
{
	"commands":[
	{
		"allocate":{
			"index":"index_name",
			"shard":0,
			"node":"need_move_to_node_name"
		}
	}
	]
}

#(2)从集群中移除一个节点
#避免集群状态变颜色
PUT _cluster/settings
{
	"transient":{
		"cluster.routing.allocation.exclude._ip":"the_ip_of_your_node"
	}
}

#(3)分配和恢复的速率
#Recovery 的并发数量
  Cluster.routing.allocation.node_concurrent_recoveries: 2
#recovery 更改恢复的速率
  indices.recovery.max_bytes_per_sec:80mb
#recovery 更改在单个节点上恢复的并发流数
  indices.recovery.concurrent_streams:6
#Relocation  更改移动碎片的数量,以平衡集群
  Cluster.routing.allocation.cluster_concurrent_rebalance: 2

#(4) synced flush
#当需要重启一个节点时,使用它

#通过 synced flush ,可以在索引上防止一个 sync ID。这样可以提供这些分配的 Recovery 的时间
POST _flush/synced

#(5)清空节点的缓存 
#使用场景:节点上出现了高内存占用。这个会极大影响集群性能,但可以避免 OOM
POST _cache/clear

#(6)控制搜索的队列
#使用场景:当搜索的响应事件过长,看到有 reject 指标的增加,都可以适当加这个数值
PUT _cluster/settings
{
  "transient": {
    "threadpool.search.queue_size":2000
  }
}

#(7)circuit breaker 电路中断
#Adjust the circuit breakers单个操作超过40%的内存占用,则中断并记录
PUT _cluster/settings
{
  "persistent": {
    "indices.breaker.total.limit":"40%"
  }

【17】ES 使用 shrink 与 rollover 管理索引,ES 索引API

img

img

img

img

课程demo

[复制代码](javascript:void(0)😉

# 打开关闭索引
DELETE test
#查看索引是否存在
HEAD test

PUT test/_doc/1
{
  "key":"value"
}

#关闭索引
POST /test/_close
#索引存在
HEAD test
# 无法查询
POST test/_count

#打开索引
POST /test/_open
POST test/_search
{
  "query": {
    "match_all": {}
  }
}
POST test/_count


# 在一个 hot-warm-cold的集群上进行测试
GET _cat/nodes
GET _cat/nodeattrs

DELETE my_source_index
DELETE my_target_index
PUT my_source_index
{
 "settings": {
   "number_of_shards": 4,
   "number_of_replicas": 0
 }
}

PUT my_source_index/_doc/1
{
  "key":"value"
}

GET _cat/shards/my_source_index

# 分片数3,会失败
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 3,
    "index.codec": "best_compression"
  },
  "aliases": {
    "my_search_indices": {}
  }
}



# 报错,因为没有置成 readonly
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 2,
    "index.codec": "best_compression"
  },
  "aliases": {
    "my_search_indices": {}
  }
}

#将 my_source_index 设置为只读
PUT /my_source_index/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}

# 报错,必须都在一个节点
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 2,
    "index.codec": "best_compression"
  },
  "aliases": {
    "my_search_indices": {}
  }
}

DELETE my_source_index
## 确保分片都在 hot
PUT my_source_index
{
 "settings": {
   "number_of_shards": 4,
   "number_of_replicas": 0,
   "index.routing.allocation.include.box_type":"hot"
 }
}

PUT my_source_index/_doc/1
{
  "key":"value"
}

GET _cat/shards/my_source_index

#设置为只读
PUT /my_source_index/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}


POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 2,
    "index.codec": "best_compression"
  },
  "aliases": {
    "my_search_indices": {}
  }
}


GET _cat/shards/my_target_index

# My target_index状态为也只读
PUT my_target_index/_doc/1
{
  "key":"value"
}



# Split Index
DELETE my_source_index
DELETE my_target_index

PUT my_source_index
{
 "settings": {
   "number_of_shards": 4,
   "number_of_replicas": 0
 }
}

PUT my_source_index/_doc/1
{
  "key":"value"
}

GET _cat/shards/my_source_index

# 必须是倍数
POST my_source_index/_split/my_target
{
  "settings": {
    "index.number_of_shards": 10
  }
}

# 必须是只读
POST my_source_index/_split/my_target
{
  "settings": {
    "index.number_of_shards": 8
  }
}


#设置为只读
PUT /my_source_index/_settings
{
  "settings": {
    "index.blocks.write": true
  }
}


POST my_source_index/_split/my_target_index
{
  "settings": {
    "index.number_of_shards": 8,
    "index.number_of_replicas":0
  }
}

GET _cat/shards/my_target_index



# write block
PUT my_target_index/_doc/1
{
  "key":"value"
}



#Rollover API
DELETE nginx-logs*
# 不设定 is_write_true
# 名字符合命名规范
PUT /nginx-logs-000001
{
  "aliases": {
    "nginx_logs_write": {}
  }
}

# 多次写入文档
POST nginx_logs_write/_doc
{
  "log":"something"
}


POST /nginx_logs_write/_rollover
{
  "conditions": {
    "max_age":   "1d",
    "max_docs":  5,
    "max_size":  "5gb"
  }
}

GET /nginx_logs_write/_count
# 查看 Alias信息
GET /nginx_logs_write


DELETE apache-logs*


# 设置 is_write_index
PUT apache-logs1
{
  "aliases": {
    "apache_logs": {
      "is_write_index":true
    }
  }
}
POST apache_logs/_count

POST apache_logs/_doc
{
  "key":"value"
}

# 需要指定 target 的名字
POST /apache_logs/_rollover/apache-logs8xxxx
{
  "conditions": {
    "max_age":   "1d",
    "max_docs":  1,
    "max_size":  "5gb"
  }
}


# 查看 Alias信息
GET /apache_logs

[复制代码](javascript:void(0)😉

img

img

img

img

【18】ES 索引的生命周期 与管理工具

img

img

img

img

img

img

img

img

img

【19】备份

image-20210505223634121

  • 在配置文件中指定快照目录
  • 指定一个 repository(备份仓库、备份设备),应用配置文件中指定的备份目录
  • 然后利用_snapshot/创建的 repository 去备份
posted @ 2021-05-06 15:43  郭大侠1  阅读(523)  评论(0编辑  收藏  举报