財務平臺億級數據量毫秒級查詢優化之elasticsearch原理解析

說在前面mysql

財務平臺進行分錄分表之後,隨着數據量的日漸遞增,業務人員對帳務數據的實時分析響應時間愈來愈長,體驗性慢慢降低,以前咱們基於mysql的性能優化作了一遍,能夠說基於mysql該作的優化已經基本上都作了,本次是基於elasticsearch對其作進一步的性能優化算法

 

正文sql

mysql索引原理數據庫

基於mysql最經常使用也最直接有效的性能優化也就是添加索引。json

 

mysql索引是怎麼實現的呢?數據庫最基本的查詢算法是順序查找,時間複雜度爲O(n),顯然在數據量很大的時候很低,優化的查詢算法有二分查找,二叉樹查找,雖然查找效率提升了,可是各自對檢索的數據都有要求,二分查找檢索被要求數據是有序的,而二叉樹查找只能用於二叉樹上,可是數據自己的組織結構不可能徹底知足各類數據結構,例如,理論上不可能同時將兩列都按順序進行組織,因此在數據以外,數據庫系統還維護者知足特定查找算法的數據結構,這些數據結構以某種方式引用數據,這樣就能夠在這些數據結構上實現高級查找算法,這種數據結構就是索引。數組

 

索引是什麼?索引是存儲引擎用於快速找到記錄的一種數據結構,這是索引的基本功能,主要基於hash,b+tree。緩存

 

咱們開發當中通常用到都是mysql innoDB引擎,採用的是b+tree。性能優化

 

b+tree的優點主要體如今查詢性能上,在單元素查詢時,b+tree會自頂層向下逐層查找節點,最終找到咱們須要的葉子節點,範圍查詢時,b+tree找到葉子節點的起始位置,經過葉子節點鏈表依次查詢數據,直到範圍結束爲止。服務器

 

參考上面的示意圖數據結構

 

總結:基於b+tree的mysql索引,當這個樹的形狀瘦低的時候查詢效率就會很快,由於查找磁盤的io次數不多,可是若是這個樹的形狀胖高的時候,查詢磁盤的次數就會比較多,那麼查詢效率就會愈來愈慢,因此基於mysql索引的性能優化,索引是有限制的,適量的添加索引會對查詢效率有明顯提高,可是索引過量就拔苗助長,不但查詢效率會下降,也會影響其餘操做的效率,由於其餘操做的時候也是須要維護索引的。

 

elasticsearch索引原理

elasticsearch底層是索引原理是倒排索引,使用場景通常是OLAP,支持rest風格json數據格式交互的全文檢索引擎,開源,面向文檔設計,實時檢索,索引能夠無限擴展,只要你的服務器的磁盤、內存足夠大。

 

咱們先看一個列子

 

一個字段有一個本身的倒排索引。18,20這些叫作term,而[1,3]就是postinglist。Posting list就是一個int的數組,存儲了全部符合某個term的文檔id。

 

term Dictionary

term排序後的集合,方便二分查找,有了term Dictionary以後就能夠在磁盤上查找到具體的document,磁盤的讀操做很是昂貴,一次大概須要10ms時間,不一樣存儲方式的磁盤性能不同,因此爲了減小磁盤的讀取次數就必要把一些數據緩存到內存中,可是term Dictionary會有不少,不能完整的放到內存中,因而就有了termindex

term index

能夠理解爲就是英文詞典的目錄,它是一棵樹的結構

 

示意圖

 

 

這棵樹不會包含全部的term,它只包含term的一些前綴,經過term index能夠快速地定位到term dictionary的某個offset,而後從這個位置再日後順序查找,大大減小了磁盤訪問次數

 

示意圖

 

 

因此term index不須要存下全部的term,而僅僅是他們的一些前綴與Term Dictionary的block之間的映射關係,再結合FST(Finite StateTransducers)的壓縮技術,可使term index緩存到內存中

爲何elasticsearch比mysql快

mysql只有 termdictionary這一層,是以樹的方式存儲在磁盤上的。檢索一個term須要若干次的磁盤訪問操做,而elasticsearch,在term dictionary的基礎上添加了term index來加速檢索,term index以樹的形式緩存在內存中。從term index查到對應的term dictionary的block位置以後,再去磁盤上找term,大大減小了磁盤的訪問次數。

term index在內存中是以FST的形式保存的,其特色是很是節省內存。Term dictionary在磁盤上是以分block的方式保存的,一個block內部利用公共前綴壓縮,好比都是Ab開頭的單詞就能夠把Ab省去。這樣term dictionary能夠更節約磁盤空間。

壓縮技術

用FST壓縮term index以外,對posting list也有壓縮。

 

聯合索引查詢

以上都是單field索引,若是多個field索引的聯合查詢,好比查詢age=18 AND gender=女,倒排索引如何知足快速查詢的要求呢?大體過程以下:根據過濾條件 age=18 的先從term index找到18在term dictionary的大概位置,而後再從term dictionary裏精確地找到18這個term,而後獲得一個posting list或者一個指向posting list位置的指針。而後再查詢gender=女的過程也是相似的。最後得出age=18 AND gender=女,就是把兩個 posting list作一個「與」的合併

一、skip list

二、bitset  二進制,直接按位與

總結

elasticsearch就是儘可能將磁盤裏的東西搬進內存,減小磁盤隨機讀取次數(同時也利用磁盤順序讀特性),結合各類壓縮算法,高效使用內存,從而達到快速搜索的目的。

 

mysql索引與elasticsearch索引對比

mysql

     若是數據量不是特別大,在千萬級別,適當的管理好索引,查詢效率仍是能夠的,可是對索引命中率有要求,就是必需要保證索引的命中率,還有就是索引的數量限制好,可是查詢條件比較多、須要添加不少索引的時候mysql索引就有瓶頸了。

 

elasticsearch

     使用了OLAP場景,海量數據實時查詢,億級以上數據量,由於底層採用的是倒排索引機制,只要你的服務器資源足夠好,理論上隨着數據量的增長、索引的增量,實時查詢效率是線性的。

 

說到最後

 

本次解析僅表明我的看法,僅供參考。

相關文章
相關標籤/搜索