目的
本文主要介紹的內容有以下三點:
一. Elastic Stack是什么以及組成部分
二. Elastic Stack前景以及業務應用
三. Elasticsearch原理(索引方向)
四. Elasticsearch相對薄弱的地方
一、Elastic Stack是什么以及組成部分
介紹Elastic Stack是什么,其實只要一句話就可以,就是: 一套完整的大資料處理堆疊,從攝入、轉換到存盤分析、可視化,
它是不同產品的集合,各司其職,形成完整的資料處理鏈,因此Elastic Stack也可以簡稱為BLEK,
Beats 輕量型資料采集器
Logstash 輸入、過濾器和輸出
Elasticsearch 查詢和分析
Kibana 可視化,可自由選擇如何呈現資料
1. Beats - 全品類采集器,搞定所有資料型別
Filebeat(日志檔案):對成百上千、甚至上萬的服務器生成的日志匯總,可搜索,
Metricbeat(指標): 收集系統和服務指標,CPU 使用率、記憶體、檔案系統、磁盤 IO 和網路 IO 統計資料,
Packetbeat(網路資料):網路資料包分析器,了解應用程式動態,
Heartbeat(運行時間監控):通過主動探測來監測服務的可用性
......
Beats支持許許多多的beat,這里列的都是比較的常用的beat,了解更多可以點擊鏈接:Beats 社區
2. Logstash - 服務器端資料處理管道
介紹Logstash之前,我們先來看下Linux下常用的幾個命令
cat alldata.txt | awk ‘{print $1}’ | sort | uniq | tee filterdata.txt
只要接觸過Linux同學,應該都知道這幾個命名意思
cat alldata.txt #將alldata.txt的內容輸出到標準設備上
awk ‘{print $1}’ #對上面的內容做截取,只取每一行第一列資料
sort | uniq #對截取后的內容,進行排序和唯一性操作
tee filterdata.txt #將上面的內容寫到filterdata.txt
上面的幾個簡單的命令就可以看出來,這是對資料進行了常規的處理,用名詞修飾的話就是:資料獲取/輸入、資料清洗、資料過濾、資料寫入/輸出
而Logstash做的也是相同的事(看下圖),

將系統的日志檔案、應用日志檔案、系統指標等資料,輸入到Input,再通過資料清洗以及過濾,輸入到存盤設備中,這里當然是輸入到Elasticsearch
3. Elasticsearch - 分布式檔案存盤、RESTful風格的搜索和資料分析引擎
Elasticsearch主要也是最原始的功能就是搜索和分析功能,這里就簡單說一下,下面講原理的時候會著重講到Elasticsearch
搜索:全文搜索,完整的資訊源轉化為計算機可以識別、處理的資訊單元形成的資料集合 ,
分析:相關度,搜索所有內容,找到所需的具體資訊(詞頻或熱度等對結果排序)
4. Kibana- 可視化
可視化看下圖(來源官網)便知

可以對日志分析、業務分析等做可視化
現在從總體上來了解下,在心中對Elastic Stack有個清楚的認知(下圖),

二、Elastic Stack前景以及業務應用
1. DB-Engines 排名

Elasticsearch是Elastic Stack核心,由圖可以看出在搜索領域Elasticsearch暫時沒有對手,
2. ES社區

ES中文社區也是相當活躍的,會定期做一下分享,都是大公司的寶貴經驗,值得參考,
3. 2018年攜程的使用情況(讓我們看看能處理多大的資料)
集群數量是94個,最小的集群一般是3個節點,全部節點數量大概700+,
最大的一個集群是做日志分析的,其中資料節點330個,最高峰一天產生1600億檔案,寫入值300w/s,
現在有2.5萬億檔案,大概是幾個PB的量
三、Elasticsearch(ES)原理
因為篇目有限,本篇只介紹ES的索引原理,
ES為什么可以做全文搜索,主要就是用了倒排索引,先來看下面的一張圖

看圖可以簡單的理解倒排索引就是:關鍵字 + 頁碼
對倒排索引有個基本的認識后,下面來做個簡單的資料例子,

現在對Name做到排索引,記住:關鍵字 + ID(頁碼),

對Age做到排索引,

對Intersets做到排索引,

現在搜索Age等于18的,通過倒排索引就可以快速得到1和3的id,再通過id就可以得到具體資料,看,這樣是不是快的狠,
如果是用Mysql等關系資料庫,現在有十多億資料(大資料嘛),就要一條一條的掃描下去找id,效率可想而知,而用倒排索引,找到所有的id就輕輕松松了,
在ES中,關鍵詞叫Term,頁碼叫Posting List,
但這樣就行了嗎? 如果Name有上億個Term,要找最后一個Term,效率豈不是還是很低?
再來看Name的倒排索引,你會發現,將Armani放在了第一個,Tyloo放在了第三個,可以看出來,對Term做了簡單的排序,雖然簡單,但很實用,這樣查找Term就可以用二分查找法來查找了,將復雜度由n變成了logn,
在ES中,這叫Term Dictionary,
到這里,再來想想MySQL的b+tree, 你有沒有發現原理是差不多的,那為什么說ES搜索比MySQL快很多,究竟快在哪里? 接下來再看,
有一種資料結構叫Trie樹,又稱前綴樹或字典樹,是一種有序樹,這種資料結構的好處就是可以壓縮前綴和提高查詢資料,
現在有這么一組Term: apps, apple, apply, appear, back, backup, base, bear,用Trie樹表示如下圖,

通過線路路徑字符連接就可以得到完成的Term,并且合用了前綴,比如apps, apple, apply, appear合用了app路徑,節省了大量空間,
這個時候再來找base單詞,立即就可以排除了a字符開頭的單詞,比Term Dictionary快了不知多少,
在ES中,這叫Term Index
現在我們再從整體看下ES的索引

先通過Trie樹快速定位block(相當于頁碼), 再到Term Dictionary 做二分查找,得到Posting List,
索引優化
ES是為了大資料而生的,這意味著ES要處理大量的資料,它的Term資料量也是不可想象的,比如一篇文章,要做全文索引,就會對全篇的內容做分詞,會產生大量的Term,而ES查詢的時候,這些Term肯定要放在記憶體里面的,
雖然Trie樹對前綴做了壓縮,但在大量Term面前還是不夠,會占用大量的記憶體使用,于是就有ES對Trie樹進一步演化,
FST(Finite State Transducer )確定無環有限狀態轉移器 (看下圖)

可以看appear、bear 對共同的后綴做了壓縮,
Posting List磁盤壓縮
假設有一億的用戶資料,現在對性別做搜索,而性別無非兩種,可能"男"就有五千萬之多,按int4個位元組存盤,就要消耗50M左右的磁盤空間,而這僅僅是其中一個Term,
那么面對成千上萬的Term,ES究竟是怎么存盤的呢?接下來,就來看看ES的壓縮方法,
**Frame Of Reference (FOR) 增量編碼壓縮,將大數變小數,按位元組存盤 **
只要能把握“增量,大數變小數,按位元組存盤”這幾個關鍵詞,這個演算法就很好理解,現在來具體看看,
現在有一組Posting List:[60, 150, 300,310, 315, 340], 按正常的int型存盤,size = 6 * 4(24)個位元組,
-
按增量存盤:60 + 90(150)+ 150(300) + 10(310) + 5(315)+ 25(340),也就是[60, 90, 150, 10, 5, 25],這樣就將大數變成了小數,
-
切分成不同的block:[60, 90, 150]、[10, 5, 25],為什么要切分,下面講,
-
按位元組存盤:對于[60, 90, 150]這組block,究竟怎么按位元組存盤,其實很簡單,就是找其中最大的一個值,看X個位元能表示這個最大的數,那么剩下的數也用X個位元表示(切分,可以盡可能的壓縮空間),
[60, 90, 150]最大數150 < 2^8 = 256,也就是這組每個數都用8個位元表示,也就是 3*8 = 24個位元,再除以8,也就是3個位元組存在,再加上一個8的標識位(說明每個數是8個位元存盤),占用一個位元組,一共4個位元組,
[10, 5, 25]最大數25 < 2^5 = 32,每個數用5個位元表示,3*5=15位元,除以8,大約2個位元組,加上5的標識位,一共3個位元組,
那么總體size = 4 + 3(7)個位元組,相當于24個位元組,大大壓縮了空間,
再看下圖表示

Posting List記憶體壓縮
同學們應該都知道越復雜的演算法消耗的CPU性能就越大,比如常見的https,第一次互動會用非對稱密碼來驗證,驗證通過后就轉變成了對稱密碼驗證,FOR同樣如此,那么ES是用什么演算法壓縮記憶體中的Posting List呢?
Roaring Bitmaps 壓縮位圖索引
Roaring Bitmaps 涉及到兩種資料結構 short[] 、bitmap,
short好理解就是2個位元組的整型,
bitmap就是用位元表示資料,看下面的例子,
Posting List:[1, 2, 4, 7, 10] -> [1, 1, 0, 1, 0, 0, 1,0, 0, 1],取最大的值10,那么就用10個位元表示這組Posting List,第1, 2, 4, 7, 10位存在,就將相對應的“位”置為1,其他的為0,
但這種bitmap資料結構有缺陷,看這組Posting List: [1, 3, 100000000] -> [1, 0, 1, 0, 0, 0, …, 0, 0, 1 ],最大數是1億,就要1億的位元表示,這么算下來,反而消耗了更多的記憶體,
那如何解決這個問題,其實也很簡單,跟上面一樣,將大數變成小數,
看下圖:

第一步:將每個數除以65536,得到(商,余數),
第二步:按照商,分成不同的block,也就是相同的商,放在同一個block里面,余數就是這個值在這個block里面的位置(永遠不會超過65536,余數嘛),
第三步:判斷底層block用什么資料結構存盤資料,如果block里面的余數的個數超過4096個,就用short存盤,反之bitmap,
上面那個圖是官網的圖,看下我畫的圖,可能更好理解些,

到這里,ES的索引原理就講完了,希望大家都能理解,
四、Elasticsearch(ES)相對薄弱的地方
1. 多表關聯
其實ES有一個很重要的特性這里沒有介紹到,也就是分布式,每一個節點的資料和,才是整體資料,
這也導致了多表關聯問題,雖然ES里面也提供了Nested& Join 方法解決這個問題,但這里還是不建議用,
那這個問題在實際應用中應該如何解決? 其實也很簡單,裝換思路,ES無法解決,就到其他層解決,比如:應用層,用面向物件的架構,拆分查詢,
2. 深度分頁
分布式架構下,取資料便不是那么簡單,比如取前1000條資料,如果是10個節點,那么每個節點都要取1000條,10個節點就是10000條,排序后,回傳前1000條,如果是深度分頁就會變的相當的慢,
ES提供的是Scroll + Scroll_after,但這個采取的是快取的方式,取出10000條后,快取在記憶體里,再來翻頁的時候,直接從快取中取,這就代表著存在實時性問題,
來看看百度是怎么解決這個問題的,

一樣在應用層解決,翻頁到一定的深度后,禁止翻頁,
3. 更新應用
頻繁更新的應用,用ES會有瓶頸,比如一些游戲應用,要不斷的更新資料,用ES不是太適合,這個看大家自己的應用情況,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/44382.html
標籤:大數據
