Elasticsearch 100問(1-30)

第1問

  • 問:重啟集群后,出現(xiàn)了unassigned shards, 是什么原因:
  • 答:集群的shard數(shù)量較多,在節(jié)點重啟后,由于recovery并發(fā)限制,shard分配次數(shù)超限,集群就不會在分配shard了,從而出現(xiàn)unassigned shards; 可以使用api對shard進行重新分配:POST _cluster/reroute?retry_failed=true

第2問

  • 問:使用ES過程中,出現(xiàn)bulk reject, 查看日志看到bulk queue滿了,請問這是什么原因?
  • 答:可以通過GET _cat/thread_pool/bulk?s=queue:desc&v查看正在拒絕或者歷史拒絕的個數(shù);一般默認bulk queue大小是1024, 造成bulk reject的大多數(shù)原因大概有兩種:
    (1) shard容量多大,建議每個shard容量控制在20G-50G,shard數(shù)量不能過多,也不能過少
    (2) shard分布不均,可通過調(diào)整index.routing.allocation.total_shards_per_node參數(shù)來解決

第3問

  • 問:磁盤寫滿后,清理了一部分數(shù)據(jù),此時無法向ES中寫入數(shù)據(jù),請問是什么原因:
  • 答:磁盤寫滿后,ES會把集群的block級別改為read_only_allow_delete, 此時需要修改該參數(shù),通過調(diào)用PUT _cluster/settings {cluster. blocks.read_only_allow_delete:"false"}解決,如果出現(xiàn)index level級別的block賊需要修改對應(yīng)索引的配置

第4問

  • 問:使用logstash收集日志時,如何把logstash默認添加的@timestamp字段替換為日志中的時間?
  • 答:
filter {
    grok {
        match => ["message", "%{TIMESTAMP_ISO8601:logdate}"
    }
    date {
        match => ["logdate", "yyyy-MM-dd HH:mm:ss,SSS"]
        target => "@timestamp"
    }
}

第5問

  • 問:使用logstash收集日志時,如何修改logstash默認添加的@timestamp字段的時區(qū)為東八區(qū)?
  • 答:
filter {
  date {
    match => ["message","UNIX_MS"]
    target => "@timestamp"   
  }
  ruby { 
   code=>"event.set('timestamp',event.get('@timestamp').time.localtime + 8*60*60)" 
      }
  ruby {
   code => "event.set('@timestamp',event.get('timestamp'))"
  }
  mutate {
   remove_field => ["timestamp"]
  }
}

第6問

  • 問:調(diào)用_forcemerge API發(fā)現(xiàn)并沒有減少segment的數(shù)量,請問是什么原因?
  • 答:_forcemerge API執(zhí)行merge是有條件的,當索引數(shù)據(jù)量比較大時,經(jīng)過了一定時間的merge之后,每個segement都會比較大,如果此時indexing的速率較低,merge操作期望可以merge的segment數(shù)量比較大,而實際上候選的segment數(shù)量沒有那么大時,就不會觸發(fā)merge操作

第7問

  • 問:聚合查詢越來越慢,請問是什么原因?
  • 答:需要確認進行聚合的字段唯一值是否比較多,唯一值較多的情況下聚合查詢構(gòu)建Global Ordinals會比較慢,如果索引沒有持續(xù)寫入,構(gòu)建好的Global Ordinals就會進行緩存,之后的查詢就可以使用緩存中的Global Ordinals;但是如果索引在持續(xù)寫入,每當?shù)讓拥膕egment發(fā)生變化時(有新數(shù)據(jù)寫入導致產(chǎn)生新的Segment、Segment Merge),就需要重新構(gòu)建Global Ordinals,隨著數(shù)據(jù)量的增大聚合字段的唯一值越來越多,構(gòu)建Global Ordinals越來越慢,所以對持續(xù)寫入的索引,聚合查詢會越來越慢。從業(yè)務(wù)角度進行優(yōu)化的方案可以參考:https://cloud.tencent.com/developer/article/1421924

第8問

  • 問:在kibana上創(chuàng)建index pattern卡主了,一直轉(zhuǎn)圈圈,無法創(chuàng)建,是什么原因?
  • 答:首先確認下.kibana的索引是否被設(shè)置為只讀了,當集群出現(xiàn)過磁盤寫滿時,ES會自動把索引設(shè)置block級別設(shè)置為readonly_allow_delete, 如果被設(shè)置為只讀,需要修改block級別PUT .kibana/_settings {"index.blocks.read_only_allow_delete":false}

第9問

  • 問:通過logstash向ES寫入日志報錯:"type"=>"illegal_state_exception", "reason"=>"Can't get text on a START_OBJECT, 請問這是什么原因?
  • 答:原因是es對字段解析錯誤,類型是字符串(keyword或者text)的字段接收到的值為對象(如json對象),出現(xiàn)這種情況,可以在logstash 配置文件中使用json_encode filter plugin對原來是對象的字段轉(zhuǎn)換為字符串。

第10問

  • 問:查詢dsl中使用了min_score參數(shù)用來限定返回文檔的得分,為什么多次執(zhí)行hit的文檔數(shù)量不一致?
  • 答:主分片和副本分片的差異導致的,底層segment可能不一致,特別是在有文檔被刪除的情況下主分片和副本分片的segment中標記刪除的文檔的數(shù)量可能會不一致(比如主分片進行了merge, 副本分片沒有進行merge),導致最終主分片和副本分片上文檔的得分不同,影響了最終的查詢結(jié)果;可以在查詢時指定preference=_primary指定只查詢主分片解決,或者自定義preference解決

第11問

  • 問:completion suggester自動補全功能,在添加seggest inputs時指定了多個詞,為什么查詢時options只返回一項?

創(chuàng)建索引并添加doc:

curl -XPUT "http://localhost:10001/music" -H 'Content-Type: application/json' -d'
{
    "mappings": {
      "_doc":{
        "properties" : {
            "suggest" : {
                "type" : "completion"
            },
            "title" : {
                "type": "keyword"
            }
        }
    }
}}'

curl -XPUT "http://localhost:10001/music/_doc/7?refresh" -H 'Content-Type: application/json' -d'
{
    "suggest" : {
        "input": [ "bat", "bar"]
    }
}'

查詢:

curl -XPOST "http://localhost:10001/music/_search?pretty" -H 'Content-Type: application/json' -d'
{
    "suggest": {
        "song-suggest" : {
            "prefix" : "ba", 
            "completion" : { 
                "field" : "suggest" 
            }
        }
    }
}'

結(jié)果:

...
"options": [
          {
            "text": "bar",
            "_index": "music",
            "_type": "_doc",
            "_id": "7",
            "_score": 1,
            "_source": {
              "suggest": {
                "input": [
                  "bat",
                  "bar"
                ]
              }
            }
          }
        ]
...
  • 答: completion suggester返回的options是文檔級別的,查詢命中后就會提前終止,所以只能返回第一個匹配到的值;解決方法是bat, bar兩個詞分別放在兩個doc中

第12問

  • 問:2核4G 3節(jié)點的集群,在保證集群性能穩(wěn)定的情況下,最多可以支持多少shard?
  • 答:每個節(jié)點上可以存儲的分片數(shù)量與可用的堆內(nèi)存大小成正比關(guān)系,分片數(shù)量越多,分片的元數(shù)據(jù)占用的內(nèi)存越多,一般情況下,1GB的堆內(nèi)存對應(yīng)分片數(shù)量不超過20

第13問

  • 問:請問ES報這個錯誤是什么原因:"caused_by"=>{"type"=>"max_bytes_length_exceeded_exception", "reason"=>"max_bytes_length_exceeded_exception: bytes can be at most 32766 in length; got 33023"}?
  • 答:原因是索引中有字段為keyword類型,但是寫入時的該字段的數(shù)據(jù)長度超過了keyword類型的最大長度32766個字節(jié),可以把該字段的類型設(shè)置為text解決。

第14問

  • 問: 使用filebeat收集日志寫入ES中,報錯:"Bulk item insert failed (i=0, status=500): {"type":"string_index_out_of_bounds_exception","reason":"String index out of range: 0"}",請問是什么原因?
  • 答:當filebeat的output.elasticsearch.index配置項有取自上游event中的某個字段,而某個event中該字段不存在時,想ES寫入數(shù)據(jù)會報錯。索引的名稱如果要從event中的某個字段獲取,需要確保該字段一定會存在。

第15問

  • 問:ES的_refresh和_flush操作的區(qū)別是什么?
  • 答:refresh調(diào)用了lucene DirectoryReader的 openIfChanged()方法,相當于重新打開了indexReader, 使得寫入的數(shù)據(jù)都可以被搜索到;flush操作調(diào)用了luecene IndexWriter的commit()方法,把仍在在文件系統(tǒng)緩存中的segment寫入到磁盤中,實現(xiàn)了數(shù)據(jù)的真正持久化,flush同時還會觸發(fā)refresh操作。

第16問

  • 問:在ES的script query中,使用doc['my_field'].value和 params['_source']['my_field'],兩種方式有什么不同?
  • 答:使用doc[]的方式會把字段的所有terms都加載進內(nèi)存并且會被緩存,因此比較消耗內(nèi)存,同時doc[]的方式只支持單值字段;使用_source的方式terms不會被緩存,相比doc[]的方式較慢。

第17問

  • 問:ES的刪除操作不是真正的刪除,那通過什么方式可以獲取到準確的文檔數(shù)量?
  • 答:通過_cat/count API獲取集群中所有文檔數(shù)量,不包含已刪除的文檔;通過{index}/_stats API獲取索引中的文檔數(shù)量,結(jié)果中docs.count值為除了標記刪除文檔之外的總的文檔數(shù),docs.deleted為標記刪除的文檔數(shù)。

第18問

  • 問:ES的_search API,當不指定索引時是會向集群中所有的索引發(fā)起查詢請求嗎?
  • 答:是默認行為,最好通過指定索引名稱或者對多個索引設(shè)置別名后進行查詢,可以減少不必要的開銷;5.6版本以后增加了分片預(yù)過濾功能,當要查詢的分片數(shù)量超過128并且查詢可能會被重寫為MatchNoneQuery時,會進行過濾,過濾掉不需要的shard,_search API的返回結(jié)果中的_shards.skipped表示了過濾掉了多少shard。

第19問

  • 問:如果使用scroll批量獲取查詢結(jié)果,ES執(zhí)行該查詢時還會使用node query cache或者shard request cache嗎?
  • scroll請求不會用到cache,因為使用cache在查詢請求執(zhí)行過程中會修改search context,會破壞掉scroll的context。

第20問

  • 問:如何實現(xiàn)字符串的前后通配符匹配,比如輸入bc,想查詢出abc, abcd, bcd, 但是不能查詢出abdc?
  • 答:使用query_string查詢:
{
    "query":{
        "query_string":{
            "query":"field:*ab*"
        }
    }
}

第21問

  • 問:使用query_string查詢指定的整型字段,查詢的值為正數(shù)時正常,值為負數(shù)時拋異常,如“status:-1”時會報錯,怎么解決?
  • 答:需要把負號轉(zhuǎn)義("status:\-1")或者對負數(shù)加引號, 否則會認為負號是一個操作符而解析失敗。

第22問

  • 問:在kibana中要對long型的字段進行聚合,但是提示不支持,請問這是什么原因?
  • 答:如果索引是按天創(chuàng)建的,并且一個index pattern下包含多個索引,檢查下索引的mapping,是否之前的索引中字段類型是否是字符串類型,如果不同索引中該字段的類型不一致,則不能對該字段進行聚合。https://github.com/elastic/kibana/issues/3451

第23問

  • 問:通過bulk api向es寫數(shù)據(jù)時,報錯failed to execute bulk item (index) BulkShardRequest ...source[n/a, actual length: [4.5kb], max length: 2kb]}], 請問是字段超過了最大長度2kb的限制嗎?
  • 答:日志中打出的max length不是字段的最大長度的意思,而是超過了2kb就不把具體的doc信息在日志中打出,bulk失敗的信息需要查看日志中后面的異常信息,一般是字段解析失敗或者是bulk隊列滿導致的。

第24問

第25問

  • 問: filebeat 7.x版本,在配置文件中定義了index名稱,為什么寫入到es中仍然生成的是filebeat-*之類的索引?
  • 答: 通過配置setup.ilm.enabled: false解決。索引生命周期管理ilm功能默認開啟,開啟的情況下索引名稱只能為filebeat-*, 通過setup.ilm.enabled: false進行關(guān)閉;如果要使用自定義的索引名稱,同時又需要啟用ilm,可以修改filebeat的模板。

第26問

  • 問: 使用filebeat+es+kibana收集容器中的nginx日志,但是發(fā)現(xiàn)kibana中的message是一整段,字段都放在一起了,請問這個該怎么處理?
  • 答: 兩種解決辦法:

(1)nginx日志配置為json格式, filebeat配置文件中指定解析json格式的日志json.keys_under_root: true
(2)仍然使用默認的nginx日志格式,在es中自定義ingest pipeline解析每個字段,filebeat配置文件中指定使用定義好的pipeline

第27問

  • 問: 請問ES的fielddata和docvalues有什么區(qū)別呢?
  • 答: fielddata是在堆內(nèi)存的,docvalues是在堆外內(nèi)存的;docvalues默認對所有not_analyzed字段開啟(index時生成),如果要對analyzed字段進行聚合,就要使用fielddata了(使用時把所有的數(shù)據(jù)全都加載進內(nèi)存);如果不需要對analyzed字段進行聚合,就可以降低堆內(nèi)存,Elasticsearch(更快的 GC)和 Lucene(更多的內(nèi)存用于緩存)的性能越好

第28問

  • 問:ES的ik-analyzer分詞插件默認會把英文大寫字母轉(zhuǎn)換為小寫,但是業(yè)務(wù)查詢時是對大小寫敏感的,怎么可以做到使用ik-analyzer分詞插件的同時禁止把大寫字母轉(zhuǎn)換為小寫?
  • 答:基于ik_smart分詞類型自定義analyzer, 同時配置參數(shù) "enable_lowercase": false:
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ik": {
          "type": "ik_smart",
          "enable_lowercase": false
        }
      }
    }
  }
}

第29問

  • 問:業(yè)務(wù)日志按文件大小滾動(最大100MB,滾動后壓縮),使用filbeat收集日志時,發(fā)現(xiàn)在日志滾動較快的情況下filebeat沒有釋放掉已經(jīng)被刪除掉的日志文件,導致磁盤使用率較高,請問這個怎么解決?
  • 答:可以通過配置close_timeout參數(shù)釋放掉已經(jīng)刪除文件的文件句柄。

第30問

  • 問:使用filebeat 5.6.4收集nginx日志文件(按天滾動,滾動后壓縮),發(fā)現(xiàn)filebeat data目錄下registry文件越來越大,并沒有清理掉很早日志文件的state信息,請問這個怎么解決?
  • 答:通過配置ignore_older和clean_inactive兩個參數(shù),清理掉registry中無用的文件state信息。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容