背景
最近有個簡單的需求,離線數據挖掘得出的標籤需要支持online的查詢,查詢場景比較簡單,支持按照單個id或者多個id批量查詢,tp99需要在200ms,批量的時候id 集合的大小不會超過1000,平均下來不會超過200的樣子。這種場景直接上ES相對來說比較省事,不過ES佔用資源較多,想嘗試用hbase來解決這種場景,下面記錄下具體的過程。
爲何要考慮HBase?
HBase的若干問題
- rowkey的設計,這個關係到數據是否分佈均勻,一般根據業務場景強相關,我們這個就是按照id來設計的查詢,前期考慮根據id的首個數字來進行劃分,後來發現 region server 存在嚴重的熱點問題,看了下數據才發現,我們的id是子增的,而且id比較大,主要都落到2,3開頭的region裏面了,對於自增的id可以採用id%n 的方法來劃分,最終採用n=60,最後看了下分佈到每個 regionserver 的數據非常均勻,基本都在410W左右。
- 預分區可以均衡讀寫壓力,老生常談的問題了
- 列可以動態增加,對於每行數據不一樣的應用比較適合,爲null的列是不會進行存儲的,這一點很靈活
- 熱點的問題,在均衡了rowkey的設計之後,可以使得訪問請求能均衡的分佈到每個region server,不過從壓測的情況看,數據的rt 波動比較大, 因爲blockcache 不是表級別的,全局的lru比較容易被踢出來,如果被踢出來的話,需要去讀hfile了。
- 因爲hbase 是按照column family存儲的,其列名是會保存在keyvalue裏面的,比較佔用空間,可以簡短一點,另外,讀取數據的過程也是按照column family讀取的,涉及到storeFileScanner的切換,效率會有些影響,不過這塊沒有具體測試過,column family不要超過3個,有時候業務字段拆分成不同的column family更爲合理,不過對性能的影響需要再深入測試。
- 我們的業務場景是所有數據都要輪一遍,所以blockcache對我們沒啥用,從壓測的結果看200 個 id的情況下,tp99在270ms,對staging進行測試,同機房內,qps也就40多,這個結果比較慘。
- 對線上機器進行了觀察,發現hbase的region server的memory 和heap使用率都挺高的,比ES的機器配置要高很多了,不符合花小錢搞事情的原則。
丟不掉的ES
- es集羣還是比較可靠的,性能槓槓的,之前想着節省資源的情況下用用hbase,不過hbase的blockcache 也不小,es雖然是虛機,單臺只有8G,但還是比較穩定的
- es可以通過disable source, 只index而不 store,啓用best compress (可以省 1/3 的空間) 等達到最大利用率
- es 的吞度量還是不錯的,同樣的壓測,qps是hbase的4倍,rt只有hbase的一半不到。
ES的問題
- ES做簡單的查詢還行,不過要小心返回結果可能並不是你所想的,es 爲了提升檢索效率,有些地方是用的近似值,用集合查詢的時候,from to 下,會受限制與window size 的大小,有時候返回的結果不穩定而且不全,這個測試的時候發現了,還是比較坑的。
- filter方式因爲不計算score和存在緩存的方式,性能一般情況下是ok的,不過據壓測情況看,filter的tp90雖然比query快了大概10ms,但是tp99 的曲線波動的很厲害,遠不如query 的tp99平穩,說明性能是有較大的波動的
- 根據2做了些研究,es的cache是基於node級別的,有query和filter的cache,query只緩存count類型的查詢,filter緩存採用lru機制,會根據filter條件做緩存,採用的是bitset,既然是lru,肯定會有換入換出,懷疑是抖動的原因,如果有大牛知道,歡迎指正。