前言:
寫在最前面的話,土豪以及資料中心提供統一服務的朋友基本可以無視,看看熱鬧就好,畢竟能用錢解決的問題都不是問題
需求來源:
由于各種原因,包含但不限于資訊安全,方便管理,資料重用等原因,相當一部分的大資料業務產品需要進行本地化或者私有化部署,此時除了技術開銷(產品成本)外,硬體開銷也會成為一個頭等大事,成為很多專案的重要考慮因素,所以在功能以及性能表現差不多的情況下,硬體成本更低成為產品競爭力的一個重要因素,
拆分成專業術語,上述需求其實就是記憶體,硬碟,CPU以及帶寬資源的降低與優化,在當前大資料平臺性能嚴重依賴記憶體的時代(尤其是非計算密集型或者沒有機器學習或者深度學習的前提下),記憶體資源幾乎是無法削減的,除非以犧牲性能為代價,所以優化的重點將從CPU.硬碟以及帶寬上下手,如果記憶體有富余,盡量用記憶體去置換其他資源,從而達到性能最大化
設計方案:
平臺現狀:
公司內部是elasticsearch,hbase以及redis的重度使用者,考慮到抓大放小,立竿見影的目標,而redis幾乎只靠記憶體,所以硬碟以及CPU的優化目標就只有拿elasticsearch和hbase開刀了,帶寬毫無疑問只能拿傳輸的訊息開刀了,下面就從CPU,硬碟以及帶寬來進行分開描述,
具體實作:
CPU:
提高CPU資源使用率:
對于絕大多數非計算密集型的大資料平臺來說,CPU在標配的服務器上一般都是富余資源,所以可以考慮使用CPU資源去置換其他資源,提高CPU使用率,
具體方案如下:
- CPU置換硬碟資源:對存盤的資料進行Compression和Encoder,正巧elasticsearch和hbase(幾乎所有的資料庫)都支持,那就搞起吧,具體的實施原則下面介紹,這里先提一嘴
- CPU置換帶寬資源:對傳輸的資料選取高性能的Serialize和DeSerialize,也有助于降低帶寬資源,同樣下面具體介紹
減少CPU空閑量:
- 兼顧CPU密集型應用和非CPU密集型應用的混合使用,使CPU資源充分利用,較少空閑量
- 針對部分場景下,如Hadoop主節點或者HBase的主節點,如果沒用來存盤資料,則節點負載理論上不會太高,在保證組件穩定性的前提下可以在該節點上部署部分應用來充分利用CPU以及其他資源
硬碟:
資料庫資料滾動存盤:
大資料的特點就是資料量大,但是單位資料的價值比較低,在正常的業務條件下,可以保持一定時間內的明細資料,如半年或者一年,其余的資料在經過統計分析后可以進行轉儲或者直接洗掉,畢竟很多情況下,我們不會關心幾年前發生的一條明細資料的情況,
針對這種場景,hbase以及elasticsearch中的資料可以設計滾動存盤,只保留最近一段時間內的資料,elasticsearch可以通過curator或者定時任務來進行資料清理;hbase可以通過ttl或者定時任務來清理資料
使用壓縮以及編碼策略:
壓縮以及編碼策略是資料庫節省硬碟資源的常規操作,有的默認開啟了,有的未開啟,有的可以優化,針對hbase以及elasticsearch有如下方案:
- Elasticsearch使用best_compression壓縮,默認情況下Elasticsearch使用的是lz4壓縮,理想情況下,使用best_compression能節省大概15%-25%的存盤,但是由于壓縮只作用于source欄位,所以如果禁用了source欄位或者Field的索引量比較大,則壓縮效果會大打折扣,具體以實際測驗資料為準
- 對于HBase,可以使用compression和encoder,具體參見這里HBase資料壓縮 Column family Compress & Data Block Encoding
優化存盤結構:
對于Elasticsearch來說,可以開箱即用,不建立索引也可以通過資料分析來創建索引和存盤資料;對于HBase來說,由于是無shema的結構(表的配置只到列族一級),所以可以隨便擴展列,這些功能再給我們帶來很大便利,降低使用成本的前提下,也帶來了巨大開銷的代價,所以自定義存盤方案,優化存盤結構成為提高性能,降低硬體開銷的一個重大突破口,具體操作如下:
- Elasticsearch對不必要的特性進行禁用,這個內容比較多,大家可以自行在網上學習,如果需要的話,我找個時間再整理一篇檔案,舉兩個例子來說明:對于一個String型別的欄位,如果不需要分詞,則將field型別設定為keyword代替text;對于int型的值,如果不需要進行大小比對,僅僅是精確查詢,則將field型別設定為keyword代替number型別,總而言之,禁用一切不需要的屬性和索引
- 在不影響查詢的前提下,減少HBase列的個數,對關聯性較大的欄位進行統一存盤,因為對于hbase來說,底層都是存盤cell的,每多一列,rowkey,columnFamily,timestamp等都需要冗余存盤一份,所以對于關聯性較大的列建議統一存盤到一列,用json,二進制物件或者protocolbuffer進行處理
帶寬:
帶寬資源相比上面服務器資源的一次性投入,是一個持續投入的資源,對于某些資料量較大,資料敏感需要使用專線的場景,帶寬費用一年動輒幾十萬甚至上百萬,確實很嚇人,哪怕在當今帶寬費用已經大幅削減的前提下,費用也是不菲的,所以針對上述情況,設計下面的兩套方案進行帶寬資源的削減:
使用碼表轉換減小訊息體:
對于訊息中重復率較高,欄位體較大的部分,可以使用碼表進行編碼轉換的方式進行傳輸,傳輸程序中使用轉換了的編碼,在server端和client端存放解碼字典進行解碼,
對于部分固定型別的欄位,如ip,date,time,位置資訊等欄位,可以轉換成int或者其他更小的訊息體來進行傳輸,在兩端進行編解碼,
選用高效的序列化和反序列化演算法:
序列化和反序列化對于網路傳輸來說是必需的,但是序列化和反序列化的演算法確實可以優化的,筆者絕大部分使用的java,所以默認的序列化和反序列演算法是java自帶的defaultXXX的序列化和反序列演算法,這個演算法不需要額外實作或者處理就可以使用,但是缺點是性能和效果是真心的差,建議使用高效的序列化和反序列演算法,在這里筆者建議使用kyro或者protocol Buffer,大體介紹下兩者的優缺點和應用場景:
- kyro很快,壓縮比很高,spark默認就是用kyro進行序列化和反序列化,但是缺點就是不兼容變化,如果元資料發生增量變化,則kyro無法進行決議,所以針對物體固定,幾乎不會發生變化的場景,kyro是個很好的選擇
- protocol Buffer是google出品,所以對性能不需要有任何擔心,而且可以做到兼容增量變化,但是缺點是需要手動維護一個元資料的proto檔案,序列化和反序列化需要依賴該proto檔案生成的物體檔案,所以針對物體不固定,需要增量更新的場景,protocol Buffer是個很好地選擇
具體的技術選型請大家自行學習,
結語:
降低硬體和帶寬資源就和系統性能優化一樣,總是永無止境的,所謂性能優化一時爽,一直優化一直爽,所以大家可以根據自己的實際需求進行選取,達到一個點即可,凡事都講投入產出比,性能優化亦是如此,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/171982.html
標籤:其他
