查看段内存大小

curl -s -uelastic:changeme 'http://IP:9200/_cat/segments?v'

 

curl -s -uelastic:changeme 'http://IP:9200/_cat/nodes?v&h=segments.count,segments.memory,segments.index_writer_memory,segments.version_map_memory,segments.fixed_bitset_memory'

返回

 

查看模板

http://ip:9200/_cat/templates?v

 

集群管理篇


 

后台查看所有分片状态

http://IP:9200/_cat/shards

查询得到master节点的唯一标识

http://IP:9200/_nodes/process?pretty

 

ElasticSearch的坑

(https://www.jianshu.com/p/4bbc894e520e)

 

遇到的问题

  • 创建索引太慢

Elasticsearch创建分片速度会随着集群内分片数增加变慢。以ES 5.5.2版本、3节点集群为例,在默认配置下,当集群分片数超过1w时,创建index的耗时一般在几十秒甚至以上。

ElasticSearch默认是5个分片,1个副本,相当于每创建一个索引就会产生10个分片。一开始没有问题,后来索引数目达到了4000左右(其中大部分数据量都很小,几十M而已),也就是有超过1万的分片存在,所有节点都需要维护分片和节点的关系,而且为了保证一致性,都是单线程更新,所以效率很低。

  • 重启ElasticSearch节点出现大量未分配分片

当一个节点不可达后,为了尽快恢复集群的高可用特性,ElasticSearch会尽快地重新调整分片,没有副本的,也会全量复制分片。当节点恢复后,集群又会再次重新调整分片,达到负载均衡的目的

修改延迟分配时间为5分钟

PUT _all/_settings

{

  "settings": {

    "index.unassigned.node_left.delayed_timeout": "5m"

  }

}

  • 关闭一个节点后,集群状态变成red

当时有部分索引的主分片一直没有分配,导致集群处于red状态。当时没有仔细分析原因,只是快速地把那部分索引进行重建处理(从其他数据源导入)。当时还不知道怎么查看未分配的原因,其实可以查看分片详情命令,看到未分配的原因

#分片详情命令,查看未分配的原因

_cat/shards?h=index,shard,prirep,state,unassigned.reason&v

采用的措施有:手工分配,但是系统表示不支持命令allocate

最佳实践

  • 索引很小,shard设置为1,replica也是1就可以了
  • ElasticSearch推荐的最大JVM堆空间是30~32G
  • 一般一个分片不要超过50GB
  • 索引稳定后,可以使用forcemerge,提高检索效率
  • shrink index API

参考

  • How many shards should I have in my Elasticsearch cluster?
  • [译]优化ElasticSearch之合理分配索引分片
  • Elasticsearch最佳实践之分片使用优化
  • Delaying allocation when a node leaves

 

 

 

# 查看索引相关信息

GET kibana_sample_data_ecommerce

 

# 查看索引的文档总数

GET kibana_sample_data_ecommerce/_count

 

# 查看前10条文档,了解文档格式

POST kibana_sample_data_ecommerce/_search

{

}

 

# _cat indices API

# 查看indices

GET /_cat/indices/kibana*?v&s=index

 

# 查看状态为绿的索引

GET /_cat/indices?v&health=green

 

# 按照文档个数排序

GET /_cat/indices?v&s=docs.count:desc

 

# 查看具体的字段

GET /_cat/indices/kibana*?pri&v&h=health,index,pri,rep,docs.count,mt

 

# How much memory is used per index?

GET /_cat/indices?v&h=i,tm&s=tm:desc

 

 

查询管理命令列表

curl 'localhost:9200/_cat'

 

 

1.集群管理

集群状态查询

curl 'localhost:9200/_cat/health?v'

curl '192.168.56.10:9200/_cat/nodes?v'

curl '192.168.56.10:9200/_cat/nodes?v&h=hc,hm,rc,rm'

 

 

 

启动节点

bin/elasticsearch     -Des.cluster.name=es4fql   -Des.node.name=n_4.216  -d

关闭节点

curl -XPOST 'http://localhost:9200/_cluster/nodes/n2/_shutdown'

curl -XPOST 'http://localhost:9200/_shutdown'

curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown?delay=10s'

 

 

 

2.索引管理

查询索引状态

curl 'localhost:9200/_cat/indices?v'

 

 

创建索引

curl -XPUT 'localhost:9200/goods_v1?pretty'

 

 

删除索引

curl -XDELETE 'localhost:9200/goods_v1?pretty'

 

 

创建别名

curl -XPOST localhost:9200/_aliases -d '

{

    "actions": [

        { "add": {

            "alias": "goods",

            "index": "goods_v1"

        }}

    ]

}

'

删除并更新别名

curl -XPOST 'http://localhost:9200/_aliases' -d '

{

    "actions" : [

        { "remove" : { "index" : "goods_v2", "alias" : "goods" } },

        { "add" : { "index" : "goods_v1", "alias" : "goods" } }

    ]

}'

 

 

查看已有别名

curl -XGET 'localhost:9200/_cat/aliases'

 

 

查看别名对应的索引

curl -XGET 'localhost:9200/_alias/help'

 

 

 

 

创建mapping

curl -XPOST http://localhost:9200/goods_v1/fulltext/_mapping -d'

{

    "fulltext": {

             "_all": {

            "indexAnalyzer": "ik",

            "searchAnalyzer": "ik_syno",

            "term_vector": "no",

            "store": "false"

        },

     "properties": {

        "sku_id" :{

          "type": "string"

      },

      "product_id":{

          "type": "string"

      },

      "product_name":{

          "type": "string",

          "store": "no",

          "term_vector": "with_positions_offsets",

          "indexAnalyzer": "ik",

          "searchAnalyzer": "ik_syno",

          "include_in_all": "true",

          "boost": 8

      }

    }

    }

}'

 

 

获取mapping

curl -XGET 'http://localhost:9200/help/_mapping/fulltext?pretty'

 

查看分区

curl 'localhost:9200/_cat/shards?v'

 

curl -XGET 'http://localhost:9200/_cat/shards' | grep INIT

 

修复unsigned 分区

for shard in $(curl -XGET http://localhost:9200/_cat/shards | grep UNASSIGNED | grep goods_v1 |awk '{print $2}'); do

    curl -XPOST 'localhost:9200/_cluster/reroute' -d '{

        "commands" : [ {

              "allocate" : {

                  "index" : "goods_v1", 

                  "shard" : $shard, 

                  "node" : "n_4.216", 

                  "allow_primary" : false

              }

            }

        ]

    }'

    sleep 5

done

 

 

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{

        "commands" : [ {

              "allocate" : {

                  "index" : "goods", 

                  "shard" : 2, 

                  "node" : "n2", 

                  "allow_primary" : false

              }

            }

        ]

    }'

 

 

 

 

索引修复

java -cp lucene-core-4.10.4.jar -ea:org.apache.lucene... org.apache.lucene.index.CheckIndex /opt/elasticsearch-1.5.0/data/elasticsearch/nodes/0/indices/goods_v2/2/index -fix

 

 

解决unsigned 分区的问题

curl -XPUT 'localhost:9200/<index>/_settings' \

    -d '{"index.routing.allocation.disable_allocation": false}'

 

 

3.文档管理

获取文档

curl -XGET 'localhost:9200/goods/fulltext/S201406251699?pretty'

删除文档

curl -XDELETE 'localhost:9200/goods/fulltext/1?pretty'

 

 

获取索引中前10个文档

curl -XPOST 'localhost:9200/goods/_search?pretty' -d '

{

  "query": { "match_all": {} }

}'

 

 

4.缓存管理

创建时显式开启缓存

curl -XPUT localhost:9200/my_index -d'

{

  "settings": {

    "index.cache.query.enable": true

  }

}

'

更新设置开启缓存

curl -XPUT localhost:9200/goods/_settings -d'

{ "index.cache.query.enable": true }

'

 

 

查询各节点缓存状态

curl 'localhost:9200/_nodes/stats/indices/query_cache?pretty&human'

5.分词测试

curl -XGET 'http://localhost:9200/goods/_analyze?analyzer=ik_max_word_syno&pretty' -d '爱疯狂'

————————————————

版权声明:本文为CSDN博主「believetruelove」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:

别名

Put  test1/_alias/test11

 

{

  • "acknowledged": true

}

 

节点磁盘使用率85% 90% 95%

 

1、节点磁盘使用率过高,导致ES集群shard无法分配,丢失数据?

有两个配置,分配副本的时候

参数名称

默认值

含义

cluster.routing.allocation.disk.watermark.low

85%

当节点磁盘占用量高于85%时,就不会该节点分配副本

cluster.routing.allocation.disk.watermark.high

90%

当节点磁盘占用量高于90%时,尝试将该节点的副本重分配到其他节点

配置方式

curl -XPUT 'localhost:9200/_cluster/settings' -d

'{

"transient": {  

"cluster.routing.allocation.disk.watermark.low": "90%"

    }

}'

 建议:密切关注ES集群节点的性能参数,对潜在风险有感知。

 https://elasticsearch.cn/question/4026

cluster.routing.allocation.disk.threshold_enabled: false

模板管理

template机制是比较有用的,特别是管理大量索引的时候。先给一个template的demo。

order:10  template的优先级,优先级高(order数字大的)会覆盖优先级低的template里的字段。

template:test*,这个template会命中test开头的索引。

index.number_of_shards:20 //index的一些配置

index.number_of_replicas::1

index.refresh_interval:5s

 

{

"aliases": {},

"order": 10,

"template": "test*",

"settings": {

"index": {

"priority": "5",

"merge": {

"scheduler": {

"max_thread_count": "1"

                }

            },

"search": {

"slowlog": {

"threshold": {

"query": {

"warn": "10s",

"debug": "1s",

"info": "5s",

"trace": "500ms"

                        },

"fetch": {

"warn": "1s",

"debug": "500ms",

"info": "800ms",

"trace": "200ms"

                        }

                    }

                }

            },

"unassigned": {

"node_left": {

"delayed_timeout": "5m"

                }

            },

"max_result_window": "10000",

"number_of_shards": "20",

"number_of_replicas": "1",

"translog": {

"durability": "async"

            },

"requests": {

"cache": {

"enable": "true"

                }

            },

"mapping": {

"ignore_malformed": "true"

            },

"refresh_interval": "5s"

        }

    }

}

 

配置方式

curl -XPUT localhost:9200/_template/template_1 -d '

{

"template" : "test*",

"order" : 0,

"settings" : {

"number_of_shards" : 1

    },

"mappings" : {

"type1" : {

"_source" : { "enabled" : false }

        }

    }

}

'

 

在配置了模板以后,如何建立索引

# 索引创建

curl -XPUT http://35.1.4.127:9200/index_name

 

3、mapping创建的一些注意事项

在创建索引type mapping的时候要妥善处理好_all和_source,不然会影响索引的性能。

_all,enable的话会把一个type中的所有字段合并成一个大字段,增加索引时间和大小。

_source,enable的话会请求会返回_source的结构体。

一般我们会禁用_all,打开_source。

另外,对时间的处理,可以如下这样,对于各种繁琐的时间格式都是支持的。

配置方式

 

curl -PUT http://35.1.4.129:9200/index_name/RELATION/_mapping -d '{

"RELATION": {

"_all": {

"enabled": "false"

        },

"_source": {

"enabled": "true"

        },

"properties": {

"FROM_SFZH": {

"type": "keyword"

            },

"TO_SFZH": {

"type": "keyword"

            },

"CREATE_TIME": {

"type": "date",

"format": "yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||strict_date_optional_time||epoch_millis||yyyy-MM-dd HH:mm:ss"

            }

        }

    }

}'

 

 

4、批量数据灌入ES时要禁用副本和刷新

大规模批量导入数据的时候,要禁用副本和刷新,ES在索引数据的时候,如果有副本的话,会同步副本,造成压力。

等到数据索引完成后,在恢复副本。

配置方法

 

// 关闭
curl -PUT http://35.1.4.129:9200/_settings -d '{

"index": {

"number_of_replicas" : 0

"refresh_interval" : -1

}    

}'

 

 

// 打开

curl -PUT http://35.1.4.129:9200/_settings -d '{

"index": {

"number_of_replicas" : 1

"refresh_interval" : 5s

}    

}'

 

 

 5、jvm层面监控和优化

Elasticsearch是java开发的组件,当然可以压测看一下jvm的表现,例如通过jconsole远程连接。

config/jvm.options里面有各种jvm的配置,可以根据硬件资源合理配置一下。jvm调优就不说了。

-Djava.rmi.server.hostname=192.168.1.152

-Dcom.sun.management.jmxremote

-Dcom.sun.management.jmxremote.port=9110

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.authenticate=false

 

6、高并发查询时,优化ES线程池

当你查询并发上来了,有时候你会发现下面这个异常

EsRejectedExcutionException[rejected execution(queue capacity 50) on.......]

这个原因是在新版本的elasticsearch中线程池已经是fixed类型了,即固定大小的线程池,默认是5*core数,当所有线程忙碌,且队列满的情况下,es会拒绝请求。

多种请求类型对应多种线程池

index:此线程池用于索引和删除操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为200。

search:此线程池用于搜索和计数请求。它的类型默认为fixed,size默认为(可用处理器的数量* 3) / 2) + 1,队列的size默认为1000。

suggest:此线程池用于建议器请求。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。

get:此线程池用于实时的GET请求。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。

bulk:此线程池用于批量操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为50。

percolate:此线程池用于预匹配器操作。它的类型默认为fixed,size默认为可用处理器的数量,队列的size默认为1000。

这里以index为例,可以在elasticsearch.yml中修改线程池配置

threadpool.index.type: fixed

threadpool.index.size: 100

threadpool.index.queue_size: 500

通过api控制

 

curl -XPUT 'localhost:9200/_cluster/settings' -d '{

"transient": {

"threadpool.index.type": "fixed",

"threadpool.index.size": 100,

"threadpool.index.queue_size": 500

    }

}'

 

 

 

elasticsearch 5.x 系列之二 线程池的设置

7、 若干副本shard分配不成功,集群状态yellow

7.1 先看看集群状态

curl -XGET http://10.96.78.164:9200/_cluster/health?pretty

结果如下,如果有未分配的分片,unassigned_shards应该不为0,status=yellow。

 

{

"cluster_name": "elasticsearch",

"status": "green",

"timed_out": false,

"number_of_nodes": 1,

"number_of_data_nodes": 1,

"active_primary_shards": 575,

"active_shards": 575,

"relocating_shards": 0,

"initializing_shards": 0,

"unassigned_shards": 0,

"delayed_unassigned_shards": 0,

"number_of_pending_tasks": 0,

"number_of_in_flight_fetch": 0,

"task_max_waiting_in_queue_millis": 0,

"active_shards_percent_as_number": 100

}

 

 

7.2 查看未分配的shard属于哪个index,以及allocate的目标机器是哪个。

curl -XGET http://localhost:9200/_cat/shards | grep UNASSIGNED

结果

xiankan_xk_qdhj                  3 r UNASSIGNED    0    261b 10.96.78.164 yfbf9D3

xiankan_xk_qdhj                  2 r UNASSIGNED    0    261b 10.96.78.164 yfbf9D3

xiankan_xk_qdhj                  1 r UNASSIGNED    0    261b 10.96.78.164 yfbf9D3

xiankan_xk_qdhj                  4 r UNASSIGNED    0    261b 10.96.78.164 yfbf9D3

r-表示副本分片,p是主分片,ip是分配目标机器

 

7.3 尝试1:索引级别的副本重新分配

有问题的索引,先关闭其副本,然后打开重新分配副本。

关闭

curl -PUT http://35.1.4.129:9200/xiankan_xk_zjhj/_settings -d '{

"index": {

"number_of_replicas" : 0

}    

}'

打开

http://10.96.78.164:9200/xiankan_xk_zjhj/_settings -d '{

"index": {

"number_of_replicas": 1

  }

}'

 

7.4 尝试2:node级别的副本重新分配

重启shard分配不成功的node,如果shard分布在为数不多的几个node上,可以根据ip重启node上的es实例

杀死es

ps -ef | grep elasticsearch | grep -v grep | awk '{print $2}' | xargs kill -9

启动es

./bin/elasticsearch -d

 

7.5 尝试3:逐个索引shard的reroute

 

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{

"commands" : [ {

"allocate" : {

"index" : "xiankan_xk_zjhj",

"shard" : 1,

"node" : "yfbf9D3",

"allow_primary" : true

}

}

] }'

 

 

elasticsearch设置之setting(静态、动态)、mapping相关


一、setting相关

1.静态设置:只能在索引创建时或在状态为 closed index(闭合索引)上设置

 

参数 说明

index.number_of_shards 主分片数,默认为5.只能在创建索引时设置,不能修改

index.shard.check_on_startup 是否应在索引打开前检查分片是否损坏,当检查到分片损坏将禁止分片被打开。false:默认值;checksum:检查物理损坏;true:检查物理和逻辑损坏,这将消耗大量内存和CPU;fix:检查物理和逻辑损坏。有损坏的分片将被集群自动删除,这可能导致数据丢失

index.routing_partition_size 自定义路由值可以转发的目的分片数。默认为 1,只能在索引创建时设置。此值必须小于index.number_of_shards

index.codec 默认使用LZ4压缩方式存储数据,也可以设置为 best_compression,它使用 DEFLATE 方式以牺牲字段存储性能为代价来获得更高的压缩比例

2.动态设置

 

参数 说明

index.number_of_replicas 每个主分片的副本数。默认为 1。

index.auto_expand_replicas 基于可用节点的数量自动分配副本数量,默认为 false(即禁用此功能)

index.refresh_interval 执行刷新操作的频率,这使得索引的最近更改可以被搜索。默认为 1s。可以设置为 -1 以禁用刷新。

index.max_result_window 用于索引搜索的 from+size 的最大值。默认为 10000

index.max_rescore_window 在搜索此索引中 rescore 的 window_size 的最大值

index.blocks.read_only 设置为 true 使索引和索引元数据为只读,false 为允许写入和元数据更改。

index.blocks.read 设置为 true 可禁用对索引的读取操作

index.blocks.write 设置为 true 可禁用对索引的写入操作

index.blocks.metadata 设置为 true 可禁用对索引元数据的读取和写入

index.max_refresh_listeners 索引的每个分片上可用的最大刷新侦听器数

二、mapping相关

1.基本数据类型

 

类型 说明

字符串类型 string,text,keyword

整数类型 integer,long,short,byte

浮点类型 double,float,half_float,scaled_float

逻辑类型 boolean

日期类型 date

范围类型 range

二进制类型 binary

2.字符串类型

(1)string

string类型在ElasticSearch 旧版本中使用较多,从ElasticSearch 5.x开始不再支持string,由text和keyword类型替代。

(2)text

当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。

(3)keyword

keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到。

 

3.字符串类型可接受参数

 

————————————————

版权声明:本文为CSDN博主「残阳蓝夕」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:

调优

https://elasticsearch.cn/article/6202

配置文件层面

系统层面

使用方式调优

 

 

 

TTL(高版本已无此功能)

Elasticsearch使用TTL导致OOM问题分析解决


 

 

ES 内存分析

 

通过jmap获取堆转储快照,9326 是ES进程的pid,命令如下:

jmap -dump:live,format=b,file=/export/dump/dump.hd 9326

 

在Linux上安装mat,进入mat目录,使用mat工具分析dump文件,命令如下:

 

./ParseHeapDump.sh /export/dump/dump.hd

./ParseHeapDump.sh /export/dump/dump.hd org.eclipse.mat.api:suspects

./ParseHeapDump.sh /export/dump/dump.hd org.eclipse.mat.api:overview

./ParseHeapDump.sh /export/dump/dump.hd org.eclipse.mat.api:top_components

 

生成三个报告:

dump_Top_Components.zip

dump_System_Overview.zip

dump_Leak_Suspects.zip

————————————————

版权声明:本文为CSDN博主「daydayupzzc」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:

 

elasticsearch使用7大原则,让你玩转ES

一、 硬件环境选择

  如果有条件,尽可能使用SSD硬盘, 不错的CPU。ES的厉害之处在于ES本身的分布式架构以及lucene的特性;IO的提升,会极大改进ES的速度和性能;内存配置方面,一般来说,64G内存的机器节点较佳。

二、系统拓朴设计

ES集群在架构拓朴时,一般都会采用Hot-Warm的架构模式,即设置3种不同类型的节点:Master节点、Hot 节点和Warm节点。

Master节点设置:一般会设置3个专用的maste节点,以提供最好的弹性扩展能力。当然,必须注意

discovery.zen.minimum_master_nodes属性的设置,以防split-brain问题,使用公式设置:N/2+1(N为候选master节点数)。 该节点保持: node.data: false ; 因为master节点不参与查询、索引操作,仅负责对于集群管理,所以在CPU、内存、磁盘配置上,都可以比数据节点低很多。

Hot节点设置:索引节点(写节点),同时保持近期频繁使用的索引。 属于IO和CPU密集型操作,建议使用SSD的磁盘类型,保持良好的写性能;节点的数量设置一般是大于等于3个。将节点设置为hot类型:

node.attr.box_type:hot

  针对index, 通过设置

index.routing.allocation.require.box_type:hot 可以设置将索引写入hot节点。

Warm节点设置: 用于不经常访问的read-only索引。由于不经常访问,一般使用普通的磁盘即可。内存、CPU的配置跟Hot节点保持一致即可;节点数量一般也是大于等于3个。

  当索引不再被频繁查询时,可通过

index.routing.allocation.require.box_type:warm, 将索引标记为warm, 从而保证索引不写入hot节点,以便将SSD磁盘资源用在刀刃上。一旦设置这个属性,ES会自动将索引合并到warm节点。同时,也可以在elasticsearch.yml中设置index.codec: best_compression 保证warm 节点的压缩配置。

Coordinating节点:协调节点用于做分布式里的协调,将各分片或节点返回的数据整合后返回。在ES集群中,所有的节点都有可能是协调节点,但是,可以通过设置node.master、node.data 、node.ingest 都为false 来设置专门的协调节点。需要较好的CPU和较高的内存。

三、ES的内存设置

  由于ES构建基于lucene, 而lucene设计强大之处在于lucene能够很好的利用操作系统内存来缓存索引数据,以提供快速的查询性能。lucene的索引文件segements是存储在单文件中的,并且不可变,对于OS来说,能够很友好地将索引文件保持在cache中,以便快速访问;因此,我们很有必要将一半的物理内存留给lucene ; 另一半的物理内存留给ES(JVM heap )。所以, 在ES内存设置方面,可以遵循以下原则:

1.当机器内存小于64G时,遵循通用的原则,50%给ES,50%留给lucene。

2.当机器内存大于64G时,遵循以下原则:

a. 如果主要的使用场景是全文检索, 那么建议给ES Heap分配4~32G的内存即可;其它内存留给操作系统, 供lucene使用(segments cache), 以提供更快的查询性能。

b. 如果主要的使用场景是聚合或排序, 并且大多数是numerics, dates, geo_points 以及not_analyzed的字符类型, 建议分配给ES Heap分配4~32G的内存即可,其它内存留给操作系统,供lucene使用(doc values cache),提供快速的基于文档的聚类、排序性能。

c. 如果使用场景是聚合或排序,并且都是基于analyzed 字符数据,这时需要更多的heap size, 建议机器上运行多ES实例,每个实例保持不超过50%的ES heap设置(但不超过32G,堆内存设置32G以下时,JVM使用对象指标压缩技巧节省空间),50%以上留给lucene。

3.禁止swap,一旦允许内存与磁盘的交换,会引起致命的性能问题。

  通过在elasticsearch.yml中bootstrap.memory_lock: true,以保持JVM锁定内存,保证ES的性能。

4. GC设置原则:

a. 保持GC的现有设置,默认设置为:Concurrent-Mark and Sweep (CMS),别换成G1GC,因为目前G1还有很多BUG。

b. 保持线程池的现有设置,目前ES的线程池较1.X有了较多优化设置,保持现状即可;默认线程池大小等于CPU核心数。如果一定要改,按公式((CPU核心数* 3)/ 2)+ 1 设置;不能超过CPU核心数的2倍;但是不建议修改默认配置,否则会对CPU造成硬伤。

四、 集群分片设置

ES一旦创建好索引后,就无法调整分片的设置,而在ES中,一个分片实际上对应一个lucene 索引,而lucene索引的读写会占用很多的系统资源,因此,分片数不能设置过大;所以,在创建索引时,合理配置分片数是非常重要的。一般来说,我们遵循一些原则:

1.控制每个分片占用的硬盘容量不超过ES的最大JVM的堆空间设置(一般设置不超过32G,参加上文的JVM设置原则),因此,如果索引的总容量在500G左右,那分片大小在16个左右即可;当然,最好同时考虑原则2。

2.考虑一下node数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以, 一般都设置分片数不超过节点数的3倍。

五、Mapping建模

1.尽量避免使用nested或parent/child,能不用就不用;nested query慢,parent/child query 更慢,比nested query慢上百倍;因此能在mapping设计阶段搞定的(大宽表设计或采用比较smart的数据结构),就不要用父子关系的mapping。

2.如果一定要使用nested fields,保证nested fields字段不能过多,目前ES默认限制是50。参考:

index.mapping.nested_fields.limit :50

  因为针对1个document, 每一个nested field, 都会生成一个独立的document, 这将使Doc数量剧增,影响查询效率,尤其是JOIN的效率。

3.避免使用动态值作字段(key), 动态递增的mapping,会导致集群崩溃;同样,也需要控制字段的数量,业务中不使用的字段,就不要索引。控制索引的字段数量、mapping深度、索引字段的类型,对于ES的性能优化是重中之重。以下是ES关于字段数、mapping深度的一些默认设置:

index.mapping.nested_objects.limit :10000

index.mapping.total_fields.limit:1000

index.mapping.depth.limit: 20

六、 索引优化设置

1.设置refresh_interval为-1,同时设置number_of_replicas 为0,通过关闭refresh间隔周期,同时不设置副本来提高写性能。

2.修改index_buffer_size 的设置,可以设置成百分数,也可设置成具体的大小,大小可根据集群的规模做不同的设置测试。

indices.memory.index_buffer_size:10%(默认)

indices.memory.min_index_buffer_size: 48mb(默认)

indices.memory.max_index_buffer_size

3.修改translog相关的设置:

a. 控制数据从内存到硬盘的操作频率,以减少硬盘IO。可将sync_interval的时间设置大一些。

index.translog.sync_interval:5s(默认)

b. 控制tranlog数据块的大小,达到threshold大小时,才会flush到lucene索引文件。

index.translog.flush_threshold_size:512mb(默认)

4. _id字段的使用,应尽可能避免自定义_id, 以避免针对ID的版本管理;建议使用ES的默认ID生成策略或使用数字类型ID做为主键。

5. _all字段及_source字段的使用,应该注意场景和需要,_all字段包含了所有的索引字段,方便做全文检索,如果无此需求,可以禁用;_source存储了原始的document内容,如果没有获取原始文档数据的需求,可通过设置includes、excludes 属性来定义放入_source的字段。

6.合理的配置使用index属性,analyzed 和not_analyzed,根据业务需求来控制字段是否分词或不分词。只有groupby需求的字段,配置时就设置成not_analyzed, 以提高查询或聚类的效率。

七、 查询优化

1. query_string 或multi_match的查询字段越多, 查询越慢。可以在mapping阶段,利用copy_to属性将多字段的值索引到一个新字段,multi_match时,用新的字段查询。

2.日期字段的查询, 尤其是用now 的查询实际上是不存在缓存的,因此, 可以从业务的角度来考虑是否一定要用now, 毕竟利用query cache 是能够大大提高查询效率的。

3.查询结果集的大小不能随意设置成大得离谱的值, 如query.setSize不能设置成 Integer.MAX_VALUE, 因为ES内部需要建立一个数据结构来放指定大小的结果集数据。

4.尽量避免使用script,万不得已需要使用的话,选择painless & experssions 引擎。一旦使用script查询,一定要注意控制返回,千万不要有死循环(如下错误的例子),因为ES没有脚本运行的超时控制,只要当前的脚本没执行完,该查询会一直阻塞。

 

5.避免层级过深的聚合查询, 层级过深的group by , 会导致内存、CPU消耗,建议在服务层通过程序来组装业务,也可以通过pipeline的方式来优化。

6.复用预索引数据方式来提高AGG性能:如通过terms aggregations 替代range aggregations, 如要根据年龄来分组,分组目标是: 少年(14岁以下) 青年(14-28) 中年(29-50) 老年(51以上), 可以在索引的时候设置一个age_group字段,预先将数据进行分类。从而不用按age来做range aggregations, 通过age_group字段就可以了。

7. Cache的设置及使用:

a.QueryCache: ES查询的时候,使用filter查询会使用query cache, 如果业务场景中的过滤查询比较多,建议将querycache设置大一些,以提高查询速度。

indices.queries.cache.size: 10%(默认),可设置成百分比,也可设置成具体值,如256mb。

  当然也可以禁用查询缓存(默认是开启), 通过index.queries.cache.enabled:false设置。

b.FieldDataCache: 在聚类或排序时,field data cache会使用频繁,因此,设置字段数据缓存的大小,在聚类或排序场景较多的情形下很有必要,可通过

indices.fielddata.cache.size:30% 或具体值10GB来设置。但是如果场景或数据变更比较频繁,设置cache并不是好的做法,因为缓存加载的开销也是特别大的。

c.ShardRequestCache: 查询请求发起后,每个分片会将结果返回给协调节点(Coordinating Node), 由协调节点将结果整合。

  如果有需求,可以设置开启; 通过设置

index.requests.cache.enable: true来开启。

  不过,shard request cache只缓存hits.total, aggregations, suggestions类型的数据,并不会缓存hits的内容。也可以通过设置

indices.requests.cache.size: 1%(默认)来控制缓存空间大小。

 

 

日志级别及慢日志设置

https://www.elastic.co/guide/cn/elasticsearch/guide/current/logging.html

 

  1.   配置文件注意

1.  path.data和path.logs 般需要配置到独立的磁盘分区下

2.  bootstrap.memory_lock:ture ,防止swap

 

  1.   堆大小设置

       min(31G, 物理内存/2)

 

  1.  磁盘尽量SSD
  2.  磁盘监控

      磁盘占用85%后,不在分配副本,(目前集团90%预警短信或空闲空间10G),应监控80%较为合适。

     

  1.  CPU核数16+
  2.  ES服务器文件描述符扩大(ulimit -n 65536)

 

  1.  ES服务器JVM最好与应用程序版本一致

 

  1.  使用别名(读使用)

 

  1.  索引数、分片数、副本数

 

     1. 索引数不要太多, 分片大小不超过50G

     2. 副本数设为1

     3. 默认分片为1(Since 7.X), 建议分片数:数据容量/40G

 

 

 

  1.  Mapping

     1. 不使用默认mapping, 枚举类型映射为keyword

     2. 字段默认 

Indexed:true.  非查询条件字段可设置为false

Store: false.    

doc_value:  true. 不需要排序、聚合的字段设置为false

_all: fasle

 

 

  1. 数据写入优化

        批量写入(数据大小在5-15M左右为好,默认不超过100M)

 

 

  1. 禁用 wildcard模糊匹配

 

  1. 禁用swap(见1)
  2. 配置索引主键字段(而非ES自动生成)
  3. 查询使用filter过滤器
  4. 控制返回字段和结果(需要什么返回什么,非全部返回)

 查看缓存信息

        http://IP:9200/_nodes/stats/indices/query_cache?pretty&human

 

 

{
    "from":9900,
    "size":200,
    "query":{
        "bool":{
            "must":[
                {
                    "range":{
                        "cardValidityEndDate":{
                            "from":null,
                            "to":"2020-07-08T16:00:00.000Z",
                            "include_lower":true,
                            "include_upper":true,
                            "boost":1
                        }
                    }
                },
                {
                    "nested":{
                        "query":{
                            "bool":{
                                "must":[
                                    {
                                        "term":{
                                            "contactList.contactType":{
                                                "value":"1",
                                                "boost":1
                                            }
                                        }
                                    }
                                ],
                                "adjust_pure_negative":true,
                                "boost":1
                            }
                        },
                        "path":"contactList",
                        "ignore_unmapped":false,
                        "score_mode":"avg",
                        "boost":1
                    }
                },
                {
                    "nested":{
                        "query":{
                            "bool":{
                                "must":[
                                    {
                                        "terms":{
                                            "policyRoleList.policyRole":[
                                                "1",
                                                "2",
                                                "4",
                                                "5",
                                                "6",
                                                "7"
                                            ],
                                            "boost":1
                                        }
                                    }
                                ],
                                "adjust_pure_negative":true,
                                "boost":1
                            }
                        },
                        "path":"policyRoleList",
                        "ignore_unmapped":false,
                        "score_mode":"avg",
                        "boost":1
                    }
                }
            ],
            "adjust_pure_negative":true,
            "boost":1
        }
    }
}