内容简介:ELK Tips 主要介绍一些 ELK 使用过程中的小技巧,内容主要来源为 Elastic 中文社区。当 terms 的个数较少的时候,TermsQuery 等效为 ConstantScoreQuery 内部包含多个 TermQuery:当 terms 较多的时候,它将使用匹配的文档组合成一个位集,并在该位集上进行评分;此时查询效率比普通的 Bool 合并要更加高效。
ELK Tips 主要介绍一些 ELK 使用过程中的小技巧,内容主要来源为 Elastic 中文社区。
一、Logstash
1、Logstash 性能调优主要参数
-
pipeline.workers
:设置启动多少个线程执行 fliter 和 output;当 input 的内容出现堆积而 CPU 使用率还比较充足时,可以考虑增加该参数的大小; -
pipeline.batch.size
:设置单个工作线程在执行过滤器和输出之前收集的最大事件数,较大的批量大小通常更高效,但会增加内存开销。输出插件会将每个批处理作为一个输出单元。;例如,ES 输出会为收到的每个批次发出批量请求;调整pipeline.batch.size
可调整发送到 ES 的批量请求(Bulk)的大小; -
pipeline.batch.delay
:设置 Logstash 管道的延迟时间, 管道批处理延迟是 Logstash 在当前管道工作线程中接收事件后等待新消息的最长时间(以毫秒为单位);简单来说,当pipeline.batch.size
不满足时,会等待pipeline.batch.delay
设置的时间,超时后便开始执行 filter 和 output 操作。
二、Elasticsearch
1、TermsQuery 与多个 TermQuery 的区别
当 terms 的个数较少的时候,TermsQuery 等效为 ConstantScoreQuery 内部包含多个 TermQuery:
Query q1 = new TermInSetQuery(new Term("field", "foo"), new Term("field", "bar")); // 等效为下面的语句 BooleanQuery bq = new BooleanQuery(); bq.add(new TermQuery(new Term("field", "foo")), Occur.SHOULD); bq.add(new TermQuery(new Term("field", "bar")), Occur.SHOULD); Query q2 = new ConstantScoreQuery(bq); 复制代码
当 terms 较多的时候,它将使用匹配的文档组合成一个位集,并在该位集上进行评分;此时查询效率比普通的 Bool 合并要更加高效。
当 terms 的个数较多时,TermsQuery 比多个 TermQuery 组合的查询效率更高。
2、ES 借助 nginx 配置域名
upstream /data/ { server 192.168.187.xxx:9200; keepalive 300 ; } server { listen 80; server_name testelk.xx.com; keepalive_timeout 120s 120s; location /data { proxy_pass http://data/; proxy_http_version 1.1; proxy_set_header Connection "Keep-Alive"; proxy_set_header Proxy-Connection "Keep-Alive"; proxy_set_header X-Real-IP $remote_addr; proxy_pass_header remote_user proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; proxy_set_header X-Nginx-Proxy true; } } 复制代码
3、ES Reindex 时如何不停止写入服务
方案一:kennywu76
ES 的 reindex 在索引有实时的 update/delete 的情况下,即使借助 alias,也没有办法实现真正的 zero down time。
增加新文档比较好办,通过 alias 切换写入到新索引,同时 reindex 做旧->新索引的数据传输即可;但是 update/delete 操作针对的文档如果还未从旧索引传输过来,直接对新索引操作会导致两个索引数据不一致。
我能够想到的(一个未经实际验证)的方案,前提是数据库里的文档有一个类似 last_update_time
字段记录文档最后更新的时间,用作写入 ES 文档的版本号,然后数据写入新索引的时候,url 里带上下面这样的参数: version_type=external_gt&version=xxxxxx
。
其中 version_type=external_gt
表示写入文档的版本号大于已有的文档版本号,或者文档不存在,写入才会成功,否则会抛版本冲突的异常。 另外 delete 操作都要转换成 index 操作,index 的内容可以是一个空文档 。
这样实时数据写入新索引和 reindex 可以同时进行,实时写入的数据应该具有更高的版本,总是能够成功,reindex 如果遇到版本冲突,说明该文档被实时部分更新过了,已经过时,可以直接放弃跳过。
该方案的缺陷:
- 要求数据源里的数据具有版本信息,可能因为各种局限,不太容易更改;
- delete 操作必须转化为写入一个空文档,delete 实际上是一个标记文档,并且本身也有版本信息。但是如果后端发生了 segment merge,delete 可能会被合并以后物理清除。这样 delete 和对应的版本信息丢失,之后 reindex 如果写入了旧版本的文档,仍然会有一致性问题;但是空文档会增加索引文件的大小,有额外的消耗,一个可能的缓解办法是在 reindex 全部做完以后,再做一次空文档的删除。
改进方案:the_best
重建索引步骤如下:
- 保证 delete 操作都要转换成 index 操作,index 的内容可以是一个空文档;
- 对老索引
old_index
(业务上的别名还是挂在老索引上)进行重索引操作(version_type=external
);
curl -X POST 'http://<hostname>:9200/_reindex' { "conflicts": "proceed", "source": { "index": "old_index", "size": 1000 }, "dest": { "index": "new_index", "version_type": "external" } } 复制代码
- 将别名切到 newIndex;
- 将重索引时间段内
old_index
产生的热数据,再捞一次到new_index
中(conflicts=proceed&version_type=external
);
curl -X POST /_reindex { "conflicts": "proceed", "source": { "index": "old_index" "query": { "constant_score" : { "filter" : { "range" : { "data_update_time" : { "gte" : <reindex开始时刻前的毫秒时间戳> } } } } } }, "dest": { "index": "new_index", "version_type": "external" } } 复制代码
- 手动做一次空文档的删除。
这种方式取决于重索引期间产生的数据量大小(会影响步骤4的用时),不过我们可以视具体业务情况灵活操作。比如说数据量比较大重索引我们用了10个小时(这10个小时内新产生了200多万的数据),在切别名前,我们可以按步骤(4)的调用方式,把近10个小时的数据再捞一遍到新索引中,如此迭代个几次,直到别名切完后,我们能保证最后一次的步骤(4)可以在较短时间内完成。
4、ES 节点通讯配置
http.port: 9200 http.bind_host: 127.0.0.1 transport.tcp.port: 9300 transport.bind_host: 127.0.0.1 复制代码
5、把 Lucene 的原生 query 传给 ES
SearchRequest searchRequest = new SearchRequest(indexName); searchRequest.types(typeName); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.from(0); sourceBuilder.size(10); sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //q为Lucene检索表达式, 直接输入关键词匹配_all或者*字段, 字段匹配user:kimchy, //多字段匹配user:kimchy AND message:Elasticsearch QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(q); sourceBuilder.query(queryStringQueryBuilder); searchRequest.source(sourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest); SearchHits searchHits = searchResponse.getHits(); 复制代码
6、ES 文档字段个数限制
ES 文档默认不允许文档字段超过 1000,超过 1000 会报如下错误:
failed to put mappings on indices [[[nfvoemspm/srjL3cMMRUqa7DgOrYqX-A]]], type [log] java.lang.IllegalArgumentException: Limit of total fields [1000] in index [xxx] has been exceeded 复制代码
可以通过修改索引配置来修改字段个数限制,不过还是推荐从业务上进行优化:
修改settings { "index.mapping.total_fields.limit": 2000 } 复制代码
7、将 DSL 字符串转换为 QueryBuilder
## wrapper 案例 GET /_search { "query" : { "wrapper": { "query" : "eyJ0ZXJtIiA6IHsgInVzZXIiIDogIktpbWNoeSIgfX0=" } } } ## RestClient QueryBuilders.wrapperQuery("{\"term\": {\"field\":\"value\"}}") 复制代码
8、ES 集群重启后 Slice Scroll 速度变慢
重启机器之后,pagecache 都没有了,所有数据都要重新从磁盘加载。
9、ES 开启索引新建删除日志
PUT _cluster/settings { "persistent": { "logger.cluster.service": "DEBUG" } } 复制代码
10、慢日志全局级别设定
- 对已经存在的索引可以通过 PUT _settings 做存量设置
- 对之后新增的索引,可以使用类似于下面的template
PUT _template/global-slowlog_template { "order": -1, "version": 0, "template": "*", "settings": { "index.indexing.slowlog.threshold.index.debug" : "10ms", "index.indexing.slowlog.threshold.index.info" : "50ms", "index.indexing.slowlog.threshold.index.warn" : "100ms", "index.search.slowlog.threshold.fetch.debug" : "100ms", "index.search.slowlog.threshold.fetch.info" : "200ms", "index.search.slowlog.threshold.fetch.warn" : "500ms", "index.search.slowlog.threshold.query.debug" : "100ms", "index.search.slowlog.threshold.query.info" : "200ms", "index.search.slowlog.threshold.query.warn" : "1s" } } 复制代码
11、TCP 设置多个端口的用途
transport.tcp.port
这个参数不写,默认为 9300-9399
,开放那么多 端口有用么?
- 如果设置一个端口,假设这个端口占用了程序就无法正常启动;
- 如果设置多个端口,一个端口占用会寻找下一个端口,直至找到可用端口。
12、ES 临时重启,设置分片延迟分配策略
PUT _all/_settings { "settings": { "index.unassigned.node_left.delayed_timeout": "5m" } } 复制代码
三、Kibana
1、kibana 图表自定义标注
可以用 TSVB,支持标注。
Kibana TSVB 注解的使用: elasticsearch.cn/article/701
2、Kibana discover 导出 csv 文件
请参考文章: 如何快速把 Kibana Discover 页的 Document Table 导出成 CSV
3、修改 kibana 的默认主页
四、社区文章精选
Any Code,Code Any!
扫码关注『AnyCode』,编程路上,一起前行。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM国际大学生程序设计竞赛题解
赵端阳//袁鹤 / 电子工业 / 2010-7 / 39.00元
随着各大专院校参加ACM/ICPC热情的高涨,迫切需要有关介绍ACM国际大学生程序设计竞赛题解的书籍。《ACM国际大学生程序设计竞赛题解(2)》根据浙江大学在线题库的部分题目,经过分类、筛选、汇编,并进行了解答(个别特别简单或者特别复杂的题目未选择),比较详细地分析和深入浅出地讲解了解题的方法和用到的算法。题目的类型包括基础编程、模拟、字符串处理、搜索、动态规划、回溯、图论、几何和数学题。 ......一起来看看 《ACM国际大学生程序设计竞赛题解》 这本书的介绍吧!