那年那日那朵花

".......(o´ω`o)......"

elasticsearch使用心(tian)得(keng)

2016-11-25 13:51 elk

elasticsearch也使用了一段时间了,总结一下这段时间的一些心得。


推荐安装使用marvel监控elasticsearch集群信息以及delete-by-query插件

mavel监控很好用,比自己敲curl调API好用多了,又快又直观。而delete-by-query插件可以帮助删除一些根据查询得出的结果数据。

#安装marvel
/usr/share/elasticsearch/bin/plugin install file:///path/to/file/license-2.3.5.zip
/usr/share/elasticsearch/bin/plugin install file:///path/to/file/marvel-agent-2.3.5.zip
/opt/kibana/bin/kibana plugin --install marvel --url file:///path/to/file/marvel-2.3.5.tar.gz

#安装delete-by-query
/usr/share/elasticsearch/bin/plugin install file:///path/to/file/delete-by-query-2.3.5.zip

导入license,license可以免费申请,申请地址https://register.elastic.co/marvel_register

#导入license文件license.json
curl -XPUT -u admin 'http://localhost:9200/_license' -d @license.json
#查询license信息
curl -XGET -u admin 'http://localhost:9200/_license'

将elasticsearch广播转为单播

elasticsearch默认是广播的,只要同一网段内elasticsearch设置的集群名一样就会自动加入到elasticsearch集群中,这样的设计很方便,但是实际上我更加希望是自己指定服务器。。。。。

通过调整elasticsearch.yml中的discovery.zen.ping.unicast.hosts: ["127.0.0.1", "112.116.44.174"]配置项即可


命令行方式查看elasticsearch状态

#查看节点状态
curl -XGET 'http://localhost:9200/_nodes?pretty'
#查看文件描述符
curl -XGET 'http://localhost:9200/_nodes/stats/process?pretty'
#查看健康值
curl -XGET 'http://localhost:9200/_cat/health?v'
#查看节点信息
curl -XGET 'http://localhost:9200/_cat/nodes?v'
#查看索引信息
curl -XGET 'http://localhost:9200/_cat/indices?v'

elasitcsearch堆内存不要超过32G

根据官方文档的说法,elasticsearch设置的ES_HEAP_SIZE通常为服务器内存的一半,另外一半留给lucene。而且不能超过32G

一般的设置31gb即可。如果想要极限一下,那么就如下这样
如果是 Java 1.7 设置-Xmx32600m。如果是 Java 1.8 设置-Xmx32766m


参数调整

elasticsearch.yml配置文件里面,调整http.max_content_length: 500mb 这个默认就100m 建议调大 之前有过报错

另外是调整队列大小

 #如果队列满了logstash就会报错LogStash::Inputs::Beats::InsertingToQueueTakeTooLong,解决办法
curl -XPUT http://localhost:9200/_cluster/settings -d '{
    "transient" : {
        "threadpool.index.queue_size" : 3000
    }
}'

通过RESTfulAPI调的话,分为两种persistent 和transient,persistent 是在重启之后生效,而transient是立即生效但重启集群后失效。所以如果要让配置持久生效的话,可以在elasticsearch.yml配置文件里面配置。添加threadpool.index.queue_size: 1200即可。


提高起新节点时同步数据的速度

如果elasticsearch加入了新的节点,那么分片就会重新分配。这个过程需要一些时间,如果感觉分配的速度太慢可以调整如下参数(当然最根本的是看服务器的性能)。

#起新节点后同步时的线程数
curl -XPUT http://localhost:9200/_cluster/settings -d '{
    "transient" : {
        "cluster.routing.allocation.node_concurrent_recoveries" : 8
    }
}'

集群节点重启

elasticsearch节点一旦重启就会脱离elasticsearch集群,那么elasticsearch就会重新分配分片,这个过程会消耗部分系统资源并且需要一些时间,然后当我们的节点启动好重新加入集群后,又会发生同样的事情。。。。。而我们重启elasticsearch是一个已知的动作。并不希望每当因为重启,一个节点脱离集群后整个集群发生重新分片分配,套用官方网站上的说法如下:

https://www.elastic.co/guide/en/elasticsearch/guide/current/_rolling_restarts.html
** By nature, Elasticsearch wants your data to be fully replicated and evenly balanced. If you shut down a single node for maintenance, the cluster will immediately recognize the loss of a node and begin rebalancing. This can be irritating if you know the node maintenance is short term, since the rebalancing of very large shards can take some time (think of trying to replicate 1TB—even on fast networks this is nontrivial). **

所以重启可以这样做,当然如果是单机运行就不需要这么搞了。(说白了如果手动重启就会发生脱离集群重新分配一次,加入集群也重新分配一次。下面的方法就可以只在加入集群的时候重新分配次,反正重启节点耗时是肯定的= =)

#重启

curl -XPUT http://localhost:9200/_cluster/settings -d'
{
    "transient" : {
        "cluster.routing.allocation.enable" : "none"
    }
}'

#shutdown
#该配置
#startup

curl -XPUT http://localhost:9200/_cluster/settings -d'
{
    "transient" : {
        "cluster.routing.allocation.enable" : "all"
    }
}'

段优化

对与一些老的索引可以做合并segement优化,段优化的时候系统开销是蛮大的,而且如果索引比较大的话耗时会很长,但是这样可以减少segement的数量优化查询效率,还是有必要做一下的,所以可以设置定时在半夜里没啥量的时候做,而且段优化不能用在正在进行索引(indexing)的索引上。例如我这边索引是以日为单位建立的,那么就每天在半夜对前一天的索引做段优化。

#优化段,optimizeAPI 同forcemergeAPI
curl -XPOST "http://localhost:9200/indexname/_optimize?max_num_segments=1"

单个filebeat收集日志量有限

由于之前我收集日志是到一台专门的日志服务器上收集,随着业务量的增加以及添加到elk的应用增多,我发现一个filebeat实例最多收集的效率应该在2000条每秒左右,当时每到晚上量上去的时候,日志收集就会有延迟,然后刨去脚本程序导入elasticsearch的量,我就发现索引率(也就是吞吐量)就在2000/s。一开始我没有注意到这个现象,对logstash和elasticsearch调了半天,毫无一点卵用= =。后来我起多个filebeat实例,负责各个不同的应用,然后索引率就上去了。


不要在logstash的filter plugin中配置multiline

如果在filter plugin中配multiline的话,logstash的workers会强制设置为1(即使你设置为其他值也没用)。这样会导致logstash处理效率下降。

解决办法就是将多行匹配配置到input plugin中。可以这样

input {
    beats {
        port => "5044"
        codec => multiline {
            patterns_dir => ["/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.5/patterns"]
            pattern => "(^%{SYSLOGTIMESTAMP} %{WORD}\s+at .+)|(^\s+at .+)|(^\*[\u4e00-\u9fa5]+.+)|(^[\u4e00-\u9fa5]+.+)"
            what => "previous"
        }
    }
}

Cloudhu 个人随笔|built by django|

沪ICP备16019452号-1