[译]为什么ElasticSearch应用开发者需要了解cluster state

标签: elasticsearch | 发表时间:2017-03-23 17:07 | 作者:牧曦之晨
出处:https://segmentfault.com/blogs

在前面的文章( ES vs Solr)中我们提到, ES构建了Loggly的很多核心功能. 在把这项通用搜索技术用于我们的日志管理系统, 并为超过5000多客户提供准实时服务的过程中, 我们在技术上成长颇多. 按照我们对开源社区的尊重, 在此希望能把我们所学到的知识回馈到社区.

本文将探讨对ES扩展过程中的性能有深远影响的关键概念: cluster state.

什么是cluster state

ES的一个突出优点是其无模型规则约束. 起初, 你可以把一个包含任意字段数目的文档添加到索引中, 而并不需要提前在ES中定义这些字段的类型. 能把这些字段添加到索引并随后进行搜索是件让人兴奋的事情. 但这些字段的名称, 类型以及它们被添加到的索引信息则会自动添加到ES的 cluster state信息中(假设你使用了默认的 动态mapping设置. 当然像ES的其他配置一样, 你可以调整或禁用该行为).

当然,这里还有些秘密: 如果你向一个已存在的字段(例如integer)中试图添加另外一种类型(例如string)的字段值时, ES将会失败. 同一个索引中的相同字段不能同时具有两种不同类型. 这称为 mapping冲突. ES的处理取决于涉及的具体类型. 例如:

  • 如果向一个字符串类型中添加整数值, 则会进行强制类型转换

  • 如果向一个整数类型中添加字符串值, 则会遇到异常, ES拒绝接收该文档.

所以关注下你的ES响应,尤其在使用bulk做批量索引时.

cluster state是你的重要参考

像其他倒排索引一样, 当你搜索数据时, ES需要知道这些数据的元信息及其存储位置. 当节点接收到查询请求, 首先要做的就是你要查询的对象在哪些分片上, 然后判断这个索引上有哪些字段以及它们的类型.(你不能在一个字符串类型的字段上进行数字范围查询). 而这些信息都记录在cluster state之中.

顾名思义, cluster state是全局性信息, 包含了整个群集中所有分片的元信息(规则, 位置, 大小等信息), 并保持每个每节的信息同步.

在一个包含众多节点的集群中, ES是如何做到信息同步的呢? 原来ES的cluster state信息是由master节点维护的, 当它收到data节点的状态更新变化后, 就把这些信息依次广播到其他节点, 仅此而已.

假如你的cluster state每2½分钟更新300磅

请记住: cluster state是你的群集中每个节点上的每个索引包含的每个分片的所有字段信息. 如果你有大量的字段, 例如把ES作为大量易变且无固定规则文档的存储, 那么cluster state将会变得庞大. 在Loggly服务中恰恰如此. 因为客户发送给我们的文档格式随意, 包含任意数据的唯一字段, 并且数量跨度较大. 我们每秒处理数十万次请求, 所以Loggly的cluster state可达数百兆大小.

希望你看到光明之门

也许警告声已在你脑海中响起: "你是说当有任何变化时, ES会广播数百兆的数据到不同节点?". 也许事实并不像你想像的那么糟糕. 在cluster state管理方面, ES已经做了几个优化:

  • 从ES2.0以来, 只有变化的cluster state信息才会被广播. 相比以前的版本, 这带来了巨大的性能提升.

  • 在ES节点前传递信息之前, ES对cluster state做了效果显明的压缩.

  • ES在合并cluster state更新以及批量处理上相当明智, 特别是最近的ES版本中.(在后面的文章 Pending Tasks会介绍前期版本中未做这些优化时的内部处理)

即便如此, 经常关注你的cluster state也是很有必要的. 另外, 我们发现在规模化运行ES集群早期, 索引大量数据之前要做的第一件事, 就是 为ES的cluster state数据量设置上限, 以避免超出ES处理能力而导致集群故障. 关于cluster state更严重的问题--以及在Loggly, 我们是如何解决cluster state问题的--将会在以后的文章出介绍, 希望能对你有所帮助.

cluster state示例

下面是一个具有两个节点的集群, 其中包含了只有一条文档的一个索引的cluster state信息. 当然这与我们真实场景中的数据有很大区别, 因为在我们的集群中有很多机器和大量的索引节点以及超出你想象的mapping数量. 但这个例子已经足够让你了解cluster state所包含的信息了.

  {
  "cluster_name" : "elasticsearch",
  "version" : 11,
  "master_node" : "-mq1SRuuQoeEq-3S8SdHqw",
  "blocks" : { },
  "nodes" : {
    "sIh5gQcFThCcz3SO6txvvQ" : {
      "name" : "Max",
      "transport_address" : "inet[/162.245.23.194:9301]",
      "attributes" : { }
    },
    "-mq1SRuuQoeEq-3S8SdHqw" : {
      "name" : "Llyron",
      "transport_address" : "inet[/162.245.23.194:9300]",
      "attributes" : { }
    }
  },
  "metadata" : {
    "templates" : { },
    "indices" : {
      "blog" : {
        "state" : "open",
        "settings" : {
          "index" : {
            "uuid" : "UQMz5vbXSBqFU_8U3u4gYQ",
            "number_of_replicas" : "1",
            "number_of_shards" : "5",
            "version" : {
              "created" : "1030099"
            }
          }
        },
        "mappings" : {
          "user" : {
            "properties" : {
              "name" : {
                "type" : "string"
              }
            }
          }
        },
        "aliases" : [ ]
      }
    }
  },
  "routing_table" : {
    "indices" : {
      "blog" : {
        "shards" : {
          "4" : [ {
            "state" : "STARTED",
            "primary" : true,
            "node" : "sIh5gQcFThCcz3SO6txvvQ",
            "relocating_node" : null,
            "shard" : 4,
            "index" : "blog"
          }, {
            "state" : "STARTED",
            "primary" : false,
            "node" : "-mq1SRuuQoeEq-3S8SdHqw",
            "relocating_node" : null,
            "shard" : 4,
            "index" : "blog"
          } ],
          "0" : [ {
            "state" : "STARTED",
            "primary" : true,
            "node" : "sIh5gQcFThCcz3SO6txvvQ",
            "relocating_node" : null,
            "shard" : 0,
            "index" : "blog"
          }, {
            "state" : "STARTED",
            "primary" : false,
            "node" : "-mq1SRuuQoeEq-3S8SdHqw",
            "relocating_node" : null,
            "shard" : 0,
            "index" : "blog"
          } ],
          "3" : [ {
            "state" : "STARTED",
            "primary" : false,
            "node" : "sIh5gQcFThCcz3SO6txvvQ",
            "relocating_node" : null,
            "shard" : 3,
            "index" : "blog"
          }, {
            "state" : "STARTED",
            "primary" : true,
            "node" : "-mq1SRuuQoeEq-3S8SdHqw",
            "relocating_node" : null,
            "shard" : 3,
            "index" : "blog"
          } ],
          "1" : [ {
            "state" : "STARTED",
            "primary" : false,
            "node" : "sIh5gQcFThCcz3SO6txvvQ",
            "relocating_node" : null,
            "shard" : 1,
            "index" : "blog"
          }, {
            "state" : "STARTED",
            "primary" : true,
            "node" : "-mq1SRuuQoeEq-3S8SdHqw",
            "relocating_node" : null,
            "shard" : 1,
            "index" : "blog"
          } ],
          "2" : [ {
            "state" : "STARTED",
            "primary" : true,
            "node" : "sIh5gQcFThCcz3SO6txvvQ",
            "relocating_node" : null,
            "shard" : 2,
            "index" : "blog"
          }, {
            "state" : "STARTED",
            "primary" : false,
            "node" : "-mq1SRuuQoeEq-3S8SdHqw",
            "relocating_node" : null,
            "shard" : 2,
            "index" : "blog"
          } ]
        }
      }
    }
  },
  "routing_nodes" : {
    "unassigned" : [ ],
    "nodes" : {
      "sIh5gQcFThCcz3SO6txvvQ" : [ {
        "state" : "STARTED",
        "primary" : true,
        "node" : "sIh5gQcFThCcz3SO6txvvQ",
        "relocating_node" : null,
        "shard" : 4,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : true,
        "node" : "sIh5gQcFThCcz3SO6txvvQ",
        "relocating_node" : null,
        "shard" : 0,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : false,
        "node" : "sIh5gQcFThCcz3SO6txvvQ",
        "relocating_node" : null,
        "shard" : 3,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : false,
        "node" : "sIh5gQcFThCcz3SO6txvvQ",
        "relocating_node" : null,
        "shard" : 1,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : true,
        "node" : "sIh5gQcFThCcz3SO6txvvQ",
        "relocating_node" : null,
        "shard" : 2,
        "index" : "blog"
      } ],
      "-mq1SRuuQoeEq-3S8SdHqw" : [ {
        "state" : "STARTED",
        "primary" : false,
        "node" : "-mq1SRuuQoeEq-3S8SdHqw",
        "relocating_node" : null,
        "shard" : 4,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : false,
        "node" : "-mq1SRuuQoeEq-3S8SdHqw",
        "relocating_node" : null,
        "shard" : 0,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : true,
        "node" : "-mq1SRuuQoeEq-3S8SdHqw",
        "relocating_node" : null,
        "shard" : 3,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : true,
        "node" : "-mq1SRuuQoeEq-3S8SdHqw",
        "relocating_node" : null,
        "shard" : 1,
        "index" : "blog"
      }, {
        "state" : "STARTED",
        "primary" : false,
        "node" : "-mq1SRuuQoeEq-3S8SdHqw",
        "relocating_node" : null,
        "shard" : 2,
        "index" : "blog"
      } ]
    }
  },
  "allocations" : [ ]
}

相关 [elasticsearch 应用 开发] 推荐:

[译]为什么ElasticSearch应用开发者需要了解cluster state

- - SegmentFault 最新的文章
在前面的文章( ES vs Solr)中我们提到, ES构建了Loggly的很多核心功能. 在把这项通用搜索技术用于我们的日志管理系统, 并为超过5000多客户提供准实时服务的过程中, 我们在技术上成长颇多. 按照我们对开源社区的尊重, 在此希望能把我们所学到的知识回馈到社区. 本文将探讨对ES扩展过程中的性能有深远影响的关键概念: cluster state..

[译]elasticsearch mapping

- - an74520的专栏
es的mapping设置很关键,mapping设置不到位可能导致索引重建. 请看下面各个类型介绍^_^. 每一个JSON字段可以被映射到一个特定的核心类型. JSON本身已经为我们提供了一些输入,支持 string,  integer/ long,  float/ double,  boolean, and  null..

Elasticsearch as Database - taowen - SegmentFault

- -
【北京上地】滴滴出行基础平台部招聘 Elasticsearch 与 Mysql binlog databus 开发工程师. 内推简历投递给: taowen@didichuxing.com. 推销Elasticsearch. 时间序列数据库的秘密(1)—— 介绍. 时间序列数据库的秘密(2)——索引.

ElasticSearch 2 的节点调优(ElasticSearch性能)

- - 行业应用 - ITeye博客
一个ElasticSearch集群需要多少个节点很难用一种明确的方式回答,但是,我们可以将问题细化成一下几个,以便帮助我们更好的了解,如何去设计ElasticSearch节点的数目:. 打算建立多少索引,支持多少应用. elasticsearch版本: elasticsearch-2.x. 需要回答的问题远不止以上这些,但是第五个问题往往是容易被我们忽视的,因为单个ElasticSearch集群有能力支持多索引,也就能支持多个不同应用的使用.

elasticsearch的javaAPI之query

- - CSDN博客云计算推荐文章
elasticsearch的javaAPI之query API. the Search API允许执行一个搜索查询,返回一个与查询匹配的结果(hits). 它可以在跨一个或多个index上执行, 或者一个或多个types. 查询可以使用提供的 query Java API 或filter Java API.

Elasticsearch基础教程

- - 开源软件 - ITeye博客
转自:http://blog.csdn.net/cnweike/article/details/33736429.     Elasticsearch有几个核心概念. 从一开始理解这些概念会对整个学习过程有莫大的帮助.     接近实时(NRT).         Elasticsearch是一个接近实时的搜索平台.

ElasticSearch索引优化

- - 行业应用 - ITeye博客
ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡. 所以从上我可以通过索引的settings进行第一优化:. 这两个参数第一是到tranlog数据达到多少条进行平衡,默认为5000,而这个过程相对而言是比较浪费时间和资源的. 所以我们可以将这个值调大一些还是设为-1关闭,进而手动进行tranlog平衡.

elasticsearch集群搭建

- - zzm
之前对于CDN的日志处理模型是从 . logstash agent==>>redis==>>logstash index==>>elasticsearch==>>kibana3,对于elasticsearch集群搭建,可以把索引进行分片存储,一个索引可以分成若干个片,分别存储到集群里面,而对于集群里面的负载均衡,副本分配,索引动态均衡(根据节点的增加或者减少)都是elasticsearch自己内部完成的,一有情况就会重新进行分配.

Elasticsearch集群入门

- - 编程语言 - ITeye博客
欢迎来到Elasticsearch的奇妙世界,它是优秀的全文检索和分析引擎. 不管你对Elasticsearch和全文检索有没有经验,都不要紧. 我们希望你可以通过这本书,学习并扩展Elasticsearch的知识. 由于这本书也是为初学者准备的,我们决定先简单介绍一般性的全文检索概念,接着再简要概述Elasticsearch.

Elasticsearch 学习笔记

- - 研发管理 - ITeye博客
安装  Elasticsearch. 1:解压下载的安装包 elasticsearch-1.7.2.zip. 修改  node.name: es(集群状态名字一致). 2:在https://github.com/elasticsearch/elasticsearch-servicewrapper下载该插件后,解压缩.