1 增加 Refresh 时间间隔
2 减少副本数量
3、开启异步刷写
4、开启慢查询日志

二、服务器层面

5、内存设置
6、集群分片设置
7、Mapping建模
8、索引优化设置
9、查询优化

1 增加 Refresh 时间间隔

为了提高索引性能,Elasticsearch 在写入数据时候,采用延迟写入的策略,即数据先写到内存中,当超过默认 1 秒 (index.refresh_interval)会进行一次写入操作,就是将内存中 segment 数据刷新到操作系统中,此时我们才能将数据搜索出来,所以这就是为什么 Elasticsearch 提供的是近实时搜索功能,而不是实时搜索功能。

当然像我们的内部系统对数据延迟要求不高的话,我们可以通过延长 refresh 时间间隔,可以有效的减少 segment 合并压力,提供索引速度。在做全链路跟踪的过程中,我们就将 index.refresh_interval 设置为 30s,减少 refresh 次数。

同时,在进行全量索引时,可以将 refresh 次数临时关闭,即 index.refresh_interval 设置为 -1,数据导入成功后再打开到正常模式,比如 30s。

通过修改主配置文件 elasticsearch.yml 或者 Rest API 都可以对 index.refresh_interval 进行修改,增大该属性可以提升写入吞吐。

PUT  /_template/{TEMPLATE_NAME}
{
  "template":"{INDEX_PATTERN}",
  "settings" : {
    "index.refresh_interval" : "30s"
  }
}

PUT {INDEX_PAATERN}/_settings
{
    "index.refresh_interval" : "30s"
}

2 减少副本数量

Elasticsearch 默认副本数量为 3 个(7.x默认一个分片、一个副本),虽然这样会提高集群的可用性,增加搜索的并发数,但是同时也会影响写入索引的效率。

在索引过程中,需要把更新的文档发到副本节点上,等副本节点生效后在进行返回结束。
使用 Elasticsearch 做业务搜索的时候,建议副本数目还是设置为 3 个,但是像内部 ELK 日志系统、分布式跟踪系统中,完全可以将副本数目设置为 1 个。
在数据导入时,或是reindex的时候,可以将副本数改为0,等操作完毕后,在恢复事先定义的数目。

"settings": {
    "number_of_replicas":0 
  }
3、开启异步刷写

如果允许数据丢失,可以对特定 index 开启异步刷写:

PUT  /_template/{TEMPLATE_NAME}
{
  "template":"{INDEX_PATTERN}",
  "settings" : {
    "index.translog.durability": "async"
  }
}

PUT  {INDEX_PAATERN}/_settings
{
  "index.translog.durability": "async"
}
4、开启慢查询日志
不论是数据库还是搜索引擎,对于问题的排查,开启慢查询日志是十分必要的,ES 开启慢查询的方式有多种,但是最常用的是调用模板 API 进行全局设置:

PUT  /_template/{TEMPLATE_NAME}
{

"template":"{INDEX_PATTERN}",
  "settings" : {
    "index.indexing.slowlog.level": "INFO",
    "index.indexing.slowlog.threshold.index.warn": "10s",
    "index.indexing.slowlog.threshold.index.info": "5s",
    "index.indexing.slowlog.threshold.index.debug": "2s",
    "index.indexing.slowlog.threshold.index.trace": "500ms",
    "index.indexing.slowlog.source": "1000",
    "index.search.slowlog.level": "INFO",
    "index.search.slowlog.threshold.query.warn": "10s",
    "index.search.slowlog.threshold.query.info": "5s",
    "index.search.slowlog.threshold.query.debug": "2s",
    "index.search.slowlog.threshold.query.trace": "500ms",
    "index.search.slowlog.threshold.fetch.warn": "1s",
    "index.search.slowlog.threshold.fetch.info": "800ms",
    "index.search.slowlog.threshold.fetch.debug": "500ms",
    "index.search.slowlog.threshold.fetch.trace": "200ms"
  },
  "version"  : 1
}

PUT {INDEX_PAATERN}/_settings
{
    "index.indexing.slowlog.level": "INFO",
    "index.indexing.slowlog.threshold.index.warn": "10s",
    "index.indexing.slowlog.threshold.index.info": "5s",
    "index.indexing.slowlog.threshold.index.debug": "2s",
    "index.indexing.slowlog.threshold.index.trace": "500ms",
    "index.indexing.slowlog.source": "1000",
    "index.search.slowlog.level": "INFO",
    "index.search.slowlog.threshold.query.warn": "10s",
    "index.search.slowlog.threshold.query.info": "5s",
    "index.search.slowlog.threshold.query.debug": "2s",
    "index.search.slowlog.threshold.query.trace": "500ms",
    "index.search.slowlog.threshold.fetch.warn": "1s",
    "index.search.slowlog.threshold.fetch.info": "800ms",
    "index.search.slowlog.threshold.fetch.debug": "500ms",
    "index.search.slowlog.threshold.fetch.trace": "200ms"
}
这样,在日志目录下的慢查询日志就会有输出记录必要的信息了。

{CLUSTER_NAME}_index_indexing_slowlog.log
{CLUSTER_NAME}_index_search_slowlog.log
5、内存设置

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

5.1 当机器内存小于64G时,遵循通用的原则,50%给ES,50%留给lucene。
5.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。
    d. 当机器内存大于等于64G时,我们都会采用 31 G 设置
        -Xms 31g
        -Xmx 31g
5.3 禁止swap,一旦允许内存与磁盘的交换,会引起致命的性能问题。 通过: 在elasticsearch.yml 中 bootstrap.memory_lock: true, 以保持JVM锁定内存,保证ES的性能。
5.4 GC设置原则:
    a. 保持GC的现有设置,默认设置为:Concurrent-Mark and Sweep (CMS),别换成G1GC,因为目前G1还有很多BUG。
    b. 保持线程池的现有设置,目前ES的线程池较1.X有了较多优化设置,保持现状即可;默认线程池大小等于CPU核心数。如果一定要改,按公式((CPU核心数* 3)/ 2)+ 1 设置;不能超过CPU核心数的2倍;但是不建议修改默认配置,否则会对CPU造成硬伤。
    c.调整  elasticsearch.yml ,对 bulk/flush 线程池进行调优

threadpool.bulk.type:fixed
    threadpool.bulk.size:8 #(CPU核数)
    threadpool.flush.type:fixed
    threadpool.flush.size:8 #(CPU核数)

6、集群分片设置

ES一旦创建好索引后,就无法调整分片的设置,而在ES中,一个分片实际上对应一个lucene 索引,而lucene索引的读写会占用很多的系统资源,因此,分片数不能设置过大;所以,在创建索引时,合理配置分片数是非常重要的。一般来说,我们遵循一些原则:
    6.1 控制每个分片占用的硬盘容量不超过ES的最大JVM的堆空间设置(一般设置不超过32G,参加上文的JVM设置原则),因此,如果索引的总容量在500G左右,那分片大小在16个左右即可;当然,最好同时考虑原则6.2。
    6.2 考虑一下node数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,一旦该节点故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。所以, 一般都设置分片数不超过节点数的3倍。

7、Mapping建模

7.1 尽量避免使用nested或 parent/child,能不用就不用;nested query慢, parent/child query 更慢,比nested query慢上百倍;因此能在mapping设计阶段搞定的(大宽表设计或采用比较smart的数据结构),就不要用父子关系的mapping。
    7.2 如果一定要使用nested fields,保证nested fields字段不能过多,目前ES默认限制是50。参考:
    index.mapping.nested_fields.limit :50
    因为针对1个document, 每一个nested field, 都会生成一个独立的document, 这将使Doc数量剧增,影响查询效率,尤其是JOIN的效率。
    7.3 避免使用动态值作字段(key),  动态递增的mapping,会导致集群崩溃;同样,也需要控制字段的数量,业务中不使用的字段,就不要索引。控制索引的字段数量、mapping深度、索引字段的类型,对于ES的性能优化是重中之重。以下是ES关于字段数、mapping深度的一些默认设置:

index.mapping.nested_objects.limit :10000
    index.mapping.total_fields.limit:1000
    index.mapping.depth.limit: 20

8、索引优化设置

8.1 设置refresh_interval 为-1,同时设置number_of_replicas 为0,通过关闭refresh间隔周期,同时不设置副本来提高写性能。 
    8.2 修改index_buffer_size 的设置,可以设置成百分数,也可设置成具体的大小,大小可根据集群的规模做不同的设置测试。 
        indices.memory.index_buffer_size:10%(默认)
        indices.memory.min_index_buffer_size: 48mb(默认)
        indices.memory.max_index_buffer_size
    8.3 修改translog相关的设置:
        a. 控制数据从内存到硬盘的操作频率,以减少硬盘IO。可将sync_interval的时间设置大一些。
            index.translog.sync_interval:5s(默认)。
        b. 控制tranlog数据块的大小,达到threshold大小时,才会flush到lucene索引文件。
            index.translog.flush_threshold_size:512mb(默认)
    8.4 _id字段的使用,应尽可能避免自定义_id, 以避免针对ID的版本管理;建议使用ES的默认ID生成策略或使用数字类型ID做为主键。
    8.5 _all字段及_source字段的使用,应该注意场景和需要,_all字段包含了所有的索引字段,方便做全文检索,如果无此需求,可以禁用;_source存储了原始的document内容,如果没有获取原始文档数据的需求,可通过设置includes、excludes 属性来定义放入_source的字段。
    8.6 合理的配置使用index属性,analyzed 和not_analyzed,根据业务需求来控制字段是否分词或不分词。只有 groupby需求的字段,配置时就设置成not_analyzed, 以提高查询或聚类的效率。

9、查询优化

9.1 query_string 或 multi_match的查询字段越多, 查询越慢。可以在mapping阶段,利用copy_to属性将多字段的值索引到一个新字段,multi_match时,用新的字段查询。
    9.2 日期字段的查询, 尤其是用now 的查询实际上是不存在缓存的,因此, 可以从业务的角度来考虑是否一定要用now, 毕竟利用query cache 是能够大大提高查询效率的。
    9.3 查询结果集的大小不能随意设置成大得离谱的值, 如query.setSize不能设置成 Integer.MAX_VALUE, 因为ES内部需要建立一个数据结构来放指定大小的结果集数据。
    9.4 尽量避免使用script,万不得已需要使用的话,选择painless & experssions 引擎。一旦使用script查询,一定要注意控制返回,千万不要有死循环(如下错误的例子),因为ES没有脚本运行的超时控制,只要当前的脚本没执行完,该查询会一直阻塞。
    9.5 避免层级过深的聚合查询, 层级过深的group by , 会导致内存、CPU消耗,建议在服务层通过程序来组装业务,也可以通过pipeline的方式来优化。
    9.6 复用预索引数据方式来提高AGG性能:
    如通过 terms aggregations 替代 range aggregations, 如要根据年龄来分组,分组目标是: 少年(14岁以下) 青年(14-28) 中年(29-50) 老年(51以上), 可以在索引的时候设置一个age_group字段,预先将数据进行分类。从而不用按age来做range aggregations, 通过age_group字段就可以了。
    9.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://blog.csdn.net/u014646662/java/article/details/99293604

Java中的注解是如何工作的?--annotation学习一的更多相关文章

  1. Java中的注解是如何工作的?

    自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解.这篇文章中,我将向大家讲述 ...

  2. java中的注解(Annotation)

    转载:https://segmentfault.com/a/1190000007623013 简介 注解,java中提供了一种原程序中的元素关联任何信息.任何元素的途径的途径和方法. 注解是那些插入到 ...

  3. java中元注解

    java中元注解有四个: @Retention @Target @Document @Inherited:  @Retention:注解的保留位置 @Retention(RetentionPolicy ...

  4. java中的注解详解和自定义注解

    一.java中的注解详解 1.什么是注解 用一个词就可以描述注解,那就是元数据,即一种描述数据的数据.所以,可以说注解就是源代码的元数据.比如,下面这段代码: @Override public Str ...

  5. 有一部分程序员还不知道Java 中的注解到底是如何工作的?

    作者:人晓 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解. 这篇文章中, ...

  6. Java中的注解到底是如何工作的?

    作者:人晓 www.importnew.com/10294.html 自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分.开发过程中,我们也时常在应用代码中会看到诸如@Over ...

  7. 【java】细说 JAVA中 标注 注解(annotation)

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...

  8. 【java】详解java中的注解(Annotation)

    目录结构: contents structure [+] 什么是注解 为什么要使用注解 基本语法 4种基本元注解 重复注解 使用注解 运行时处理的注解 编译时处理的注解 1.什么是注解 用一个词就可以 ...

  9. 【转载:java】详解java中的注解(Annotation)

    目录结构: contents structure [+] 什么是注解 为什么要使用注解 基本语法 4种基本元注解 重复注解 使用注解 运行时处理的注解 编译时处理的注解 1.什么是注解 用一个词就可以 ...

随机推荐

  1. CUDA中的流与事件

    流:CUDA流很像CPU的线程,一个CUDA流中的操作按顺序进行,粗粒度管理多个处理单元的并发执行. 通俗的讲,流用于并行运算,比如处理同一副图,你用一个流处理左边半张图片,再用第二个流处理右边半张图 ...

  2. MySQL 常用show命令

    MySQL中有很多的基本命令,show命令也是其中之一,在很多使用者中对show命令的使用还容易产生混淆,本文汇集了show命令的众多用法. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  3. T恤

    64%聚酯纤维+36%纯棉比较舒服,洗了不易变形,普通纯棉易变形

  4. Unity3D研究院之Editor下监听Transform变化

    美术有可以直接在Editor下操作Transform,我想去修正他们编辑的数值,所以我就得监听Transform.       C#   1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...

  5. 怎么让OCR文字识别软件转换别的语言文档

    ABBYY PDF Transformer+让您可创建或转换希伯来语.意第绪语.日语.中文.泰语.韩语和阿拉伯语的文档.那么如何顺利使用这些复杂语言文字呢?小编教你两步骤轻松快速处理包含以下复杂语言文 ...

  6. unity, animtion倒放

    AnimationState.speed Description The playback speed of the animation. 1 is normal playback speed. A ...

  7. Jfinal中log4j的配置

    基本不用配置: 1.web.xml不用配置: 2.添加文件log4j.properties到src下面: 3.lib中复制log4j的jar包进去: 4.可以使用了; package demo; im ...

  8. 读取Config文件工具类 PropertiesConfig.java

    package com.util; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io ...

  9. SQL SERVER 生成MYSQL建表脚本

    /****** Object: StoredProcedure [dbo].[GET_TableScript_MYSQL] Script Date: 06/15/2012 13:05:14 ***** ...

  10. jQuery图片无缝滚动JS代码ul/li结构

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...