最近換了工做,由於工做的須要,也正好本身想好好研究一下Java這門牛逼的語言,看了一下ElasticSearch和Lucene的源碼,以前歷來沒有寫過也沒有看過Java的東西,因此也算是惡補了一下Java吧,因爲是從C程序員開始的,因此對這種帶虛擬機的語言總有一些偏見,老以爲內存很差控制,因此一直以來都沒有怎麼碰過Java,最近靜下心來好好看了一下Java和相關的源碼,除了感受語言自己囉嗦了一點,仍是不錯的,可是有一點比較受不了就是基本上用vi很難作Java開發,要是沒有IDE的話,感受寫Java有些蛋疼啊。程序員
接下來一段時間會多聊一聊ElasticSearch和lucene相關的,由於最近也在研究這個,先看了Lucene的底層代碼,確實寫得簡潔明瞭,後面有機會會好好寫寫這方面的東西。算法
好了,不閒扯了,今天想說一說搜索引擎或者數據庫中索引(主要是倒排索引)的字典結構,一個好的高效的字典結構直接影響到索引的效果,而索引的構建其實並非徹底追求速度,還有磁盤空間,內存空間等各個因素,因此在一個索引系統中,須要權衡各個關係,找到一種適合你當前業務的數據結構進行存儲。這樣才能發揮索引最大的能效,通常狀況下,對於索引來講(主要是倒排索引)的字典來講,有跳躍表,B+樹,前綴樹,後綴樹,自動狀態機,哈希表這麼幾種數據結構,其實只要是一個快速的查找型的數據結構就能夠用來作索引的字典。數據庫
咱們從簡單的開始,一個一個來講說,今天先說說跳躍表,跳躍表結構很是很是簡單,可是,你真的瞭解它麼?編程
跳躍表是一種簡單,高效的快速查找結構,實現起來成本最小,而且速度也很快,只須要一個圖就能夠完美的解釋跳躍表的樣子,並且對於編程人員來講,要實現一個跳躍表看着圖就能實現,如下就是跳躍表的結構圖,沒有什麼難度。數組
跳躍表有幾個特色,這種特色對於某些類型的查詢是有至關的效率提高的。緩存
在lucene中,跳躍表並無用來存儲字典,而是用來存儲docid鏈,這裏後面咱們說lucene底層和Elasticsearch的時候再說具體結構吧,這篇咱們僅用來討論用跳躍表存字典的狀況。微信
對於跳躍表,咱們看看有一些什麼樣的優化方式可讓其更加適應一些場景。優化的話,咱們通常從空間和時間兩個方面來考慮一個優化,對於空間的話,又分紅內存空間優化和磁盤空間優化,固然通常首先考慮內存的優化,對於時間來講,也分紅構建時間和查詢時間兩個方面來優化,空間和時間是兩個相互矛盾的優化,具體到實際操做上如何取捨就要看具體的場景了。數據結構
可是上圖這種存儲方式不適合動態的增長或者刪除節點,由於一次這樣的更新操做須要操做好幾回磁盤,而且會致使磁盤上各個節點是不連續的,很是影響效率,因此比較適合那種寫入之後就不會變化的跳躍表的狀況。性能
上圖中的底層表示秒,第二層表示分鐘,第一層表示小時,那個紅色的節點表示那一分鐘實際上是沒數據的,爲了把節點數固定下來虛擬出來的節點,這樣能夠提升查詢的效率。優化
上面兩個大類型的優化,其實不少地方是矛盾的,具體取捨的時候就要看你的業務場景了,假設須要用跳躍表來存儲你的主鍵,你的業務場景是更新操做不多,查詢操做主要針對其餘字段而非主鍵的話,那麼底層存磁盤上,上面幾層的數據項也存磁盤上,而且經過LRU或者mmap交換內存和磁盤空間的跳躍表比較適合你。若是用來存儲分詞後的關鍵字的話,由於中文分詞之後關鍵詞的量級通常在幾十萬這個級別,那麼直接載入內存的話也能接受,因此直接加載到內存的方式可能更適合你。
好了,今天先寫這麼多,後面還有不少字典結構能夠優化的,慢慢來講,正好最近本身也在研究索引的優化,能夠留言討論哈,有說得不對的,隨便拍。
若是你以爲不錯,歡迎轉發給更多人看到,也歡迎關注個人公衆號,主要聊聊搜索,推薦,廣告技術,還有瞎扯。。文章會在這裏首先發出來:)掃描或者搜索微信號XJJ267或者搜索西加加語言就行