索引

Hermes與開源的Solr、ElasticSearch的不一樣

談到Hermes的索引技術,相信不少同窗都會想到Solr、ElasticSearch。Solr、ElasticSearch在真可謂是大名鼎鼎,是兩個頂級項目,最近有些同窗常常問我,「開源世界有Solr、ElasticSearch爲何還要使用Hermes?」java

在回答這個問題以前,你們能夠思考一個問題,既然已經有了Oracle、Mysql等數據庫爲何你們還要使用ES下的Hive、Spark? Oracle和Mysql也有集羣版,也能夠分佈式,那ES與Hive的出現是否是多餘的?
    Hermes的出現,並非爲了替代Solr、ES的,就像Hadoop的出現並非爲了幹掉Oracle和Mysql同樣。而是爲了知足不一樣層面的需求。sql

1、Hermes與Solr,ES定位不一樣

Solr\ES :偏重於爲小規模的數據提供全文檢索服務;Hermes:則更傾向於爲大規模的數據倉庫提供索引支持,爲大規模數據倉庫提供即席分析的解決方案,並下降數據倉庫的成本,Hermes數據量更「大」。數據庫

u Solr、ES的使用特色以下:多線程

1. 源自搜索引擎,側重搜索與全文檢索。併發

2. 數據規模從幾百萬到千萬不等,數據量過億的集羣特別少。
    Ps:有可能存在個別系統數據量過億,但這並非廣泛現象(就像Oracle的表裏的數據規模有可能超過Hive裏同樣,但須要小型機)。分佈式

u Hermes:的使用特色以下:高併發

1. 一個基於大索引技術的海量數據實時檢索分析平臺。側重數據分析。oop

2. 數據規模從幾億到萬億不等。最小的表也是千萬級別。性能

在 騰訊17 臺TS5機器,就能夠處理天天450億的數據(每條數據1kb左右),數據能夠保存一個月之久。大數據

2、Hermes與Solr,ES在技術實現上也會有一些區別

u Solr、ES在大索引上存在的問題:

1. 一級跳躍表是徹底Load在內存中的。

這種方式須要消耗不少內存不說,首次打開索引的加載速度會特別慢.

在Solr\ES中的索引是一直處於打開狀態的,不會頻繁的打開與關閉;

這種模式會制約一臺機器的索引數量與索引規模,一般一臺機器固定負責某個業務的索引。

2. 爲了排序,將列的所有值Load到放到內存裏。

排序和統計(sum,max,min)的時候,是經過遍歷倒排表,將某一列的所有值都Load到內存裏,而後基於內存數據進行統計,即便一次查詢只會用到其中的一條記錄,也會將整列的所有值都Load到內存裏,太浪費資源,首次查詢的性能太差。

數據規模受物理內存限制很大,索引規模上千萬後OOM是常事。

3. 索引存儲在本地硬盤,恢復難

一旦機器損壞,數據即便沒有丟失,一個幾T的索引,僅僅數據copy時間就須要好幾個小時才能搞定。

4. 集羣規模過小

支持Master/Slave模式,可是跟傳統Mysql數據庫同樣,集羣規模並無特別大的(百臺之內)。這種模式處理集羣規模受限外,每次擴容的數據遷移將是一件很是痛苦的事情,數據遷移時間過久。

5. 數據傾斜問題

倒排檢索即便某個詞語存在數據傾斜,因數據量比較小,也能夠將所有的doc list都讀取過來(好比說男、女),這個doc list會佔用較大的內存進行Cache,固然在數據規模較小的狀況下佔用內存不是特別多,查詢命中率很高,會提高檢索速度,可是數據規模上來後,這裏的內存問題愈來愈嚴重。

6. 節點和數據規模受限

Merger Server只能是一個,制約了查詢的節點數量;數據不能進行動態分區,數據規模上來後單個索引太大。

7. 高併發導入的狀況下, GC佔用CPU過高,多線程併發性能上不去。

    AttributeSource使用了WeakHashMap來管理類的實例化,並使用了全局鎖,不管加了多大的線程,導入性能上不去。

    AttributeSource與NumbericField,使用了大量的LinkHashMap以及不少無用的對象,致使每一條記錄都要在內存中建立不少無用的對象,形成了JVM要頻繁的回收這些對象,CPU消耗太高。

    FieldCacheImpl使用的WeakHashMap有BUG,大數據的狀況下有OOM的風險。

單機導入性能在筆者的環境下(1kb的記錄每臺機器想突破2w/s 很難)

Solr與ES小結

並非說Solr與ES的這種方式很差,在數據規模較小的狀況下,Solr的這種處理方式表現優越,併發性能較好,Cache利用率較高,事實證實在生產領域Solr和ES是很是穩定的,而且性能也很卓越;可是在數據規模較大,而且數據在頻繁的實時導入的狀況下,就須要進行一些優化。

u Hermes在索引上的改進:

1. 索引按需加載

大部分的索引處於關閉狀態,只有真正用到索引纔會去打開;一級跳躍表採用按需Load,並不會Load整個跳躍表,用來節省內存和提升打開索引的速度。Hermes常常會根據業務的不一樣動態的打開不一樣的索引,關閉那些不常用的索引,這樣一樣一臺機器,能夠被多種不一樣的業務所使用,機器利用率高。

2. 排序和統計按需加載

排序和統計並不會使用數據的真實值,而是經過標籤技術將大數據轉換成佔用內存很小的數據標籤,佔用內存是原先的幾十分之一。

另外不會將這個列的所有值都Load到內存裏,而是用到哪些數據Load哪些數據,依然是按需Load。不用了的數據會從內存裏移除。

3. 索引存儲在HDFS中

理論上只要HDFS有空間,就能夠不斷的添加索引,索引規模不在嚴重受機器的物理內存和物理磁盤的限制。容災和數據遷移容易得多。

4. 採用Gaia進行進程管理(騰訊版的Yarn)

數據在HDFS中,集羣規模和擴容都是一件很容易的事情,Gaia在騰訊集羣規模已達萬臺)。

5. 採用多條件組合跳躍下降數據傾斜

若是某個詞語存在數據傾斜,則會與其餘條件組合進行跳躍合併(參考doclist的skip list資料)。

6. 多級Merger與自定義分區

7. GC上進行了一些優化

    本身進行內存管理,關鍵地方的內存對象的建立和釋放java內部本身控制,減小GC的壓力(相似Hbase的Block Buffer Cache)。

    不使用WeakHashMap和全局鎖,WeakHashMap使用不當容易內存泄露,並且性能太差。

    用於分詞的相關對象是共用的,減小反覆的建立對象和釋放對象。

        1kb大小的數據,在筆者的環境下,一臺機器每秒能處理4~8W條記錄.

相關文章
相關標籤/搜索