A. ES是什麼
是指Elastic search。
Elasticsearch是一個基於Lucene的搜索伺服器。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web介面。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜索引擎。
Elasticsearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業搜索引擎,其次是Apache Solr,也是基於Lucene。
相關信息:
Elasticsearch可以用於搜索各種文檔。它提供可擴展的搜索,具有接近實時的搜索,並支持多租戶。Elasticsearch是分布式的,這意味著索引可以被分成分片,每個分片可以有0個或多個副本。每個節點託管一個或多個分片,並充當協調器將操作委託給正確的分片。
再平衡和路由是自動完成的。相關數據通常存儲在同一個索引中,該索引由一個或多個主分片和零個或多個復制分片組成。一旦創建了索引,就不能更改主分片的數量。
B. elasticsearch可以替代資料庫嗎
不推薦代替資料庫哦~
ES團隊不推薦完全採用ES作為主要存儲,缺乏訪問控制還有一些數據丟失和污染的問題
建議還是採用專門的 DB存儲方案,然後用ES來做serving。
C. ES是什麼
指音的指碼母顏文色字,s英色代型指彩色與網字指寫e色號指還號的母.字種拼也品產一絡.也.也.密情發
D. ElasticSearch性能優化實踐(JVM調優+ES調優)
近一年內對公司的 ELK 日誌系統做過性能優化,也對 SkyWalking 使用的 ES 存儲進行過性能優化,在此做一些總結。本篇主要是講 ES 在 ELK 架構中作為日誌存儲時的性能優化方案。
隨著接入ELK的應用越來越多, 每日新增索引約 230 個,新增 document 約 3000萬到 5000萬 。
每日上午和下午是日誌上傳高峰期,在 Kibana 上查看日誌,發現問題:
(1) 日誌會有 5-40 分鍾的延遲
(2) 有很多日誌丟失,無法查到
數據先是存放在 ES 的內存 buffer,然後執行 refresh 操作寫入到操作系統的內存緩存 os cache,此後數據就可以被搜索到。
所以,日誌延遲可能是我們的數據積壓在 buffer 中沒有進入 os cache 。
查看日誌發現很多 write 拒絕執行的情況
從日誌中可以看出 ES 的 write 線程池已經滿負荷,執行任務的線程已經達到最大16個線程,而200容量的隊列也已經放不下新的task。
查看線程池的情況也可以看出 write 線程池有很多寫入的任務
所以我們需要優化 ES 的 write 的性能。
ES 的優化分為很多方面,我們要根據使用場景考慮對 ES 的要求。
根據個人實踐經驗,列舉三種不同場景下的特點 :
這三類場景的特點如下:
關於實時性
可以從三方面進行優化:JVM性能調優、ES性能調優、控制數據來源
可以從三方面進行優化:JVM 性能調優、ES 性能調優、控制數據來源
第一步是 JVM 調優。
因為 ES 是依賴於 JVM 運行,沒有合理的設置 JVM 參數,將浪費資源,甚至導致 ES 很容易 OOM 而崩潰。
(1) 查看 GC 日誌
(2) 使用 jstat 看下每秒的 GC 情況
用下面幾種方式都可查看新、老年代內存大小
(1) 使用 jstat -gc pid 查看 Eden 區、老年代空間大小
(2) 使用 jmap -heap pid 查看 Eden 區、老年代空間大小
(3) 查看 GC 日誌中的 GC 明細
上面的幾種方式都查詢出,新生代總內存約1081M,即1G左右;老年代總內存為19864000K,約19G。新、老比例約1:19,出乎意料。
這真是一個容易踩坑的地方。
如果沒有顯示設置新生代大小,JVM 在使用 CMS 收集器時會自動調參,新生代的大小在沒有設置的情況下是通過計算得出的,其大小可能與 NewRatio 的默認配置沒什麼關系而與 ParallelGCThreads 的配置有一定的關系。
所以: 新生代大小有不確定性,最好配置 JVM 參數 -XX:NewSize、-XX:MaxNewSize 或者 -xmn ,免得遇到一些奇怪的 GC,讓人措手不及。
新生代過小,老年代過大的影響
32G 的內存,分配 20G 給堆內存是不妥當的,所以調整為總內存的50%,即16G。
修改 elasticsearch 的 jvm.options 文件
設置要求:
因為指定新生代空間大小,導致 JVM 自動調參只分配了 1G 內存給新生代。
修改 elasticsearch 的 jvm.options 文件,加上
老年代則自動分配 16G-8G=8G 內存,新生代老年代的比例為 1:1。修改後每次 Young GC 頻率更低,且每次 GC 後只有少數數據會進入老年代。
ES默認使用的垃圾回收器是:老年代(CMS)+ 新生代(ParNew)。如果是JDK1.9,ES 默認使用G1垃圾回收器。
因為使用的是 JDK1.8,所以並未切換垃圾回收器。後續如果再有性能問題再切換G1垃圾回收器,測試是否有更好的性能。
優化前
每秒列印一次 GC 數據。可以看出,年輕代增長速度很快,幾秒鍾年輕代就滿了,導致 Young GC 觸發很頻繁,幾秒鍾就會觸發一次。而每次 Young GC 很大可能有存活對象進入老年代,而且,存活對象多的時候(看上圖中第一個紅框中的old gc數據),有(51.44-51.08)/100 * 19000M = 約68M。每次進入老年代的對象較多,加上頻繁的 Young GC,會導致新老年代的分代模式失去了作用,相當於老年代取代了新生代來存放近期內生成的對象。當老年代滿了,觸發 Full GC,存活的對象也會很多,因為這些對象很可能還是近期加入的,還存活著,所以一次 Full GC 回收對象不多。而這會惡性循環,老年代很快又滿了,又 Full GC,又殘留一大部分存活的,又很容易滿了,所以導致一直頻繁 Full GC。
優化後
每秒列印一次 GC 數據。可以看出,新生代增長速度慢了許多,至少要60秒才會滿,如上圖紅框中數據,進入老年代的對象約(15.68-15.60)/100 * 10000 = 8M,非常的少。所以要很久才會觸發一次 Full GC 。而且等到 Full GC 時,老年代裡很多對象都是存活了很久的,一般都是不會被引用,所以很大一部分會被回收掉,留一個比較干凈的老年代空間,可以繼續放很多對象。
ES 啟動後,運行14個小時
優化前
Young GC 每次的時間是不長的,從上面監控數據中可以看出每次GC時長 1467.995/27276 約等於 0.05秒。那一秒鍾有多少時間實在處理Young GC ? 計算公式:1467秒/ (60秒×60分 14小時)= 約0.028秒,也就是100秒中就有2.8秒在Young GC,也就是有2.8S的停頓,這對性能還是有很大消耗的。同時也可以算出多久一次Young GC, 方程是: 60秒×60分*14小時/ 27276次 = 1次/X秒,計算得出X = 0.54,也就是0.54秒就會有一次Young GC,可見 Young GC 頻率非常頻繁。
優化後
Young GC 次數只有修改前的十分之一,Young GC 時間也是約八分之一。Full GC 的次數也是只有原來的八分之一,GC 時間大約是四分之一。
GC 對系統的影響大大降低,性能已經得到很大的提升。
上面已經分析過ES作為日誌存儲時的特性是:高並發寫、讀少、接受30秒內的延時、可容忍部分日誌數據丟失。
下面我們針對這些特性對ES進行調優。
本人整理了一下數據寫入的底層原理
refresh
ES 接收數據請求時先存入 ES 的內存中,默認每隔一秒會從內存 buffer 中將數據寫入操作系統緩存 os cache,這個過程叫做 refresh;
到了 os cache 數據就能被搜索到(所以我們才說 ES 是近實時的,因為1s 的延遲後執行 refresh 便可讓數據被搜索到)
fsync
translog 會每隔5秒或者在一個變更請求完成之後執行一次 fsync 操作,將 translog 從緩存刷入磁碟,這個操作比較耗時,如果對數據一致性要求不是跟高時建議將索引改為非同步,如果節點宕機時會有5秒數據丟失;
flush
ES 默認每隔30分鍾會將 os cache 中的數據刷入磁碟同時清空 translog 日誌文件,這個過程叫做 flush。
merge
ES 的一個 index 由多個 shard 組成,而一個 shard 其實就是一個 Lucene 的 index ,它又由多個 segment 組成,且 Lucene 會不斷地把一些小的 segment 合並成一個大的 segment ,這個過程被稱為 段merge 。執行索引操作時, ES會先生成小的segment ,ES 有離線的邏輯對小的 segment 進行合並,優化查詢性能。但是合並過程中會消耗較多磁碟 IO,會影響查詢性能。
為了保證不丟失數據,就要保護 translog 文件的安全:
該方式提高數據安全性的同時, 降低了一點性能.
==> 頻繁地執行 fsync 操作, 可能會產生阻塞導致部分操作耗時較久. 如果允許部分數據丟失, 可設置非同步刷新 translog 來提高效率,還有降低 flush 的閥值,優化如下:
寫入 Lucene 的數據,並不是實時可搜索的,ES 必須通過 refresh 的過程把內存中的數據轉換成 Lucene 的完整 segment 後,才可以被搜索。
默認1秒後,寫入的數據可以很快被查詢到,但勢必會產生大量的 segment,檢索性能會受到影響。所以,加大時長可以降低系統開銷。對於日誌搜索來說,實時性要求不是那麼高,設置為5秒或者10s;對於SkyWalking,實時性要求更低一些,我們可以設置為30s。
設置如下:
index.merge.scheler.max_thread_count 控制並發的 merge 線程數,如果存儲是並發性能較好的 SSD,可以用系統默認的 max(1, min(4, availableProcessors / 2)),當節點配置的 cpu 核數較高時,merge 佔用的資源可能會偏高,影響集群的性能,普通磁碟的話設為1,發生磁碟 IO 堵塞。設置max_thread_count 後,會有 max_thread_count + 2 個線程同時進行磁碟操作,也就是設置為 1 允許3個線程。
設置如下:
該方式可對已經生成的索引做修改,但是對於後續新建的索引不生效,所以我們可以製作 ES 模板,新建的索引按模板創建索引。
因為我們的業務日誌是按天維度創建索引,索引名稱示例:user-service-prod-2020.12.12,所以用通配符 202 ..*匹配對應要創建的業務日誌索引。
前文已經提到過,write 線程池滿負荷,導致拒絕任務,而有的數據無法寫入。
而經過上面的優化後,拒絕的情況少了很多,但是還是有拒絕任務的情況。
所以我們還需要優化write線程池。
從 prometheus 監控中可以看到線程池的情況:
為了更直觀看到ES線程池的運行情況,我們安裝了 elasticsearch_exporter 收集 ES 的指標數據到 prometheus,再通過 grafana 進行查看。
經過上面的各種優化,拒絕的數據量少了很多,但是還是存在拒絕的情況,如下圖:
write 線程池如何設置:
參考: ElasticSearch線程池
write 線程池採用 fixed 類型的線程池,也就是核心線程數與最大線程數值相同。線程數默認等於 cpu 核數,可設置的最大值只能是 cpu 核數加1,也就是16核CPU,能設置的線程數最大值為17。
優化的方案:
config/elasticsearch.yml文件增加配置
優化後效果
Swap 交換分區 :
參考: ElasticSearch官方解釋為什麼要禁用交換內存
有三種方式可以實現 ES 不使用Swap分區
執行命令
可以臨時禁用 Swap 內存,但是操作系統重啟後失效
執行下列命令
正常情況下不會使用 Swap,除非緊急情況下才會 Swap。
config/elasticsearch.yml 文件增加配置
分片
索引的大小取決於分片與段的大小,分片過小,可能導致段過小,進而導致開銷增加;分片過大可能導致分片頻繁 Merge,產生大量 IO 操作,影響寫入性能。
因為我們每個索引的大小在15G以下,而默認是5個分片,沒有必要這么多,所以調整為3個。
分片的設置我們也可以配置在索引模板。
副本數
減少集群副本分片數,過多副本會導致 ES 內部寫擴大。副本數默認為1,如果某索引所在的1個節點宕機,擁有副本的另一台機器擁有索引備份數據,可以讓索引數據正常使用。但是數據寫入副本會影響寫入性能。對於日誌數據,有1個副本即可。對於大數據量的索引,可以設置副本數為0,減少對性能的影響。
分片的設置我們也可以配置在索引模板。
有的應用1天生成10G日誌,而一般的應用只有幾百到1G。一天生成10G日誌一般是因為部分應用日誌使用不當,很多大數量的日誌可以不打,比如大數據量的列表查詢介面、報表數據、debug 級別日誌等數據是不用上傳到日誌伺服器,這些 即影響日誌存儲的性能,更影響應用自身性能 。
優化後的兩周內ELK性能良好,沒有使用上的問題:
參考
E. 怎麼用spring獲取es數據
1. ES和solr都是作為全文搜索引擎出現的。都是基於Lucene的搜索伺服器。
2. ES不是可靠的存儲系統,不是資料庫,它有丟數據的風險。
3. ES不是實時系統,數據寫入成功只是trans log成功(類似於MySQL的bin log),寫入成功後立刻查詢查不到是正常的。因為數據此刻可能還在內存里而不是進入存儲引擎里。同理,刪除一條數據後也不是馬上消失。寫入何時可查詢?ES內部有一個後台線程,定時將內存中的一批數據寫入到存儲引擎,此後數據可見。默認後台線程一秒運行一次。該線程運行的越頻繁,寫入性能越低。運行的頻率越低,寫入的性能越高(不會無限高)。
4. 目前已知的單ES集群可以存儲PB級別的數據,不過這個就非常費勁了。TB級別數據沒壓力。
5. 如果使用ES官方提供的jar包訪問,需要JDK1.7及以上。
6. 使用對應的版本訪問ES server。如果ES server端的版本是1.7,那麼請使用ES 1.7的client。如果ES server是2.1,請使用2.1的client。
7. ES索引存在Linux伺服器的文件系統之上(背後是文件系統,不是類似於HDFS的分布式文件系統)
8. ES Java client是線程安全的,全局構建一個即可滿足讀寫需求,不要每次都創建ES client。每次訪問ES都構建新的es client即會拋出次異常。
9. 非常不建議使用ES的動態識別和創建的機制,因為很多情況下這並非你所需要。推薦的做法是在寫數據之前仔細的創建mapping。
10. 強烈不建議在ES中使用深分頁。可能會導致集群不可用。
11. ES是靜態分片,一旦分片數在創建索引時確定那麼後繼不能修改。
12. ES里提供了type,很多人以為type是物理表,一個type的數據是獨立存儲的;但是在ES內部並不是這樣,type在ES內部僅僅是一個欄位。所以在很多數據能分為獨立index的情況下,不要放到一個index里用type去分。只有嵌套類和父子類的情況下使用type才是合理的。
13. ES並不提供原生的中文分詞的能力。有第三方的中文分詞的插件,比如ik等。Ik是個toy分詞器,有嚴肅的分詞需求的話,請在使用ES之前使用獨立的分詞器分好詞後向ES寫入。
14. ES中的index,首先會進行分片,每一個分片數據一般都會有自己的副本數據,ES分配分片的策略會保證同一個分片數據和自己的副本不會分配到同一個節點上。當集群中的某一節點宕機後,ES的master在ping該節點時通過一定的策略會發現該節點不存活;會開啟ES的恢復過程
15. ES沒有update的能力。所有的update都是標記刪除老文檔,然後重新insert一條新文檔。
F. 匯編語言bp寄存器和es寄存器有何用
bp是基地址寄存器,一般在訪問數組或是有固定偏移量的記錄時用於存放基地址;es功能跟DS差不多都是數據段的基地址
G. es是什麼
Elasticsearch是一個基於Lucene的搜索伺服器。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web介面。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜索引擎。
Elasticsearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業搜索引擎,其次是Apache Solr,也是基於Lucene。
相關信息:
Elasticsearch可以用於搜索各種文檔。它提供可擴展的搜索,具有接近實時的搜索,並支持多租戶。Elasticsearch是分布式的,這意味著索引可以被分成分片,每個分片可以有0個或多個副本。每個節點託管一個或多個分片,並充當協調器將操作委託給正確的分片。
再平衡和路由是自動完成的。相關數據通常存儲在同一個索引中,該索引由一個或多個主分片和零個或多個復制分片組成。一旦創建了索引,就不能更改主分片的數量。
H. 為什麼ES不適合做數據存儲
es?
什麼意思?
es文件管理器?》