ELK 使用小技巧(第 5 期)

ELK Tips 主要介紹一些 ELK 使用過程當中的小技巧,內容主要來源爲 Elastic 中文社區。java

1、Logstash

一、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 操做。

2、Elasticsearch

一、TermsQuery 與多個 TermQuery 的區別

當 terms 的個數較少的時候,TermsQuery 等效爲 ConstantScoreQuery 內部包含多個 TermQuery:node

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 合併要更加高效。nginx

當 terms 的個數較多時,TermsQuery 比多個 TermQuery 組合的查詢效率更高。數據庫

二、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;
    }
}
複製代碼

三、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=xxxxxxbash

其中 version_type=external_gt 表示寫入文檔的版本號大於已有的文檔版本號,或者文檔不存在,寫入纔會成功,不然會拋版本衝突的異常。另外 delete 操做都要轉換成 index 操做,index 的內容能夠是一個空文檔app

這樣實時數據寫入新索引和 reindex 能夠同時進行,實時寫入的數據應該具備更高的版本,老是可以成功,reindex 若是遇到版本衝突,說明該文檔被實時部分更新過了,已通過時,能夠直接放棄跳過。curl

該方案的缺陷:elasticsearch

  • 要求數據源裏的數據具備版本信息,可能由於各類侷限,不太容易更改;
  • delete 操做必須轉化爲寫入一個空文檔,delete 其實是一個標記文檔,而且自己也有版本信息。可是若是後端發生了 segment merge,delete 可能會被合併之後物理清除。這樣 delete 和對應的版本信息丟失,以後 reindex 若是寫入了舊版本的文檔,仍然會有一致性問題;可是空文檔會增長索引文件的大小,有額外的消耗,一個可能的緩解辦法是在 reindex 所有作完之後,再作一次空文檔的刪除。

改進方案:the_best

重建索引步驟以下:

  1. 保證 delete 操做都要轉換成 index 操做,index 的內容能夠是一個空文檔;
  2. 對老索引 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"
    }
}
複製代碼
  1. 將別名切到 newIndex;
  2. 將重索引時間段內 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"
    }
}
複製代碼
  1. 手動作一次空文檔的刪除。

這種方式取決於重索引期間產生的數據量大小(會影響步驟4的用時),不過咱們能夠視具體業務狀況靈活操做。好比說數據量比較大重索引咱們用了10個小時(這10個小時內新產生了200多萬的數據),在切別名前,咱們能夠按步驟(4)的調用方式,把近10個小時的數據再撈一遍到新索引中,如此迭代個幾回,直到別名切完後,咱們能保證最後一次的步驟(4)能夠在較短期內完成。

四、ES 節點通信配置

http.port: 9200
http.bind_host: 127.0.0.1
transport.tcp.port: 9300
transport.bind_host: 127.0.0.1
複製代碼

五、把 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();
複製代碼

六、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
}
複製代碼

七、將 DSL 字符串轉換爲 QueryBuilder

## wrapper 案例
GET /_search
{
    "query" : {
        "wrapper": {
            "query" : "eyJ0ZXJtIiA6IHsgInVzZXIiIDogIktpbWNoeSIgfX0=" 
        }
    }
}

## RestClient
QueryBuilders.wrapperQuery("{\"term\": {\"field\":\"value\"}}")
複製代碼

八、ES 集羣重啓後 Slice Scroll 速度變慢

重啓機器以後,pagecache 都沒有了,全部數據都要從新從磁盤加載。

九、ES 開啓索引新建刪除日誌

PUT _cluster/settings
{
  "persistent": {
    "logger.cluster.service": "DEBUG"
  }
}
複製代碼

十、慢日誌全局級別設定

  1. 對已經存在的索引能夠經過 PUT _settings 作存量設置
  2. 對以後新增的索引,可使用相似於下面的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"
    }
}
複製代碼

十一、TCP 設置多個端口的用途

transport.tcp.port 這個參數不寫,默認爲 9300-9399,開放那麼多 端口有用麼?

  • 若是設置一個端口,假設這個端口占用了程序就沒法正常啓動;
  • 若是設置多個端口,一個端口占用會尋找下一個端口,直至找到可用端口。

十二、ES 臨時重啓,設置分片延遲分配策略

PUT _all/_settings
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "5m"
  }
}
複製代碼

3、Kibana

一、kibana 圖表自定義標註

能夠用 TSVB,支持標註。

Kibana TSVB 註解的使用:elasticsearch.cn/article/701

二、Kibana discover 導出 csv 文件

請參考文章:如何快速把 Kibana Discover 頁的 Document Table 導出成 CSV

三、修改 kibana 的默認主頁

elasticsearch.cn/article/633…

4、社區文章精選


Any Code,Code Any!

掃碼關注『AnyCode』,編程路上,一塊兒前行。

相關文章
相關標籤/搜索