題記
馬雲演講中曾經提到:很多時候少聽成功專家的話。所有的創業者多花點時間學習別人是怎麼失敗的,因爲成功的原因有千千萬萬,失敗的原因就一兩個點。
創業需要關注別人的失敗,而開發實戰,別人的錯誤經驗、別人的問題也非常有價值。
開發最懊悔的事莫過於:自己費盡腦汁、花費了很長時間解決了問題,原來別人在社區或者別的地方早已經給出了更優化的方案。
開發最最懊悔的事莫過於:別人已經給出了方案,但是我們仍然在黑暗中苦逼的摸索。
因此,我從2018年4月——至今,每月都會梳理出了Elasticsearch中文社區的精華乾貨——簡稱:Elastic錯題本,
問題大多來自Medcl、wood大叔等大牛的精彩回覆,結合實戰嚴選的核心問題。
放在了GitHub上。
GitHub地址:https://github.com/laoyang360/deep_elasticsearch/tree/master/es_accumulate
目的:提前加深認知,少重複走別人的彎路!
1、Elasticsearch
1.1 如何清理Elasticsearch特定時間段數據?
- Elasticsearch 6.6+新推出了一個 ILM 的功能,Index Lifecycle Management 的功能,在Kibana 界面裏面就可以直接配置索引的保留時間和過期策略。
上一次錯題本也提及:https://elasticsearch.cn/article/6358 - es5.0提供了 Rollover 特性
https://elasticsearch.cn/question/1094
1.2 能否在一個查詢中 查詢兩個條件 在對兩個結果進行除法計算?
請教各位一個問題,我們有一個場景,想通過1個查詢語句,計算兩個查詢結果的除法,
比如,我有一個查詢條件,用 idc: “BJ” 能統計出有100條數據符合要求 ,
第二個條件 idc: “SH”,能統計出有200個數據,我現在想要取到 100 / 200 這個值 50% 這個數據,
請問能有辦法實現嗎?
#參考 es6.6版本
PUT test01_index/_doc/5
{
"x_value":15,
"y_value":3
}
POST test01_index/_doc/_search
{
"script_fields": {
"my_divide_field": {
"script": {
"lang": "expression",
"source": "doc['y_value'].value != 0 ? doc['x_value'].value / doc['y_value'].value : 0"
}
}
}
}
1.3 ngram分詞器會佔很多內存嗎?
ngram分詞分的很細,會不會導致較多的內存佔用?當數據量較大時,是否有瓶頸??
【回覆】ngram分詞分的很細會產生較多的 term ,因此會比普通使用詞典分詞的佔用更多的存儲和內容;
數據量大的時候,可通過分索引和多分片來分散壓力。
1.4 自定義id帶來的問題
問題描述:我們目前業務使用了自定義id,md5(uid+someid), 目的是爲了再次更新方便。但是這樣有兩個問題,1: 這種隨機的自定義id,壓縮比很低,空間佔用高。2: 指定id bulk index 的時候,es 會先判斷 id 是否存在,然後再插入。這樣隨着數據量的增加,性能持續下降。 不知道大家有什麼好辦法,對應這種需要持續更新的數據。 數據量還挺大的。
官網建議:如果使用了自動生成id,每次導入數據的時候都要進行id的檢查。這裏是有性能消耗的。但是使用隨機生成id,就不需要這一步。
官網地址:http://t.cn/Ei47gY0
討論建議:
- id的生成策略儘量是對壓縮友好的,避免過於隨機,比如按序生成
- 想到一點減小id是否存在的判斷成本,是否考慮使用
路由
,相當於指定了插入doc所在的shard,減少判斷是否存在的數據量
1.5 關於 ik 新詞更新
想做新詞發現,更新詞庫,但是搞不清es對於這種更新詞庫後,老數據怎麼處理爲好
建議:不影響搜索的話,重建索引,reindex ,然後別名切換過去。
原因:ES數據寫入的過程即是索引化的過程,這個階段會按照設定的分詞進行數據索引化。所以,必須reindex重建索引或者重新導入數據才能生效。
1 .6 es有沒可能同時寫多個索引?
有舊有數據的同步問題的困擾,需要類似數據雙寫的操作,貌似直接設置同一個別名然後insert會報錯
alias 只能聲明一個索引爲寫活躍狀態,無法多個同時寫入,否則會報錯。
或者用reindex 開始的時候你寫兩份就行啊,修改一份。
1.7 bulk寫入數據時,READ非常高
無論是index或者是update,只要指定了doc id,lucene都需要進行get操作,當你索引數據量很大時,會有頻繁且大量segment中的數據加載到內存,這是read io高
的一個大原因,
另外通常merge 只要線程數限小,不會有非常高的read io,我之前也碰到過這個問題,自己探索了下
經覈實:確實是因爲指定id引起的。
https://elasticsearch.cn/question/6526
1.8 增加索引個數能有效的提高寫入效率嗎?
如題,
現在ES集羣是一個索引在寫,後臺15臺物理機,48c,188G,是多線程同步寫一個索引,看監控能到40W,再加併發也提高不了,但是機器的負載和線程池資源都還OK,我看線程池是index級別的設定,能通過增加寫入索引個數來增加寫入性能吧,還是說要擴容呢?
寫入及索引性能核心參考:https://www.elastic.co/guide/en/elasticsearch/reference/master/tune-for-indexing-speed.html
網上所有的書籍、文檔基本都離不開鏈接給出的東西
1.9 Elasticsearch6.5.3全聚合出現與MySQL聚合結果不一致的問題
MySQL中的聚合語句:
select sum(adv_price) from report_2019_01 where report_time>=1546272000 and report_time<1546358400;
MySQL聚合結果是:11612.840
將上面時間的數據全部導入es中,並聚合:
"aggregations": {
"revenue": {
"sum": {
"field": "adv_price"
}
}
}
}
Elasticsearch聚合結果是:9064
原因:浮點精度問題,類似相關問題都是浮點精度問題思路排查的。
1.10 如何對同一個字段進行不同的分詞
multi-fields 可以實現,也就是說一個字段可以設置多個子字段.
推薦視頻:https://elasticsearch.cn/article/13274
1.11 es禁止*刪除索引
1、永久修改——通過setting修改
PUT /_cluster/settings
{
"persistent": {
"action.destructive_requires_name": "true"
}
}
2、通過配置文件修改
建議通過1修改
1.12 怎樣限定es查詢返回數據最低分,低於XX分數的不要
min_score參數
SearchResponse response = client.prepareSearch(INDEX_NAME)
.setTypes(TYPE_NAME)
.setQuery(queryBuilder)
.setMinScore(minScore)
.execute()
.actionGet();
.setMinScore(minScore)
1.13 想問下多個terms查詢爲何不起作用,有沒有什麼解決辦法
https://elasticsearch.cn/question/7342
問題原因:大小寫問題
默認的standard analyzer包含lowcase token filter, 會把大寫轉換爲小寫,,如果一定要使用大寫查詢的話,可以自定義
1.14 關於translog和線程池拒絕
比如提交bulk,請求寫入了translog,但是由於服務器壓力大,線程池拒絕了這個請求,那translog還有用嗎?
回覆:寫translog是在寫內存之後纔會發生,如果出現拒絕是連內存還沒寫入就拒絕了,遠沒有到寫translog,
可以看看這篇文章:https://zhuanlan.zhihu.com/p/34669354
1.15 es search爲啥不用bloom filter?
首先你需要了解布隆過濾器的用途,一般是用於字符串或者數字等,檢測是否存在的場景,例如:爬蟲的 URL 去重;
ES 的查詢,大部分場景是看某個文本是否存在與某篇文檔中;或者日期、數字等是否在某個範圍;
所以應用的方向不同,因此 ES 使用了倒排索引、KD數等其他數據結構實現了搜索
1.16 將文檔存儲在es外面,同時使es搜索結果只返回文檔基本信息,這樣做能否提高性能?
問題描述:
就是說,如果文檔比較大,es把它作爲搜索結果整個返回的時候,可能對es性能造成壓力。
所以一個自然的想法就是,index時把文檔整個存進es,同時把文檔另存一份在其他專用的靜態存儲空間中,query時使es只返回文檔基本信息,如id、timestamp等,再通過id來找到靜態存儲空間中的相應文檔。
這樣子能否對es性能有較大提升,實際應用中這樣的使用模式多不多呢?
wood大叔回覆:如果文檔都非常大,靜態存儲方案廉價,能按照id,timestamp快速fetch回數據,那麼這種方案未嘗不可。 但是複雜性方面比全部放ES要高一些,應用層面多了一個依賴,也享受不到某些原生的ES特性,比如reindex。再就是靜態存儲通常也要是分佈式的,維護也有成本。所以你還是要評估一下用靜態存儲的話能省多少硬件
,如果省得不多,還不如將文檔全部放ES裏簡單直接。
bsll:理論上是可以的,用過es+hbase, es+couchbase的案例,不過樓上說的很對,得根據你的實際情況來。
1.17 sql中的 is null 和 is not null 在Elasticsearch的應用
建議源頭出發,定義NULL.
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"status_code": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
}
1.18 elasticsearch 刪除不用的索引 怎麼真正釋放磁盤空間?
比如 我創建了 course1 course2 course3 這些都是測試創建的索引 但是我用curl -XDELETE http://192.168.1.113:9200/course1 這樣的命令將course1 2 3 分別刪除 但是在 elasticsearch data 目錄下文件並未釋放磁盤空間 怎麼操作才能刪除之前不用的索引並釋放磁盤空間呢 謝謝!!
解決方案:https://elastic.blog.csdn.net/article/details/80038930
2 Logstash
2.1 logstash 批量接收數據
在logstash 中有沒有辦法使用 avro 接收數據,或者有沒有其他方案能夠接收flume 的avro sink 發來的數據
實現:
input {
kafka {
codec => avro {
schema_uri => "/tmp/schema.avsc"
}
}
}
filter {
...
}
output {
...
}
https://www.elastic.co/guide/en/logstash/current/plugins-codecs-avro.html
2.2 logstash中添加fielter grok之後怎麼過濾多餘的字段
保留message字段
參考如下:
filter {
grok {
remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
}
}
2.3 logstash和es的template
問題描述:
logstash和es都指定了索引的模板, 那logstash採集數據到es時,以哪個模板爲準呢
回覆:兩個模板會merge, 如果兩個模板有相同的配置項,以模板order大的爲準,不同的配置項則都會生效;建議設置一個單獨的模板就行了,多個模板可能有問題。
建議:實際場景驗證一下。
2.4 logstash數據監聽
問題描述:
redis中的數據通過logstash直接入庫到elasticsearch,項目使用的語言是java,目前的情況是,需要在elasticsearch中一有新數據,就要做一些其他的操作,不知道有沒有什麼方案,類似監聽elasticsearch數據是否更新、增加的機制來實現
解決方案:elasticsearch alert有類似功能,可以看一下。
3、Kibana
3.1 Kibana中有幾個Dashboard,可否對每個Dashboard分配權限,使其能夠開放給指定人羣瀏覽?
space的出現的目的就是相同公司不同部門實現不同權限的。可以參考。
3.2 kibana dev tools中文輸入有問題
這是kibana低版本的bug,高版本已經修復。kibana6.6已經不存在。
銘毅天下——Elasticsearch基礎、進階、實戰第一公衆號