ZBlog

1567668608251

Elasticsearch问题以及调优

什么是脑裂问题

  • 脑裂问题其实就是同一个集群的不同节点对于整个几位群的状态有不同的理解,导致操作错乱,类似于精神分裂
  • 1566822492817

怎么发现集群产生脑裂问题

  • Elasticsearch出现查询非常缓慢的情况
  • 通过命令查看集群的状态
  • 发现集群状态为red,且集群数量明显错误,再向不同的节点查询集群状态的时候,总体状态都是red,但是返回的集群数量却不太一样
  • 正常情况下,访问每一个节点,对集群中的状态返回应该是一致的。不一致的信息表示集群中不同节点对master节点的选择出现了问题。导致集群不能正常工作

产生脑裂问题的原因

  • 网络
    • 由于某些节点之间的网络通信出现问题,导致一些节点认为master节点已经挂了,所以有重新选举了新的master节点,从而导致集群信息混乱,可以检查Ganglia集群监控,来查看是否是网络原因
  • 节点负载过大:由于master节点与data节点都是混在一起的,有可能master节点的负载过大,导致对应的es实例停止响应,这时一部分节点会一位master节点已经挂掉从而重新选举,导致多master节点运行。同时由于data节点上ES进程占用的内存较大,较大规模的内存回收操作也能造成ES进程失去响应。所以,这个原因的可能性应该是最大的。

如何解决脑裂问题

  • 对于网络问题,只能进行网络修复,在重启集群

  • 对于负载的问题

    • 一个直观的解决方案就是将master节点与data节点分离,准备几台机器加入集群中,这几台机器只能充当master节点,不可担任存储和搜索的角色

      • 配置信息

      • 1
        2
        3
        4
        5
        node.master: true
        node.data: false
        其他节点 只能充当data不能充当master
        node.master: false
        node.data: true
    • 还有两个参数的修改可以减少脑裂问题的出现

      • discovery.zen.ping_timeout(默认值是3秒):默认情况下,一个节点会认为,如果master节点在3秒之内没有应答,那么这个节点就是死掉了,而增加这个值,会增加节点等待响应的时间,从一定程度上会减少误判。
      • discovery.zen.minimum_master_nodes(默认是1):这个参数控制的是,一个节点需要看到的具有master节点资格的最小数量,然后才能在集群中做操作。官方的推荐值是(N/2)+1,其中N是具有master资格的节点的数量
    • 如果脑裂问题已经发生该如何解决

      • 当脑裂发生后,唯一的修复办法是解决这个问题并重启集群。 当elasticsearch集群启动时,会选出一个主节点(一般是启动的第一个节点被选为主)。由于索引的两份拷贝已经不一样了,elasticsearch会认为选出来的主保留的分片是“主拷贝”并将这份拷贝推送给集群中的其他节点。这很严重。让我们设想下你是用的是node客户端并且一个节点保留了索引中的正确数据。但如果是另外的一个节点先启动并被选为主,它会将一份过期的索引数据推送给另一个节点,覆盖它,导致丢失了有效数据。
      • 所以怎么从脑裂中恢复?第一个建议是给所有数据重新索引。第二,如果脑裂发生了,要十分小心的重启你的集群。停掉所有节点并决定哪一个节点第一个启动。 如果需要,单独启动每个节点并分析它保存的数据。如果不是有效的,关掉它,并删除它数据目录的内容(删前先做个备份)。如果你找到了你想要保存数据的节点,启动它并且检查日志确保它被选为主节点。这之后你可以安全的启动你集群里的其他节点了。

Elasticsearch索引模板以及索引名

索引模板index template

  • 在我们的工作中,针对一个大批量的数据存储时需要使用多个索引库,如果我们手工去为每个索引库配置信息就很麻烦,所以就有了索引模板,创建一个模板,制定好配置信息,如果我们闯进的索引库匹配到了模板就会使用模板中的配置信息

  • 创建模板

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      curl -H "Content-Type: application/json" -XPUT localhost:9200/_template/template_1 -d '
      {
      "template" : "*",
      "order" : 0,
      "settings" : {
      "number_of_shards" : 1
      },
      "mappings" : {
      "type1" : {
      "_source" : { "enabled" : false }
      }
      }
      }
      其中的order值是用来进行模板之间的优先级排序的,如果一个索引匹配到多个模板则比较模板的order值,选取最大order值的模板进行配置信息匹配
  • 查看模板信息 curl -XGET localhost:9200/_template/temp*?pretty

  • 删除模板 curl -XDELETE localhost:9200/_template/temp_1

索引别名index alias

  • 索引别名就是为索引起一个或者多个别名方便引用

  • 公司使用es收集应用的日志,每个星期创建一个索引库,这样时间长了就会创建很多个索引库,操作和管理非常不方便

  • 由于新增的索引只会操作最新的这一周的索引库,所以我们就可以创建两个别名

  • curr_week :此别名执行这个星期的索引库,新增的数据操作这个索引库

  • last_3_month:这个别名指向的是近三个月的索引库,因为我们需要查询近三个月的数据

  • 后期只需要修改两个别名与索引库的指向关系即可,应用层的代码不许要更新、

  • 还需要将三个月之前的索引库close掉,将一年前的索引库删除

  • es默认对查询分片的数量是有限制的,默认是1000个,使用通配符查询多个索引库的时候会出问题,正好可以使用别名解决

  • 增加索引别名 可同时增减多个

    • 1
      2
      3
      4
      5
      6
      7
      8
      curl -H "Content-Type: application/json" -XPOST 'http://localhost:9200/_aliases' -d '
      {
      "actions" : [
      { "add" : { "index" : "test1", "alias" : "alias1" } },
      { "add" : { "index" : "test2", "alias" : "alias1" } }

      ]
      }'
  • 删除索引别名

    • 1
      2
      3
      4
      5
      6
      curl -H "Content-Type: application/json" -XPOST 'http://localhost:9200/_aliases' -d '
      {
      "actions" : [
      { "remove" : { "index" : "test1", "alias" : "alias1" } }
      ]
      }'

Elasticsearch参数调优

  • 解决es启动警告信息

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      vi /etc/security/limits.conf
      增加以下内容
      * soft nofile 65536
      * hard nofile 131072
      * soft nproc 2048
      * hard nproc 4096
      vi /etc/security/limits.d/90-nproc.conf
      把1024修改为4096
      * soft nproc 4096
  • 修改配置文件调整es的jvm内存大小

    • 修改bin/elasticsearch.in.sh中ES_MIN_MEM和ES_MAX_MEM的大小,建议设置一样大,避免频繁的分配内存,根据服务器内存大小,一般分配60%左右(默认256M)
    • 注意内存最大不要超过32G 一旦你越过这个神奇的32GB边界,指针会切换回普通对象指针.。每个指针的大小增加,使用更多的CPU内存带宽。事实上,你使用40~50G的内存和使用32G的内存效果是一样的。
  • 设置memory_lock来锁定进程的物理内存地址

    • 避免交换(swapped)来提高性能

      修改文件conf/elasticsearch.yml

      bootstrap.memory_lock: true

      需要根据es启动日志修改/etc/security/limits.conf文件(重启系统)

  • 改变分片的数量

    • 分片多的话,可以提升建立索引的能力,5-20个比较合适。
    • 如果分片的数量过多或者过少都会导致检索比较慢
    • 分片过多会导致查询的额时候打开较多的文件,而分片数过少会导至单个分片索引过大,所以检索速度也会慢。
    • 建议单个分片存储20G左右的索引数据【最高也不要超过50G,否则性能会很差】,所以,分片数量=数据总量/20G
    • 副本多的话,可以提升搜索的能力,但是如果设置很多副本的话也会对服务器造成额外的压力,因为主分片需要给所有副本同步数据。所以建议最多设置1-2个即可。
  • 针对不使用的index,建议close,减少内存占用。因为只要索引处于open状态,索引库中的segement就会占用内存,close之后就只会占用磁盘空间了。

    • curl -XPOST ‘localhost:9200/test/_close’
  • 要定时对索引进行合并优化,不然segment越多,占用的segment memory越多,查询的性能也越差

    • 索引量不是很大的话可以将segment设为1

    • 在es2.1.0以前调用_optimize接口,后期改为_forcemerge接口

      • 1
        2
        3
        curl -XPOST 'http://localhost:9200/test/_forcemerge?max_num_segments=1'
        client.admin().indices().prepareForceMerge("test").setMaxNumSegments(1).get();
        注意:索引合并是针对分片的。segment设置为1,则每个分片都有一个索引片段。
  • 删除文档:在es中删除文档,数据不会马上在硬盘上除去,而是在es索引中产生一个.del的文件,而在检索过程中这部分数据也会参与检索,es在检索过程会判断是否删除了,如果删除了在过滤掉。这样也会降低检索效率。所以可以执行清除删除文档

    • 1
      2
      3
      4
      shell:
      curl -XPOST 'http://localhost:9200/test/_forcemerge?only_expunge_deletes=true'
      java:
      client.admin().indices().prepareForceMerge("test").setOnlyExpungeDeletes(true).get();
  • 如果在项目开始的时候需要批量入库大量数据的话,建议将副本数设置为0

    • 因为es在索引数据的时候,如果有副本存在,数据也会马上同步到副本中,这样会对es增加压力。可以等索引完成后将副本按需要改回来。这样可以提高索引效率
  • Elasticsearch在建立索引时,根据id或(id,类型)进行hash,得到hash值之后再与该索引的分片数量取模,取模的值即为存入的分片编号

    • 可以指定把数据存储到某一个分片中,通过routing参数 可以显著提高性能

      • 1
        2
        curl -XPOST 'localhost:9200/yehua/emp?routing=rout_param' -d '{"name":"zs","age":20}'
        routing(路由参数)

博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Blog Zhao 作为主题 , 总访问量为 次 。
载入天数...载入时分秒...