報表類大數據數據存儲方案和財務數據脫敏

工作需求:

存儲: mysql

數據量: 每月100w~500w

現狀: 當前存儲沒有問題,單月查詢在總表2000w之內,索引優化好,能支撐現有業務

需求:業務比較穩定後業務方有跨月查詢的需求,折中估計每月250w數據,查詢12月,數據量爲3000w,單表數據量突破經驗值2000w常規的索引優化左襟見拙

分析: 分表是是不可行,當前跨月的報表分析結果主要爲一個複雜的查詢,全量聚合操作+子查詢。落地一張聚合表,可以探索但,前端報表篩選條件涉及到各個維度,存在儲存最粗粒度的數據就要犧牲前端篩選條件,是不能接受,存最細單表已預估一年量爲3000w,傳統的調優參數,mysql存儲已經到了天花板,加內存和機械硬盤換固態硬盤?成本太高,不能接受,緩存層思考,預估一些用戶的查詢行爲,比如只允許按季度查詢?這樣按照季度分區,可行,但限制了報表分析能力,可接受但總是糜爛着工程師的妥協。思考過後,能不能從傳統的數據庫轉向分佈式大數據的存儲方案,例如mycat, hive, Hbase, impala。

思考: 傳統數據庫因爲有着數據量小查詢快,而且具備強一致性的鎖機制和事務機制,分析本需求,報表只是單純的供查詢,0事務,不存在加鎖增刪改操作,因爲之前使用mycat的經驗,坑比較多,比如count函數會出現多個分片的結果,所以目標鎖定爲hive,hive的表結構可以和mysql表結構相似,使用也較SQL比較相似。

待解決的問題

  1. 壓測是否滿足查詢的性能問題,跨月數據量已3年數據量預估最大值進行
  2. 財務數據比較敏感,hive的權限問題,打算對相關金額做統一的加密存儲,需要考慮在加密前後進行聚合操作,比如SUM操作數據前後一致性問題

壓測數據

可以看到,我們模擬了三年的數據量,且月數據量爲1000w,全量數據4億多,進行壓力測試。測試結果很喜人,測試效果如下

壓測結果
數據量 複雜查詢耗時
數據量爲6000w,月份爲6個月 4~10s
數據量4億多,月份爲36個月 1分鐘左右

注:此結果是在presto 20個節點下的集羣,且無任務阻塞下進行

如上面壓力測試所得,在月數據大大高於真實業務數據量的情況下,耗時還是可以接受的,由此可見,選擇hive可行

 

數據脫敏加密

大家都知道,財務數據的金額比較敏感,且hive權限這一塊沒有很好的評估,所以針對金額進行加密處理,且加密之後在進行一些sum操作的時候,加密前和加密後能保持經過加密和解密之後保持一個可逆性。

  1. 考慮金額加或者減,或者乘除一個係數(比較簡單也比較容易操作)
  2. 進行加密算法加密

加密算法加密示例如下:

加密算法:AES_ENCRYPT, 解密算法: AES_DECRYPT

轉換函數:HEX, 轉換函數逆向:UNHEX。

新建一張如下測試表

CREATE TABLE `tb_finance_encrypt_test` (
  `goods_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `cost` decimal(11,2) NOT NULL DEFAULT '0.00',
  `cost_encrypt` char(64) NOT NULL DEFAULT '',
  PRIMARY KEY (`goods_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

# 插入測試數據
INSERT INTO `test`.`tb_finance_encrypt_test` ( `cost`,`cost_encrypt`) VALUES 
('100000',HEX(AES_ENCRYPT(100000, 'liuyifan3'))),
('30.53',HEX(AES_ENCRYPT(30.53, 'liuyifan3'))),
('400000000.82',HEX(AES_ENCRYPT(400000000.82, 'liuyifan3'))),
('2.82',HEX(AES_ENCRYPT(2.82, 'liuyifan3'))),
('3',HEX(AES_ENCRYPT(3, 'liuyifan3'))),
('6.78',HEX(AES_ENCRYPT(6.78, 'liuyifan3')));

 

表數據如下

爲什麼用轉換函數HEX,其上可以看出,經過轉換後的cost,可以一直保持在一個32位字符串的格式,便於儲存,AES_ENCRYPT函數返回的是一串二進制的數據,也可以直接存儲,可存爲blob類型。

聚合測試

SELECT SUM(cost), SUM(AES_DECRYPT(UNHEX(cost_encrypt), 'liuyifan3')) FROM `test`.`tb_finance_encrypt_test`;

測試結果如下:

至此數據加密功能要已經解決。補充說明,上面用的函數mysql都自帶,hive中我們的客戶端是用presto進行訪問hive,原生的presto版本不支持上面提到的加密函數和轉換函數。但擴展起來也是相當方便。也可以採用四則運算乘以一個偏移量的操作。

總結:

  1. 對數據事物要求不高,加鎖要求不高,這種直接和頁面進行報表展現的數據量超過2000w的建議直接上hive
  2. 數據安全的思考不僅可以加密脫敏,也可以混如一些干擾數據,這些干擾數據在解密後可以進行條件的過濾
  3. presto是個好東西,用起來
  4. 要敢於嘗試自己技術棧之外的技術,但前提是在線上使用的時候,應該充分考慮和模擬測試自己的一個使用場景

以上爲我在真實業務中遇到問題,和解決問題的思路和方法,供大家參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章