elasticsearchJ2EE基础

Elasticsearch使用积累(持续更新...)

2017-01-06  本文已影响799人  Kungfu猫熊

写在前面

接触Elasticsearch已经有几年的时间, 从一开始在自己的普通台式机上搭建单实例来简单记录测试环境的日志, 到现在生产上用9个Elasticsearch实例搭成的集群来记录商城后台服务的全量日志. 使用场景没变,都是用了记录日志, 并做实时检索和统计. 但是随着每天记录的数据量快速递增,QPS快速递增,我们经常会碰到一些性能问题,这些问题一直在驱动我们对Elasticsearch集群进行持续优化, 这里是有必要记录一下我们在使用ES(后续文章中用ES代替Elasticsearch)的过程中积累的经验.

常用插件

ES集群优雅停止,启动

在一开始使用ES的时候, 都是通过 kill <pid> (不是Kill -9)来关闭ES实例. 但是每回重启后, 都会发现有很长时间的分片同步(即使没有手动删除数据等操作). 后来发现ES默认是开启自动分片均衡的. 那么如果想要我们在停止,启动某个ES实例后, 可以快速将集群状态变更为Green. 我们最好可以采用如下步骤进行:

备注: 如果在集群中关闭自动均衡, 业务程序在插入数据时,不会自动创建索引, 需要预先创建好索引

ES集群JVM调优积累

在最开始, 我们使用的ES实例,没有涉及到很大的数据写入和检索(每天几百万数据). 当时我们配置ES的JVM(Xms=Xmx=8G)的垃圾回收器主要是CMS,具体配置如下:

# reduce the per-thread stack size
JAVA_OPTS="$JAVA_OPTS -Xss256k"

JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"

JAVA_OPTS="$JAVA_OPTS -XX:CMSInitiatingOccupancyFraction=75"
JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSInitiatingOccupancyOnly"

这个在小数据量,小内存时运行良好, 基本很少会出现Full gc.

后来我们的数据量为了一天1亿多, 为了加快检索, 我们将Xms,Xmx同时调整为32G. 并按天进行索引,后来发现随着索引数增加,写入数据量增加, Full GC已经影响到了我们的写入和检索(这个时候我们的ES集群是三个实例).我们决定将G1作为垃圾回收期,但是官方并不推荐使用G1, 我们还是想尝试一下换成G1, 并借此机会把JDK从1.7升级到1.8(升级很平滑), G1的具体配置如下:

JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC "
#init_globals()末尾打印日志
JAVA_OPTS="$JAVA_OPTS -XX:+PrintFlagsFinal "
#打印gc引用
JAVA_OPTS="$JAVA_OPTS -XX:+PrintReferenceGC "
#输出虚拟机中GC的详细情况.
JAVA_OPTS="$JAVA_OPTS -verbose:gc "
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails "
#Enables printing of time stamps at every GC. By default, this option is disabled.
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCTimeStamps "
#Enables printing of information about adaptive generation sizing. By default, this option is disabled.
JAVA_OPTS="$JAVA_OPTS -XX:+PrintAdaptiveSizePolicy "
# unlocks diagnostic JVM options
JAVA_OPTS="$JAVA_OPTS -XX:+UnlockDiagnosticVMOptions "
#to measure where the time is spent
JAVA_OPTS="$JAVA_OPTS -XX:+G1SummarizeConcMark "
#设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。
#JAVA_OPTS="$JAVA_OPTS -XX:InitiatingHeapOccupancyPercent=45 "

TODO 之后会在这补充替换为G1后,ES集群的表现

ES集群健康说明

在Elasticsearch集群中可以监控统计很多信息,其中最重要的就是:集群健康(cluster health)。它的 status 有 greenyellowred 三种;

可以通过如下命令获取:

GET http://127.0.0.1:9200/_cluster/health

在一个没有索引的空集群中,它将返回如下信息:

{
   "cluster_name":          "elasticsearch",
   "status":                "green", <1>
   "timed_out":             false,
   "number_of_nodes":       1,
   "number_of_data_nodes":  1,
   "active_primary_shards": 0,
   "active_shards":         0,
   "relocating_shards":     0,
   "initializing_shards":   0,
   "unassigned_shards":     0
}

status 是我们最应该关注的字段。
status 可以告诉我们当前集群是否处于一个可用的状态。三种颜色分别代表:

状态说明
green : 所有主分片和从分片都可用
yellow: 所有主分片可用,但存在不可用的从分片
red: 存在不可用的主要分片

ES配置文件详解

cluster.name: elasticsearch
#配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。

node.name: "Franz Kafka"
#节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。

node.master: true
#指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。

node.data: true
#指定该节点是否存储索引数据,默认为true。

index.number_of_shards: 5
#设置默认索引分片个数,默认为5片。

index.number_of_replicas: 1
#设置默认索引副本个数,默认为1个副本。

path.conf: /path/to/conf
#设置配置文件的存储路径,默认是es根目录下的config文件夹。

path.data: /path/to/data
#设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例:
#path.data: /path/to/data1,/path/to/data2

path.work: /path/to/work
#设置临时文件的存储路径,默认是es根目录下的work文件夹。

path.logs: /path/to/logs
#设置日志文件的存储路径,默认是es根目录下的logs文件夹

path.plugins: /path/to/plugins
#设置插件的存放路径,默认是es根目录下的plugins文件夹

bootstrap.mlockall: true
#设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把#ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要#允许elasticsearch的进程可以锁住内存,linux下可以通过`ulimit -l unlimited`命令。

network.bind_host: 192.168.0.1
#设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。


network.publish_host: 192.168.0.1
#设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。

network.host: 192.168.0.1
#这个参数是用来同时设置bind_host和publish_host上面两个参数。

transport.tcp.port: 9300
#设置节点间交互的tcp端口,默认是9300。

transport.tcp.compress: true
#设置是否压缩tcp传输时的数据,默认为false,不压缩。

http.port: 9200
#设置对外服务的http端口,默认为9200。

http.max_content_length: 100mb
#设置内容的最大容量,默认100mb

http.enabled: false
#是否使用http协议对外提供服务,默认为true,开启。

gateway.type: local
#gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的#HDFS,和amazon的s3服务器,其它文件系统的设置方法下次再详细说。

gateway.recover_after_nodes: 1
#设置集群中N个节点启动时进行数据恢复,默认为1。

gateway.recover_after_time: 5m
#设置初始化数据恢复进程的超时时间,默认是5分钟。

gateway.expected_nodes: 2
#设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。

cluster.routing.allocation.node_initial_primaries_recoveries: 4
#初始化数据恢复时,并发恢复线程的个数,默认为4。

cluster.routing.allocation.node_concurrent_recoveries: 2
#添加删除节点或负载均衡时并发恢复线程的个数,默认为4。

indices.recovery.max_size_per_sec: 0
#设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。

indices.recovery.concurrent_streams: 5
#设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。

discovery.zen.minimum_master_nodes: 1
#设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)

discovery.zen.ping.timeout: 3s
#设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。

discovery.zen.ping.multicast.enabled: false
#设置是否打开多播发现节点,默认是true。

discovery.zen.ping.unicast.hosts: ["host1", "host2:port", "host3[portX-portY]"]
#设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。

ES使用中碰到的问题

BoolFilterBuilder bqb = FilterBuilders.boolFilter();
if(vo.getQueryStr() != null && !vo.getQueryStr().trim().equals("")){    
bqb.must(FilterBuilders.queryFilter(QueryBuilders.queryStringQuery( 
ESReservedCharsUtil.removeReservedChars(vo.getQueryStr())).defaultField("body").defaultOperator(QueryStringQueryBuilder.Operator.AND)).cache(true));
// 该种方式不能检索句子
// for(String _s : vo.getQueryStr().split("\\s+")) {
//     bqb.must(FilterBuilders.termFilter("body", _s));
// }
}

其他

上一篇 下一篇

猜你喜欢

热点阅读