ES性能调优权威指南(篇一)

ES性能调优权威指南(篇一)


搜索和分析是当今应用软件的基本特征。可伸缩性和近实时处理大数据的能力是移动app、web和数据分析应用的基本要求之一。

自动补全文本字段、搜索建议、位置和地理空间搜索和多维导航是满足业务需求的可用标准。

调优是基本的、必要的和至关重要的!任何系统调优都必须基于性能测试;这就是为什么对于任何使用ES的人来说,对监控和指标变化有清楚地了解十分重要。

   这三章系列教程介绍了性能调优的一些技巧和方法,逐步解释了与之最相关的系统配置的设置和指标。



集群状态(索引和分片的容量规划)


   1个分片太少,而1000个分片又太多,那我怎样才能知道我需要多少个分片?这个问题在通常情况下是没法儿回答的。
有很多因素会影响:比如硬件条件、文档大小和复杂度、索引和分析文档的方式、查询类型、聚合方式、数据模型等等。

    在ES创建大量的索引和分片很简单,但是每个索引和分片的创

建是需要成本的。如果我们有太多的索引或分片,那么单独管理负载可能会降低我们的ES集群性能,可能会使集群状态变为红色。 使用太多索引/分片也会对索引和搜索的性能产生相当大的影响。

   ES为其无模式化提供了便利。弹性搜索提供了

 schemaless的灵活性。 我们可以向索引添加任何多字段的JSON文档,而无需告诉ES关于这些字段的任何内容。 这些新的字段 - 它们被命名什么,它们是什么类型,以及它们所在的索引 - 都会被自动添加到ES的索引映射和集群状态中。 开销最大的是 Cluster State大小的管理,其中包含集群中每个索引的所有映射。

    Cluster state API允许获得整个集群的综合状态信息。

$ curl -XGET 'http://localhost:9200/_cluster/state'

以下是拥有三个模板和五个索引单节点集群API的响应: 

{
  "cluster_name": "elasticsearch",
  "version": 6,
  "state_uuid": "skxF0gCYTAGQAUU-ZW4_GQ",
  "master_node": "VyKDGurkQiygV-of4B1ZAQ",
  "blocks": {},
  "nodes": {
    "VyKDGurkQiygV-of4B1ZAQ": {
      "name": "Siege",
      "transport_address": "127.0.0.1:9300",
      "attributes": {}
    }
  },
  "metadata": {
    "cluster_uuid": "QMSq7EOfToS-v5dKc0GdUA",
    "templates": {
      "template_one": {
        "template": "template_one_*",
        "order": 0,
        "settings": { ... },
        "mappings": { ... }
      },
      "template_two": { ... },
      "template_three": { ... }
    },
    "indices": {
      "index_one": {
        "state": "open",
        "settings": { ... },
        "mappings": { ... },
        "aliases": [ ... ]
      },
      "index_2": { ... },
      "index_3": { ... },
      "index_4": { ... },
      "index_5": { ... }
    }
  },
  "routing_table": {
    "indices": {
      "index_one": {
        "shards": {
          "0": [
            {
              "state": "STARTED",
              "primary": true,
              "node": "VyKDGurkQiygV-of4B1ZAQ",
              "relocating_node": null,
              "shard": 0,
              "index": "index_one",
              "version": 18,
              "allocation_id": {
                "id": "hAZf59wDSNS7im1wOdToHA"
              }
            }
          ]
        }
      },
      "index_two": { ... },
      "index_three": { ... },
      "index_four": { ... },
      "index_five": { ... } 
    }
  },
  "routing_nodes": {
    "unassigned": [
      {
        "state": "UNASSIGNED",
        "primary": true,
        "node": null,
        "relocating_node": null,
        "shard": 0,
        "index": "index_three",
        "version": 0,
        "unassigned_info": {
          "reason": "CLUSTER_RECOVERED",
          "at": "2017-02-08T18:46:11.027Z"
        }
      },
      { ... }
    ],
    "nodes": {
      "VyKDGurkQiygV-of4B1ZAQ": [
        {
          "state": "STARTED",
          "primary": true,
          "node": "VyKDGurkQiygV-of4B1ZAQ",
          "relocating_node": null,
          "shard": 0,
          "index": "index_one",
          "version": 18,
          "allocation_id": {
            "id": "hAZf59wDSNS7im1wOdToHA"
          }
        },
        { ... },
        { ... }
      ]
    }
  }
}
    默认情况下,集群状态请求路由到主节点,以确保返回最新的集群状态。 为了调试我们可以通过向查询字符串添加local=true来获取特定节点的本地集群状态。
随着群集规模的增长(取决于分片和索引的数量、映射、模板 ), 可以对指定URL中的各个部分的集群状态响应进行过滤。
$ curl -XGET 'http://localhost:9200/_cluster/state/{metrics}/{indices}'


度量指标可以是一个逗号分隔的列表
  • version- 显示集群的当前版本.

  • master_node -显示所选的主节点部分

  • nodes - 显示响应的节点部分
  • routing_table - 显示响应的路由部分。如果我们提供一个逗号分隔的索引列表,那么返回的结果将只包含列出的索引。

  • metadata -显示响应的元数据。如如果我们提供一个逗号分隔的索引列表,那么返回的结果将只包含列出的索引。
  • blocks - 显示响应的块部分。

我们可以规划集群状态、大小和容量以决定主分片的数量:

  • 创建一个单服务器组成的集群,并使用我们考虑在生产环境中的硬件。
  • 创建一个我们计划在生产环境中使用的设置和分析程序,但是只使用一个主分片和没有副本。
  • 用真实的文档填充(或者尽可能接近真实)
  • 运行真实的查询和聚合(或者尽可能接近真实)
一旦我们定义了单分片的容量,很容易推断整个索引的数量。以我们索引的总量为需求,加上一些额外增长的数据,再除以单个分配的容量。结果就是我们主分片的数量。

ES集群(拓扑)中的生命周期


    ES为组合复杂的集群拓扑提供了大量的工具。我们可以使用拥有健壮节点的异构集群来托管热数据,并且使用更便宜的节点存储历史数据,例如使用节点熟悉和分片分片过滤。集群中的不同节点有不同的角色(数据节点/主节点-客户端节点与否)和属性(比如区域)。划分主节点和数据节点的异构好处是我们只需要三个主选取节点并设置minimum_master_nodes为2。无论我们向集群中添加多少数据节点我们都不用改变设置。建立一个合适的集群拓扑可以有效避免脑裂 split brain。

(译者注:如果分裂是交叉的,minimum_master_nodes没法防止脑裂,但是这个bug已经被修复了了,可以参考 https://github.com/elastic/elasticsearch/issues/2488 https://github.com/LiangShang/liangshang.github.com/issues/18 https://github.com/elastic/elasticsearch/pull/7493 )

主选举节点


    主节点负责轻量级集群范围的操作,  比如创建或者删除索引、跟踪集群节点、分片分配到哪个节点等。拥有一个稳定的主节点对集群健康很重要。主节点必须访问数据/目录(就像数据节点一样),因为这是集群状态在节点重启前持久化的地方。

    为了创建一个独立的主选取节点:

node.master: truenode.data: falsenode.ingest: false
  • node.master 默认是开启的

  • 关闭node.data  (默认开启).

  • 关闭node.ingest (默认开启).


数据节点

    数据节点持有我们索引中的文档。数据节点处理例如CRUD、搜索和聚合登数据类的操作。这些操作是IO、内存、CPU密集型的。监控资源很重要并且在负载过重时需要加载更多的数据节点拥有专用数据节点的主要好处是主数据和数据角色的分离。

  为了创建一个独立的数据节点:

node.master: falsenode.data: truenode.ingest: false
  • 关闭node.master(默认开启).

  •  node.data 默认开启

  • 关闭node.ingest(默认开启).

摄取节点

    摄取节点可以执行预处理管道,有一个或多个摄取处理器组成。根据摄取过程和所需的资源执行的不同类型,只执行特定任务的摄取节点是有意义的。

     为了创建一个独立的主选取节点:

node.master: falsenode.data: falsenode.ingest: true
  • 关闭 node.master(默认开启).

  • 关闭node.data(默认开启).

  • node.ingest默认开启


协调节点


如果我们不管处理主节点职责、保存数据和预处理文档的能力,那么我们就可以有一个只能路由请求、处理搜索减少阶段和分发批量索引的协调节点。实际上,协调节点就像一个智能负载均衡器一样。

     为了创建一个独立的协调节点:

node.master: falsenode.data: falsenode.ingest: false
  • 关闭node.master(默认开启).

  • 关闭node.data(默认开启).

  • 关闭node.ingest(默认开启).


启用内存锁检查来禁用交互


    Swapping 是将一页内容复制到硬盘预先分配的空间的过程,称为交互空间,以释放内存页。物理内存和交互空间的组合大小是可用的虚拟内存值。

    交换对性能和节点稳定十分不利,因不惜一切禁止。它会导致持续几分钟而不是几毫米的gc,并可能导致节点响应缓慢,甚至是断开与集群的连接。与内容相比,磁盘是很慢的。内存是纳秒级而磁盘是毫秒级;所以访问磁盘的速度可能比访问物理内存要慢数万倍。发生的交换越多,进程就会越慢,因为应该避免交换。

    当JVM执行一个major gc时会涉及堆中的每一页。如果这些页面中的任何一个被交换到磁盘,它们不得不交换回内存。这会导致大量的磁盘抖动而ES更愿意使用服务请求。禁止交换的几种方法之一是设置ES的bootstrap.mlockall请求JVM通过mlockall将堆锁在内存中。然而,在有些情况下ES无法锁定堆(例如ES没有无限的memlock )。内存锁定检查可用于验证bootstrap.mlockall 是否开启,也可确认JVM是否成功的锁定了堆。

    以下是三种禁用交换的方法:


开启b ootstrap.mlockall


mlockall 属性允许ES节点禁止交换内存(注意这这对Linux/Unix系统适用)。这个属性可以在 config/elasticsearch.yml 文件中加入以下这行:

bootstrap.mlockall:true
5.x releases中 ,这个变量改成了 bootstrap.memory_lock: true.

mlockall 默认是关闭的,意味着ES节点允许交换。一旦添加了该字段,需要重启节点。重启ES之后可以通过以下请求返回的mlockall 值来确认是否应用成功。

curl -XGET localhost:9200/_nodes?filter_path=**.mlockall

正确的返回应该是

{"nodes":{"VyKDGurkQiygV-of4B1ZAQ":{"process":{"mlockall":true}}}}

如果我们发现mlockall是false,那意味着mlockall 请求失败。我们将会看到无法锁定JVM内存的提示信息。Linux/Unix最可能的原因是ES用户没有权限锁定内存,可以通过下面的方式授权:

  • 启动ES前设置ulimit -l unlimited 为root,或者在 /etc/security/limits.conf设置 memlock 为 unlimited

  • RPM or Debian 在系统配置文件中设置MAX_LOCKED_MEMORY 为 unlimited  (或者参阅下面的系统使用systemd)

  • 如果使用systemd Systems设置LimitMEMLOCK to infinity in the systemd configuration, .


禁用所有的交换文件


    可以完全禁用交换。一般ES是作为一个服务部署在资源上,而它的内容是由JVM变量控制的。这不需要进行交换。在Linux系统中我们可以通过运行sudo swapoff -a临时禁用交换。而要永久禁用的话需要编辑 /etc/fstab文件,并注释掉包含单词swap的任何行。


配置减少交换

    另外一个Linux系统可选的操纵是确保sysctl 中vm.swappiness 值设为1。这降低了内核交换的倾向,并且在正常情况下不该出现交换,但在紧急情况下任然运行交换。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值