標籤:應用 複雜 定址 預設 mit sql com 不能 介紹
摘要
從底層介紹Elasticsearch Shard的內部原理,以及回答為什麼使用Elasticsearch有必要瞭解Lucene的內部工作方式?
瞭解Elasticsearch API的代價
- 構建快速的搜尋應用
- 不要任何時候都commit
- 何時使用Stored Fields和Document Values
- Lucene可能不是一個合適的工具
瞭解索引的儲存方式
- term vector是索引大小的1/2
- 我移除了20%的檔案,但是索引佔用空間並未發生任何變化
版本
elasticsearch版本: elasticsearch-2.2.0
內容索引
毫不誇張的說,如果不瞭解Lucene索引的工作方式,可以說完全不瞭解Lucene,對於Elasticsearch更是如此。
建立索引
以兩個簡單的檔案為例:Lucene in action和Databases。
假設Lucene in action裡有單詞
{index, term, data, Lucene}
Databases裡有單詞
{sql, index, data}
- 樹形結構(Tree structure)
對於range query有序
查詢的時間複雜度為O(log(n))
一般的關係型資料庫大致結構可能是上面這樣的一顆B、B+樹,但是Lucene是另外一種儲存結構。
- 倒排索引(或反向索引Inverted Index)
對於Lucene來說,其主要的儲存結構是一個反向索引,它是一個數組,數組裡面是一個有序的資料字典。
這樣一個儲存結構存在與Lucene的Segment裡。
- term ordinal —— 是一個詞的序號
- term dict —— 是詞的內容
- postings list —— 存放包含詞的檔案的id序列
- doc id —— 是每個檔案的唯一標識
- document —— 存放每個檔案的內容
這兩種結構的一個重要區別是:在增加或刪除檔案時,系統會樹形結構頻繁操作,這個結構是一直變化的,而反向索引可以維持不變(Immutable)。
- 插入?
- 刪除?
- 刪除要做的只是置一個標誌位
- 搜尋及merge的時候系統會忽略被刪除的檔案
- 當有很多刪除發生時,系統會自動運行merge
- 被標記為已刪除的檔案會在merge完成後回收其所佔用的儲存空間
- 孰優孰劣?
- Lucene Index的強大之處(Index intersection)
很多資料庫不支援同時使用多個索引,但是Lucene支援
關於詳細的index intersection演算法以及如何使用skip list的可以參照(nlp.standford.edu)
更多索引
- 術語向量(Term vectors)
- 為每個檔案都會建立一個反向索引(Inverted Index)
- 適用情境:搜尋更相似的內容
- 也可以用作高亮搜尋結果
- 檔案值(Document Values)
- 以檔案欄位為單位進行列式儲存
- 適用情境:排序、權重記分
- 有序(集合)檔案值
- 分面搜尋(Faceting)
分面是指事物的多維度屬性。例如一本書包含主題、作者、年代等分面。而分面搜尋是指通過事物的這些屬性不斷篩選、過濾搜尋結果的方法。可以將分面搜尋看成搜尋和瀏覽的結合。分面搜尋作為一種有效搜尋方式,已經被用在電子商務、音樂、旅遊等多個方面。
例如,Google音樂的挑歌頁面,將歌曲分為節奏、聲調、音色、年代、流派等分面
根據檔案與搜尋匹配的情況計數
- 例如,電商網站根據衣服的款式、衣長、尺碼、顏色等分面。
簡單(naive)方案
- 利用雜湊表計數(value to count)
- O(#docs) ordinal 尋找
- O(#doc) value 尋找
Lucene方案
- 雜湊表(ord to count)
- 最後統計值
- O(#docs) ordinal 尋找
- O(#values) value 尋找
因為ordinal是密集的,所以可以簡單用數組array來表示。
- 如何使用API?
Elasticsearch進階API 都是基於Lucene API構建的,這些基礎的API包括:
----------------------------------------------------------------------------------------------- API | 用途 | 方法----------------------------------------------------------------------------------------------- Inverted index | Term -> doc ids, positions, offsets | AtomicReader.fields----------------------------------------------------------------------------------------------- Stored fields | Summaries of search results | IndexReader.document----------------------------------------------------------------------------------------------- Live docs | Ignoring deleted docs | AtomicReader.liveDocs----------------------------------------------------------------------------------------------- Term vectors | More like this | IndexReader.termVectors----------------------------------------------------------------------------------------------- Doc values/Norms | Sorting/faceting/scoring | AtomicReader.get*Values-----------------------------------------------------------------------------------------------
- 小結
檔案格式的秘密
- 不能忘的規則
儲存檔案的控制代碼
不要為每個欄位每個檔案使用檔案
避免磁碟定址
磁碟定址的時間大概為~10ms
不要忽略檔案系統的緩衝
隨機訪問小檔案還是可以的
使用輕壓縮
- 編碼解碼
- 合適的壓縮技術
- TermQuery的背後
Terms Index
在索引中尋找相應的詞
- 在記憶體中FST儲存了詞的首碼prefix
- 提供詞在字典中的位移量
- 在不存在時可以快速失敗
Terms Dictionary
Postings List
Stored Fields
對一個子集的doc id,索引存於記憶體中
高效記憶體(monotonic)壓縮
二分尋找
欄位
順序儲存
使用16KBBlock Storage壓縮
- 查詢過程小結
效能
中系統效能出現兩次下降,可能的情況是
索引增長超過檔案系統快取的大小
Stored Fields不再全部儲存於緩衝中
Terms dict/Postings lists不全在緩衝中
參考
參考來源:
SlideShare: What is in a Lucene index?
Youtube: What is in a Lucene index? Adrien Grand, Software Engineer, Elasticsearch
SlideShare: Elasticsearch From the Bottom Up
Youtube: Elasticsearch from the bottom up
Wiki: Document-term matrix
Wiki: Search engine indexing
Skip list
Standford Edu: Faster postings list intersection via skip pointers
分面搜尋(Faceted Search)
StackOverflow: how an search index works when querying many words?
StackOverflow: how does lucene calculate intersection of documents so fast?
Lucene and its magical indexes
結束
Elasticsearch 2 (10) - 在Elasticsearch之下(深入理解Shard和Lucene Index)