其實,elasticsearch5.x 和 elasticsearch2.x 並不區別很大。html
是由於,ELK裏以前版本各類很混亂,直接升級到5.0了。git
其實,elasticsearch5.x 按理來講是elasticsearch3.x,只是爲了跟隨ELK總體版本的統一。github
下面給你們介紹一下 5.0 版裏面的一些新的特性和改進算法
5.0? 天啦嚕,你是否是以爲版本跳的太快了。數據庫
好吧,先來講說背後的緣由吧。windows
相信你們都據說 ELK 吧,是 Elasticsearch 、 Logstash 、 Kibana 三個產品的首字母縮寫,如今 Elastic 又新增了一個新的開源項目成員: Beats。數組
有人建議之後這麼叫: ELKB ?緩存
爲了將來更好的擴展性:) ELKBS?ELKBSU?.....安全
因此咱們打算將產品線命名爲 ElasticStack數據結構
同時因爲如今的版本比較混亂,每一個產品的版本號都不同, Elasticsearch和Logstash目前是2.3.4;Kibana是4.5.3;Beats是1.2.3;
版本號太亂了有沒有,什麼版本的 ES 用什麼版本的 Kibana ?有沒有兼容性問題?
因此咱們打算將這些的產品版本號也統一一下,即 v5.0 ,爲何是 5.0 ,由於 Kibana 都 4.x 了,下個版本就只能是 5.0 了,其餘產品就跟着跳躍一把,第一個 5.0 正式版將在今年的秋季發佈,目前最新的測試版本是: 5.0 Alpha 4。
目前各團隊正在緊張的開發測試中,天天都有新的功能和改進,本次分享主要介紹一下 Elasticsearch 的主要變化。
Elasticsearch5.0新增功能
首先來看看 5.0 裏面都引入了哪些新的功能吧。
Elasticsearch5.0率先集成了Lucene6版本,其中最重要的特性就是 Dimensional Point Fields,多維浮點字段,ES裏面相關的字段如date, numeric,ip 和 Geospatial 都將大大提高性能。
這麼說吧,磁盤空間少一半;索引時間少一半;查詢性能提高25%;IPV6也支持了。
爲何快,底層使用的是Block k-d trees,核心思想是將數字類型編碼成定長的字節數組,對定長的字節數組內容進行編碼排序,而後來構建二叉樹,而後依次遞歸構建,目前底層支持8個維度和最多每一個維度16個字節,基本知足大部分場景。
說了這麼多,看圖比較直接。
圖中從 2015 /10/32 total bytes 飆升是由於 es 啓用了 docvalues ,咱們關注紅線,最近的引入新的數據結構以後,紅色的索引大小隻有原來的一半大小。
索引小了以後, merge 的時間也響應的減小了,看下圖:
相應的 Java 堆內存佔用只原來的一半:
1.2 再看看 索引的性能 ,也是飆升:
固然 Lucene6 裏面還有不少優化和改進,這裏沒有一一列舉。
1.3 咱們再看看索引性能方面的其餘優化。
ES5.0在Internal engine級別移除了用於避免同一文檔併發更新的競爭鎖,帶來15%-20%的性能提高 #18060 。
以上截圖來自 ES 的每日持續性能監控: https://benchmarks.elastic.co/index.html
Elasticsearch已經在Shard層面提供了Aggregation緩存,若是你的數據沒有變化,ES可以直接返回上次的緩存結果,可是有一個場景比較特殊,就是 date histogram,你們kibana上面的條件是否是常常設置的相對時間,如:from:now-30d to:now,好吧,now是一個變量,每時每刻都在變,因此query條件一直在變,緩存也就是沒有利用起來。
通過一年時間大量的重構,如今能夠作到對查詢作到靈活的重寫:
首先,`now`關鍵字最終會被重寫成具體的值;
其次 , 每一個shard會根據本身的數據的範圍來重寫查詢爲 `match_all`或者是`match_none`查詢,因此如今的查詢可以被有效的緩存,而且只有個別數據有變化的Shard才須要從新計算,大大提高查詢速度。
1.5 另外再看看和Scroll相關的吧。
如今新增了一個:Sliced Scroll類型
用過Scroll接口吧,很慢?若是你數據量很大,用Scroll遍歷數據那確實是接受不了,如今Scroll接口能夠併發來進行數據遍歷了。
每一個Scroll請求,能夠分紅多個Slice請求,能夠理解爲切片,各Slice獨立並行,利用Scroll重建或者遍歷要快不少倍。
看看這個demo
能夠看到兩個 scroll 請求, id 分別是 0 和 1 , max 是最大可支持的並行任務,能夠各自獨立進行數據的遍歷獲取。
二、咱們再看看es在查詢優化這塊作的工做
#https://www.elastic.co/guide/en/elasticsearch/reference/master/search-profile.html#_usage_3
都說要致富先修路,要調優固然須要先監控啦,elasticsearch在不少層面都提供了stats方便你來監控調優,可是還不夠,其實不少狀況下查詢速度慢很大一部分緣由是糟糕的查詢引發的,玩過SQL的人都知道,數據庫服務的執行計劃(execution plan)很是有用,能夠看到那些查詢走沒走索引和執行時間,用來調優,elasticsearch如今提供了Profile API來進行查詢的優化,只須要在查詢的時候開啓profile:true就能夠了,一個查詢執行過程當中的每一個組件的性能消耗都能收集到。
那個子查詢耗時多少,佔比多少,一目瞭然。
同時支持search和aggregation的profile。
還有一個和翻頁相關的問題,就是深度分頁 ,是個老大難的問題,由於須要全局排序( number_of_shards * (from + size) ),因此須要消耗大量內存,之前的 es 沒有限制,有些同窗翻到幾千頁發現 es 直接內存溢出掛了,後面 elasticsearch 加上了限制, from+size 不能超過 1w 條,而且若是須要深度翻頁,建議使用 scroll 來作。
可是 scroll 有幾個問題,第一個是沒有順序,直接從底層 segment 進行遍歷讀取,第二個實時性無法保證, scroll 操做有狀態, es 會維持 scroll 請求的上下文一段時間,超時後才釋放,另外你在 scroll 過程當中對索引數據進行了修改了,這個時候 scroll接口是拿不到的,靈活性較差, 如今有一個新的 Search After 機制,其實和 scroll 相似,也是遊標的機制,它的原理是對文檔按照多個字段進行排序,而後利用上一個結果的最後一個文檔做爲起始值,拿 size 個文檔,通常咱們建議使用 _uid 這個字段,它的值是惟一的 id 。
#(Search After
https://github.com/elastic/elasticsearch/blob/148f9af5857f287666aead37f249f204a870ab39/docs/reference/search/request/search-after.asciidoc )
來看一個Search After 的demo 吧,比較直觀的理解一下:
上面的 demo , search_after 後面帶的兩個參數,就是 sort 的兩個結果。
根據你的排序條件來的,三個排序條件,就傳三個參數。
三、再看看跟索引與分片管理相關的新功能吧。
#https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-shrink-index.html#_shrinking_an_index
相信你們都知道elasticsearch索引的shard數是固定的,設置好了以後不能修改,若是發現shard太多或者太少的問題,以前若是要設置Elasticsearch的分片數,只能在建立索引的時候設置好,而且數據進來了以後就不能進行修改,若是要修改,只能重建索引。
如今有了Shrink接口,它可將分片數進行收縮成它的因數,如以前你是15個分片,你能夠收縮成5個或者3個又或者1個,那麼咱們就能夠想象成這樣一種場景,在寫入壓力很是大的收集階段,設置足夠多的索引,充分利用shard的並行寫能力,索引寫完以後收縮成更少的shard,提升查詢性能。
這裏是一個API調用的例子
上面的例子對 my_source_index 伸縮成一個分片的 my_targe_index, 使用了最佳壓縮。
有人確定會問慢不慢?很是快! Shrink的過程會藉助操做系統的Hardlink進行索引文件的連接,這個操做是很是快的,毫秒級Shrink就可收縮完成,固然windows不支持hard link,須要拷貝文件,可能就會很慢了。
再來看另一個比較有意思的新特性,除了有意思,固然還很強大。
https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-rollover-index.html#indices-rollover-index
前面說的這種場景對於日誌類的數據很是有用,通常咱們按天來對索引進行分割(數據量更大還能進一步拆分),咱們之前是在程序裏設置一個自動生成索引的模板,你們用過logstash應該就記得有這麼一個模板logstash-[YYYY-MM-DD]這樣的模板,如今es5.0裏面提供了一個更加簡單的方式:Rollover API
API調用方式以下:
從上面能夠看到,首先建立一個 logs-0001 的索引,它有一個別名是 logs_write, 而後咱們給這個 logs_write 建立了一個 rollover 規則,即這個索引文檔不超過 1000 個或者最多保存 7 天的數據,超過會自動切換別名到 logs-0002, 你也能夠設置索引的 setting 、 mapping 等參數 , 剩下的 es 會自動幫你處理。這個特性對於存放日誌數據的場景是極爲友好的。
另外關於索引數據,你們以前常常重建,數據源在各類場景,重建起來非常頭痛,那就不得不說說如今新加的Reindex接口了,Reindex能夠直接在Elasticsearch集羣裏面對數據進行重建,若是你的mapping由於修改而須要重建,又或者索引設置修改須要重建的時候,藉助Reindex能夠很方便的異步進行重建,而且支持跨集羣間的數據遷移。
好比按天建立的索引能夠按期重建合併到以月爲單位的索引裏面去。
固然索引裏面要啓用_source。
來看看這個demo吧,重建過程當中,還能對數據就行加工。
3.4 再看看跟Java開發者最相關的吧,就是 RestClient了
5.0裏面提供了第一個Java原生的REST客戶端SDK,相比以前的TransportClient,版本依賴綁定,集羣升級麻煩,不支持跨Java版本的調用等問題,新的基於HTTP協議的客戶端對Elasticsearch的依賴解耦,沒有jar包衝突,提供了集羣節點自動發現、日誌處理、節點請求失敗自動進行請求輪詢,充分發揮Elasticsearch的高可用能力,而且性能不相上下。 #19055 。
四、而後咱們再看看其餘的特性吧:
簡單來講至關因而提供了文檔級別的Refresh: https://www.elastic.co/guide/en/elasticsearch/reference/master/docs-refresh.html。
索引操做新增refresh參數,你們知道elasticsearch能夠設置refresh時間來保證數據的實時性,refresh時間過於頻繁會形成很大的開銷,過小會形成數據的延時,以前提供了索引層面的_refresh接口,可是這個接口工做在索引層面,咱們不建議頻繁去調用,若是你有須要修改了某個文檔,須要客戶端實時可見怎麼辦?
在 5.0中,Index、Bulk、Delete、Update這些數據新增和修改的接口可以在單個文檔層面進行refresh控制了,有兩種方案可選,一種是建立一個很小的段,而後進行刷新保證可見和消耗必定的開銷,另一種是請求等待es的按期refresh以後再返回。
調用例子:
#https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest.html#
再一個比較重要的特性就是IngestNode了,你們以前若是須要對數據進行加工,都是在索引以前進行處理,好比logstash能夠對日誌進行結構化和轉換,如今直接在es就能夠處理了,目前es提供了一些經常使用的諸如convert、grok之類的處理器,在使用的時候,先定義一個pipeline管道,裏面設置文檔的加工邏輯,在建索引的時候指定pipeline名稱,那麼這個索引就會按照預先定義好的pipeline來處理了;
Demo again:
上圖首先建立了一個名爲my-pipeline-id的處理管道,而後接下來的索引操做就能夠直接使用這個管道來對foo字段進行操做了,上面的例子是設置foo字段爲bar值。
上面的還不太酷,咱們再來看另一個例子,如今有這麼一條原始的日誌,內容以下:
{
"message": "55.3.244.1 GET /index.html 15824 0.043」
}
google以後得知其Grok的pattern以下:)
%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}
那麼咱們使用Ingest就能夠這麼定義一個pipeline:
那麼經過咱們的 pipeline 處理以後的文檔長什麼樣呢,咱們獲取這個文檔的內容看看:
很明顯,原始字段 message 被拆分紅了更加結構化的對象了。
五、再看看腳本方面的改變
還記得Groove腳本的漏洞吧,Groove腳本開啓以後,若是被人誤用可能帶來的漏洞,爲何呢,主要是這些外部的腳本引擎太過於強大,什麼都能作,用很差或者設置不當就會引發安全風險,基於安全和性能方面,咱們本身開發了一個新的腳本引擎,名字就叫Painless,顧名思義,簡單安全,無痛使用,和Groove的沙盒機制不同,Painless使用白名單來限制函數與字段的訪問,針對es的場景來進行優化,只作es數據的操做,更加輕量級,速度要快好幾倍,而且支持Java靜態類型,語法保持Groove相似,還支持Java的lambda表達式。
咱們對比一下性能,看下圖
Groovy 是弱弱的綠色的那根。
再看看如何使用:
def first = input.doc.first_name.0;
def last = input.doc.last_name.0;
return first + " " + last;
是否是和以前的寫法差很少
或者還能夠是強類型(10倍速度於上面的動態類型)
String first = (String)((List)((Map)input.get("doc")).get("first_name")).get(0);
String last = (String)((List)((Map)input.get("doc")).get("last_name")).get(0);
return first + " " + last;
腳本能夠在不少地方使用,好比搜索自定義評分;更新時對字段進行加工等
如:
六、再來看看基礎架構方面的變化
這個是5.0 引入任務調度管理機制,用來作 離線任務的管理,好比長時間運行的reindex和update_by_query等都是運行在TaskManager機制之上的,而且任務是可管理的,你能夠隨時cancel掉,而且任務狀態持久化,支持故障恢復;
你們在用ES的時候,其實有些接口可能以及打上了Depreated標籤,即廢棄了,在未來的某個版本中就會移除,你當前能用是由於通常廢棄的接口都不會當即移除,給足夠的時間遷移,可是也是須要知道哪些不能用了,要改應用代碼了,因此如今有了Depreated日誌,當打開這個日誌以後,你調用的接口若是已是廢棄的接口,就會記錄下日誌,那麼接下來的事情你就知道你應該怎麼作了。
『誰能給我一個shard不能分配的理由』,如今有了,你們若是以前遇到過度片不能正常分配的問題,可是不知道是什麼緣由,只能嘗試手動路由或者重啓節點,可是不必定能解決,其實裏面有不少緣由,如今提供的這個explain接口就是告訴你目前爲何不能正常分配的緣由,方便你去解決。
https://www.elastic.co/guide/en/elasticsearch/reference/master/number.html
只使用 16 位 足夠知足大部分存儲監控數值類型的場景,支持範圍:2負24次方 到 65504,可是隻佔用float一半的存儲空間。
金融領域很是有用的,可計算多個向量元素協方差矩陣、相關係數矩陣等等
你們知道es是在primary上寫完而後同步寫副本,這些請求都是併發的,雖然能夠經過version來控制衝突,
可是無法保證其餘副本的操做順序,經過寫的時候產生順序號,而且在本地也寫入checkpoint來記錄操做點,
這樣在副本恢復的時候也能夠知道當前副本的數據位置,而只須要從指定的數據開始恢復就好了,而不是像之前的粗暴的作完整的文件同步 ,另外這些順序號也是持久化的,重啓後也能夠快速恢復副本信息,想一想之前的大量無用拷貝吧和來回倒騰數據吧。
七、Elasticsearch5.0其餘方面的改進
7.1 咱們再看看 mapping 這塊的改進 吧。
之前的string類型被分紅Text和Keyword兩種類型,keyword類型的數據只能徹底匹配,適合那些不須要分詞的數據,
對過濾、聚合很是友好,text固然就是全文檢索須要分詞的字段類型了。將類型分開的好處就是使用起來更加簡單清晰,之前須要設置analyzer和index,而且有不少都是自定義的分詞器,從名稱根本看不出來到底分詞沒有,用起來很麻煩。
另外string類型暫時還在的,6.0會移除。
Elasticsearch的配置實在太多,在之前的版本間,還移除過不少無用的配置,常常弄錯有沒有?
如今,配置驗證更加嚴格和保證原子性,若是其中一項失敗,那個整個都會更新請求都會失敗,不會一半成功一半失敗。下面主要說兩點:
1.設置能夠重設會默認值,只須要設置爲 `null`便可
2.獲取設置接口新增參數`?include_defaults`,能夠直接返回全部設置和默認值
在之前的es版本中,若是你的舊節點包含了部分索引數據,可是這個索引可能後面都已經刪掉了,你啓動這個節點以後,會把索引從新加到集羣中,是否是以爲有點陰魂不散,如今es5.0會在集羣狀態信息裏面保留500個刪除的索引信息,因此若是發現這個索引是已經刪除過的就會自動清理,不會再重複加進來了。
文檔對象的改進 : 字段名從新支持英文句號,再 2.0 的時候移除過 dot 在字段名中的支持,如今問題解決了,又從新支持了。
es會認爲下面兩個文檔的內容同樣:
7.4 還有其餘的一些改進
Cluster state 的修改如今會和全部節點進行 ack 確認。
Shard 的一個副本若是失敗了, Primary 標記失敗的時候會和 Master 節點確認完畢再返回。
使用 UUID 來做爲索引的物理的路徑名,有不少好處,避免命名的衝突。
_timestamp 和 _ttl 已經移除,須要在 Ingest 或者程序端處理。
ES 可直接用 HDFS 來進行備份還原( Snapshot/Restore )了 #15191 。
Delete-by-query 和 Update-by-query 從新回到 core ,之前是插件,如今能夠直接使用了,也是構建在 Reindex 機制之上。(es1.x版本是直接支持,在es2.x中提取爲插件,5.x繼續迴歸直接支持)
HTTP 請求默認支持壓縮,固然 http 調用端須要在 header 信息裏面傳對應的支持信息。
建立索引不會再讓集羣變紅了,不會由於這個卡死集羣了。
默認使用 BM25 評分算法,效果更佳,以前是 TF/IDF。
快照 Snapshots 添加 UUID 解決衝突 #18156 。
限制索引請求大小,避免大量併發請求壓垮 ES #16011。
限制單個請求的 shards 數量,默認 1000 個 #17396。
移除 site plugins ,就是說 head 、 bigdesk 都不能直接裝 es 裏面了,不過能夠部署獨立站點(反正都是靜態文件)或開發 kibana 插件 #16038 。
容許現有 parent 類型新增 child 類型 #17956。
這個功能對於使用parent-child特性的人應該很是有用。
支持分號(;)來分割 url 參數,與符號( & )同樣 #18175 。
好比下面這個例子:
curl http://localhost:9200/_cluster/health?level=indices;pretty=true
好吧,貌似不少,其實上面說的還只是衆多特性和改進的一部分, es5.0 作了很是很是多工做,原本還打算講講 bug 修復的,可是太多了,時間有限, 一些重要的 bug在 2.x 都已經第一時間解決了。
八、你們能夠查看下面的連接瞭解更多更詳細的更新日誌
https://www.elastic.co/guide/en/elasticsearch/reference/master/release-notes-5.0.0-alpha1-2x.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/release-notes-5.0.0-alpha1.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/release-notes-5.0.0-alpha2.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/release-notes-5.0.0-alpha3.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/release-notes-5.0.0-alpha4.html
下載體驗最新的版本 : https://www.elastic.co/v5
升級嚮導:https://github.com/elastic/elasticsearch-migration/blob/2.x/README.asciidoc