1. 程式人生 > >Keep Thinking And Learning

Keep Thinking And Learning

背景

    最近有個簡單的需求,離線資料探勘得出的標籤需要支援online的查詢,查詢場景比較簡單,支援按照單個id或者多個id批量查詢,tp99需要在200ms,批量的時候id 集合的大小不會超過1000,平均下來不會超過200的樣子。這種場景直接上ES相對來說比較省事,不過ES佔用資源較多,想嘗試用hbase來解決這種場景,下面記錄下具體的過程。

     為何要考慮HBase?

    為何要用hbase呢?離線資料是存放在hive表裡面的,雖然hbase匯入hbase和es都挺方便的,不過據我們測試的情況看,hive2hbase採用bulkload 的方式會快些,而且比較簡單。匯入es的過程中步驟繁瑣,需要設定重新整理時間和副本數,設定段合併和別名之類的操作,相對來說麻煩許多。hbase按照 rowkey查詢的效能還行,單次查詢在10+ms左右,雖然支援索引,不過效能差強人意,暫時不準備利用其自身的索引。 只利用hbase來儲存元資訊,這些資訊相對來說比較佔空間,僅支援按照 rowkey來查詢。

     HBase的若干問題

  1. rowkey的設計,這個關係到資料是否分佈均勻,一般根據業務場景強相關,我們這個就是按照id來設計的查詢,前期考慮根據id的首個數字來進行劃分,後來發現 region server 存在嚴重的熱點問題,看了下資料才發現,我們的id是子增的,而且id比較大,主要都落到2,3開頭的region裡面了,對於自增的id可以採用id%n 的方法來劃分,最終採用n=60,最後看了下分佈到每個 regionserver 的資料非常均勻,基本都在410W左右。
  2. 預分割槽可以均衡讀寫壓力,老生常談的問題了
  3. 列可以動態增加,對於每行資料不一樣的應用比較適合,為null的列是不會進行儲存的,這一點很靈活
  4. 熱點的問題,在均衡了rowkey的設計之後,可以使得訪問請求能均衡的分佈到每個region server,不過從壓測的情況看,資料的rt 波動比較大, 因為blockcache 不是表級別的,全域性的lru比較容易被踢出來,如果被踢出來的話,需要去讀hfile了。
  5. 因為hbase 是按照column family儲存的,其列名是會儲存在keyvalue裡面的,比較佔用空間,可以簡短一點,另外,讀取資料的過程也是按照column family讀取的,涉及到storeFileScanner的切換,效率會有些影響,不過這塊沒有具體測試過,column family不要超過3個,有時候業務欄位拆分成不同的column family更為合理,不過對效能的影響需要再深入測試。 
  6. 我們的業務場景是所有資料都要輪一遍,所以blockcache對我們沒啥用,從壓測的結果看200 個 id的情況下,tp99在270ms,對staging進行測試,同機房內,qps也就40多,這個結果比較慘。
  7. 對線上機器進行了觀察,發現hbase的region server的memory 和heap使用率都挺高的,比ES的機器配置要高很多了,不符合花小錢搞事情的原則。

    丟不掉的ES

    在對hbase進行測試之後,id超過200之後,hbase效能直線下降,很難符合線上的要求了,只能再轉回ES了。事實上,在使用hbase之前,我們設想是通過es+hbase或者es+tair來進行對比,這兩種場景因為對索引和資料進行了拆分,效能很難和直接利用es進行查詢相比,最後轉了個圈,還是回到ES上面了,索引資訊儲存在es裡面,由於es儲存的資訊極其簡單,2.5億的記錄索引,經過優化儲存,只佔用了9G的空間,200個id查詢的 rt 也就30ms左右,效能還是比較穩定的。ES的優點如下:
  1. es叢集還是比較可靠的,效能槓槓的,之前想著節省資源的情況下用用hbase,不過hbase的blockcache 也不小,es雖然是虛機,單臺只有8G,但還是比較穩定的
  2. es可以通過disable source, 只index而不 store,啟用best compress (可以省 1/3 的空間)  等達到最大利用率
  3. es  的吞度量還是不錯的,同樣的壓測,qps是hbase的4倍,rt只有hbase的一半不到。

    ES的問題

  1.  ES做簡單的查詢還行,不過要小心返回結果可能並不是你所想的,es 為了提升檢索效率,有些地方是用的近似值,用集合查詢的時候,from to 下,會受限制與window size 的大小,有時候返回的結果不穩定而且不全,這個測試的時候發現了,還是比較坑的。
  2. filter方式因為不計算score和存在快取的方式,效能一般情況下是ok的,不過據壓測情況看,filter的tp90雖然比query快了大概10ms,但是tp99 的曲線波動的很厲害,遠不如query 的tp99平穩,說明效能是有較大的波動的
  3.  根據2做了些研究,es的cache是基於node級別的,有query和filter的cache,query只快取count型別的查詢,filter快取採用lru機制,會根據filter條件做快取,採用的是bitset,既然是lru,肯定會有換入換出,懷疑是抖動的原因,如果有大牛知道,歡迎指正。
    一般做系統方案的時候,還是需要根據具體業務場景來區分,複雜不一定好,皮實耐用才是真道理,根據具體場景來做優化,有時候也能收到意想不到的效果。