Elasticsearch 学习笔记Day 27

123 阅读14分钟

hi,我是蛋挞,一个初出茅庐的后端开发,希望可以和大家共同努力、共同进步!


开启掘金成长之旅!这是我参与「掘金日新计划 · 4 月更文挑战」的第 11 天,点击查看活动详情

  • 起始标记->生产环境中的集群运维(10讲):「65 | 生产环境常用配置与上线清单」
  • 结尾标记->生产环境中的集群运维(10讲):「67 | 诊断集群的潜在问题」

生产环境常用配置与上线清单

f92df602-bd3e-482d-bf69-ea6ad39fc7d6.pngDevelopment vs.Production Mode

  • 从 ES 5 开始,支持 Development 和 Production 两种运行模式
    • 开发模式
    • 生产模式

image.png

Bootstrap Checks

  • 一个集群在 Production Mode 时,启动时必须通过所有 Bootstrap 检测,否则会启动失败
  • Bootstrap Checks 可以分为两类: JVM& Linux Checks。Linux Checks 只针对 Linux 系统

image.png www.elastic.co/guide/en/el…

JVM 设定

  • 从ES6开始,只支持64 位的JVM
    • 配置 config /jvm.options
  • 避免修改默认配置
    • 将内存Xms 和Xmx 设置成一样,避免 heap resize 时引发停顿0
    • Xmx 设置不要超过物理内存的 50%;单个节点上,最大内存建议不要超过 32G内存
    • 生产环境,JVM 必须使用 Server 模式
    • 关闭JVM Swapping

集群的API设定

  • 静态设置和动态设定
    • 静态配置文件尽量简洁: 按照文档设置所有相关系统参数。 elasticsearch.yml 配置文件中尽量只写必备参数
  • 其他的设置项可以通过 AP动态进行设定动态设定分 transient 和 persistent 两种,都会覆盖 elasticsearch.yaml 中的设置
    • Transient 在集群重启后会丢失
    • Persistent 在集群中重启后不会丢失

image.pngimage.png

系统设置

  • 参照文档“Setup Elasticsearch > Important System Configuration"

www.elastic.co/guide/en/el…

  • Disable Swapping ,Increase file descriptor,虚拟内存,number of thread

最佳实践:网络

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

最佳实践:内存设定计算实例

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

最佳实践:存储

  • 推荐使用 SSD,使用本地存储 (Local Disk)。避免使用 SAN NFS /AWS /AZure filesystem
  • 可以在本地指定多个“path.data”,以支持使用多块磁盘
  • ES本身提供了很好的 HA 机制;无需使用 RAID 1/5/10
  • 可以在 Warm 节点上使用 Spinning Disk,但是需要关闭 Concurrent Merges
    • Index.merge.scheduler.max thread count: 1
  • Trim 你的 SSD

最佳实践:服务器硬件

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

集群设置: Throttles 限流

  • 避免过多任务对集群产生性能影响为 Relocation 和 Recovery 设置限流,
  • Recovery
    • Cluster.routing.allocation.node_concurrent_recoveries: 2
  • Relocation
    • Cluster.routing.allocation.cluster_concurrent_rebalance: 2

集群设置:关闭 Dynamic Indexes

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

image.png

  • 或者通过模版设置白名单

image.png

本节知识总结

学习了在生产环境当中如何对Elasticsearch集群进行一些设定,也学习了在ES 5.0以后Production Mode情况下ES会对ES系统和JVM一些必要的检测,如果没有遵循ES的推荐检测就会失败,集群也不能正常的启动,也分享了一些关于网络和存储的最佳实践,也建议对生产环境需要进行一些必要的限定,比如说进行Dynamic Indexes这样的功能,这样才可以确保用户在使用ES集群的时候对数据进行很好的建模。

监控Elasticsearch集群

Elasticsearch Stats 相关的 AP

  • Elasticsearch 提供了多个监控相关的 AP
    • Node Stats: _nodes/stats
    • Cluster Stats:_cluster/stats
    • Index Stats: indexname/_stats

Elasticsearch Task AP

  • 查看 Task 相关的AP
    • 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
    • nodes/hot threads

The Index & Query Slow Log

  • 支持将分片上,Search 和 Fetch 阶段的慢查询写入文件
  • 支持为 Query 和 Fetch 分别定义闽值
  • 索引级的动态设置,可以按需设置,或者通过Index Template 统一设定
  • Slog log 文件通过 log4j2.properties 配置

image.png

如何创建监控 Dashboard

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

CodeDemo

# Node Stats:
GET _nodes/stats

#Cluster Stats:
GET _cluster/stats

#Index Stats:
GET kibana_sample_data_ecommerce/_stats

#Pending Cluster Tasks API:
GET _cluster/pending_tasks

# 查看所有的 tasks,也支持 cancel task
GET _tasks


GET _nodes/thread_pool
GET _nodes/stats/thread_pool
GET _cat/thread_pool?v
GET _nodes/hot_threads
GET _nodes/stats/thread_pool


# 设置 Index Slowlogs
# the first 1000 characters of the doc's source will be logged
PUT my_index/_settings
{
  "index.indexing.slowlog":{
    "threshold.index":{
      "warn":"10s",
      "info": "4s",
      "debug":"2s",
      "trace":"0s"
    },
    "level":"trace",
    "source":1000  
  }
}

# 设置查询
DELETE my_index
//"0" logs all queries
PUT my_index/
{
  "settings": {
    "index.search.slowlog.threshold": {
      "query.warn": "10s",
      "query.info": "3s",
      "query.debug": "2s",
      "query.trace": "0s",
      "fetch.warn": "1s",
      "fetch.info": "600ms",
      "fetch.debug": "400ms",
      "fetch.trace": "0s"
    }
  }
}

GET my_index

本节知识总结

介绍了Elasticsearch一些基本的的monitor的API,我们可以基于这些monitor的API构建一些功能丰富的Dashboard。

诊断集群的潜在问题

集群运维所面临的挑战

  • 用户集群数量多,业务场景差异大
  • 使用与配置不当,优化不够
    • 如何让用户更加高效和正确的使用ES0
    • 如何让用户更全面的了解自己的集群的使用状况0
  • 发现问题滞后,需要防患于未然
    • 需要“有迹可循”,做到“有则改之,无则加勉
    • Elastic 有提供 Support Diagnostics Tool - github.com/elastic/sup…

集群绿色,是否意味着足够好

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

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

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

eBay Diagnostic Tool

  • 集群健康状态,是否有节点丢失
  • 索引合理性
    • 索引总数不能过大/副本分片尽量不要设置为 0/主分片尺寸检测/索引的字段总数 (Dyamic Mapping 关闭)/索引是否分配不均衡 /索引 segment 大小诊断分析
  • 资源使用合理性
    • CPU内存和磁盘的使用状况分析/是否存在节点负载不平衡是否需要增加节点
  • 业务操作合理性
    • 集群状态变更频率,是否在业务高峰期有频繁操作
    • 慢查询监控与分析

image.png 集群中索引的诊断

  • 索引的总数是否过大
  • 是否存在字段过多的情况
  • 索引的分片个数是否设置合理
  • 单个节点的分片数是否过多
  • 数据节点之间的负载偏差是否过大
  • 冷热数据分配是否正确 (例如,Cold 节点上的索引是否设置成只读)

阿里云-EYOU 智能运维工具

每天凌晨定时诊断,也可以自主诊断。每次诊断耗时 3 分钟 - help.aliyun.com/document detail/90391.htm image.png

诊断 Shard 数

image.pngimage.png

磁盘容量估算

image.png

多维度检测,构建自己的诊断工具

image.png

相关阅读

本节知识总结

介绍了对ES集群进行诊断的潜在问题的重要性,可以结合最后的脑图对诊断的归类,结合自身业务对集群的使用状况开发出符合实际需求的诊断工具。

解决集群Yellow与Red的问题

集群健康度

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

image.png

Health 相关的 API

image.png

image.png

案例1

  • 症状:集群变红
  • 分析: 通过 Allocation Explain API 发现 创建索引失败,因为无法找到标记了相应 box type 的节点
  • 解决: 删除索引,集群变绿。重新创建索引,并且指定正确的 routing box type,索引创建成功集群保持绿色状态

案例2

  • 症状:集群变黄
  • 分析:通过 Allocation Explain API 发现无法在相同的节点上创建副本
  • 解决:将索引的副本数设置为 0,或者通过增加节点解决

分片没有被分配的一些原因

  • INDEX CREATE: 创建索引导致。在索引的全部分片分配完成之前,会有短暂的 Red,不一定代表有问题
  • CLUSTER_RECOVER: 集群重启阶段,会有这个问题
  • INDEX_REOPEN: Open 一个之前 Close 的索引
  • DANGLING_INDEX_IMPORTED:一个节点离开集群期间,有索引被删除。这个节点重新返回时,会导致 Dangling 的问题

www.elastic.co/quide/en/el…

常见问题与解决方法

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

集群 Red &Yellow 问题的总结

  • Red & Yellow 是集群运维中常见的问题
  • 除了集群故障,一些创建,增加副本等操作都会导致集群短暂的 Red 和 Yellow,所以监控和报警时需要设置一定的延时
  • 通过检查节点数,使用 ES 提供的相关 AP找到真正的原因
  • 可以指定 Move 或者 Reallocate 分片

image.png

CodeDemo

#案例1
DELETE mytest
PUT mytest
{
  "settings":{
    "number_of_shards":3,
    "number_of_replicas":0,
    "index.routing.allocation.require.box_type":"hott"
  }
}





# 检查集群状态,查看是否有节点丢失,有多少分片无法分配
GET /_cluster/health/

# 查看索引级别,找到红色的索引
GET /_cluster/health?level=indices


#查看索引的分片
GET _cluster/health?level=shards

# Explain 变红的原因
GET /_cluster/allocation/explain

GET /_cat/shards/mytest
GET _cat/nodeattrs

DELETE mytest
GET /_cluster/health/

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

GET /_cluster/health/

#案例2, Explain 看 hot 上的 explain
DELETE mytest
PUT mytest
{
  "settings":{
    "number_of_shards":2,
    "number_of_replicas":1,
    "index.routing.allocation.require.box_type":"hot"
  }
}

GET _cluster/health
GET _cat/shards/mytest
GET /_cluster/allocation/explain

PUT mytest/_settings
{
    "number_of_replicas": 0
}

本节知识小节

分享了一些Elasticsearch集群变黄或变红的原因,根据一些实例帮助我们分析原因以及如何解决这样的问题。

提升集群写性能

提高写入性能的方法

  • 写性能优化的目标: 增大写吞吐量 (Events Per Second)越高越好
  • 客户端:多线程,批量写
    • 可以通过性能测试,确定最佳文档数量
    • 多线程: 需要观察是否有 HTTP 429 返回,实现 Retry 以及线程数量的自动调节
  • 服务器端:单个性能问题,往往是多个因素造成的。需要先分解问题,在单个节点上进行调整并且结合测试,尽可能压榨硬件资源,以达到最高吞吐量
    • 使用更好的硬件。观察 CPU / IO Block
    • 线程切换 / 堆栈状况

服务器端优化写入性能的一些手段

  • 降低IO 操作
    • 使用 ES 自动生成的文档ld/一些相关的 ES 配置,如 Refresh Interval
  • 降低CPU和存储开销
    • 减少不必要分分词 /避免不需要的 doc values /文档的字段尽量保证相同的顺序,可以提高文档的压缩率
  • 尽可能做到写入和分片的均衡负载,实现水平扩展
    • Shard Filtering / Write Load Balancer
  • 调整 Bulk 线程池和队列

优化写入性能

  • ES 的默认设置,已经综合考虑了数据可靠性,搜索的实时性质,写入速度,一般不要盲目修改
  • 一切优化,都要基于高质量的数据建模

关闭无关的功能

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

image.png

针对性能的取舍

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

数据写入的过程

  • Refresh
    • 将文档先保存在Index buffer 中,以 refresh _interval 为间隔时间,定期清空 buffer,生成 segment,借助文件系统缓存的特性,先将 segment 放在文件系统缓存中,并开放查询,以提升搜索的实时性
  • Translog
    • Segment 没有写入磁盘,即便发生了当机,重启后,数据也能恢复,默认配置是每次请求都会落盘
  • Flush
    • 删除日的 translog 文件
    • 生成 Segment 并写入磁盘 /更新 commit point 并写入磁盘。** ES 自动完成,可优化点不多**

Refresh Interva

  • 降低Refresh 的频率
    • 增加 refresh interval 的数值。默认为s ,如果设置成-1,会禁止自动 refresh
      • 避免过于频繁的 refresh,而生成过多的 segment 文件
      • 但是会降低搜索的实时性
    • 增大静态配置参数 indices.memory.index buffer size
      • 默认是 10%,会导致自动触发 refresh

Translog

  • 降低写磁盘的频率,但是会降低容灾能力
    • Index.translog.durability: 默认是 request,每个请求都落盘。设置成 async,异步写入
    • Index.translog.sync interval 设置为 60s,每分钟执行一次
    • Index.translog.flush_threshod size: 默认 512 mb,可以适当调大。当translog 超过该值,会触发 flush

分片设定

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

Bulk,线程池和队列大小

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

一个索引设定的例子

image.png

CodeDemo

DELETE myindex
PUT myindex
{
  "settings": {
    "index": {
      "refresh_interval": "30s",
      "number_of_shards": "2"
    },
    "routing": {
      "allocation": {
        "total_shards_per_node": "3"
      }
    },
    "translog": {
      "sync_interval": "30s",
      "durability": "async"
    },
    "number_of_replicas": 0
  },
  "mappings": {
    "dynamic": false,
    "properties": {}
  }
}

相关阅读

本节知识小节

分享了一些Elasticsearch文档性能优化,一切性能的优化都建立于良好的数据建模的基础上,同时也可以通过新增搜索的实时性等等达到性能的提升。


此文章为4月Day11学习笔记,内容来源于极客时间《Elasticsearch 核心技术与实战》