InnoDB列壓縮,提公升DB效能

2021-07-01 22:50:17 字數 3491 閱讀 5115

案例一:io問題。某遊戲的乙個大區db由於資料量過大,記憶體緩衝池不能完全cache資料,io瓶頸制約db整體效能,導致該大區不能提供穩定服務。

案例二:儲存空間不足。某遊戲的db在合服過程中,由於資料量過大,導致合服效率極低。

對於上述問題,通用的方案或者是公升級硬體,或者是在遊戲server層修改儲存邏輯,代價都很非常大。互娛dba團隊通過在tmysql 1.4版本增加innodb列壓縮功能,對應用層透明並且節省了硬體成本從而有效解決該問題。

列壓縮技術方案與應用

互娛遊戲的後台資料庫經常使用blob/text型別欄位來儲存資料,業務中blob/text型別字段佔據了很大部分的儲存空間,如上述提到的案例二中db中約90%的儲存內容為blob/text型別列。對這些blob/text欄位進行壓縮儲存,將大大降低儲存空間,從而提高db整體效能。

一、列壓縮技術方案

tmysql列壓縮的實現主要包括語法層面、儲存格式、壓縮/解壓邏輯及匯入匯出優化等幾個方面。

1.  列壓縮功能是可配置的,為此在tmysql中增加compressed語法。

2. 儲存格式:列壓縮可以根據欄位的長度來判斷是否使用壓縮儲存,因為對於小資料量,壓縮比不壓縮可能更占用儲存空間。目前,判斷是否壓縮的策略是:如果長度小於256位元組,不壓縮儲存;如果長度大於256位元組,壓縮儲存。壓縮格式為:

首位元組標記:第乙個bit,0表示未壓縮(對應就無解壓後長度),1表示壓縮;第2,3位表示演算法型別(現階段版本只有zlib演算法),第6,7,8位表示有幾個位元組來儲存壓縮長度。

解壓後長度:表示資料在壓縮前或解壓「壓縮的內容」的長度,由於blob欄位約定的最大長度(longblob)是2^32-1,因此4位元組的最大長度已經足夠。另外,1-4位元組的內容分別表示長度上限為2^8-1、2^16-1、2^24-1,2^32-1。該資訊也用於解壓後的記憶體分配。

壓縮的內容:就是壓縮後的資料。

3.  壓縮演算法

當前版本,壓縮和解壓基於mysql內建的zlib(1.2.3)壓縮庫,函式為:my_compress和my_uncompress。

上述定義的格式中,預留了其它型別的演算法標記,後續會結合不同壓縮演算法中cpu開銷與壓縮率來權衡一種更適當的演算法。

4.  壓縮與解壓

壓縮和解壓處理需要在統一的函式呼叫位置,該位置確定在儲存引擎和server資料交換的handler介面中,即

這樣解壓和壓縮都集中在儲存引擎和server間的資料交換介面中,儲存引擎和server的其他處理就不需考慮資料是否壓縮的邏輯,簡化整個問題。

壓縮介面:row_mysql_store_col_in_innobase_format。由server層傳下來的每乙個列的資料,都會經由本函式完成資料轉換(特殊處理索引)。

解壓介面:row_sel_store_mysql_rec。本函式用於將innodb層從物理介質上讀取到的資料傳遞到server層的型別。

5.  匯入匯出優化

匯入匯出優化主要是通過兩方面來實現。首先是在server層增加新的語法select sql_compressed 、insert sql_compressed。在使用selectsql_compressed時,db會略過對壓縮資料的解壓邏輯,直接匯出。

insert sql_compressed與select sql_compressed必須是配套使用的,使用insert sql_compressed略過壓縮邏輯直接儲存資料。

其次是通過實現tmysqldump使用select sql_compressed語法來獲取資料內容,在生成sql語句時使用對符合條件的sql使用insert sql_compressed這種語法。

二、列壓縮的應用

1.  配置列的壓縮屬性

在建表時語句指定blob/text型別的列具有compressed屬性,這樣該列的內容會被壓縮儲存

支援compressed屬性的列型別包括:tinyblob,blob, mediumblob,longblob, tinytext, text, mediumtext, longtext。

2. 修改列的壓縮屬性

因此,只需簡單的alter table操作,就可以讓db中特定列壓縮儲存。以上述案例二的遊戲db中資料為例,乙個1.3g的表,通過alter table增加compressed特徵後為0.19g,壓縮率是15%。在db中,這樣的表是100個,收益明顯。

3.   透明壓縮/解壓

列屬性指定為compressed之後,tmysql內部會根據實際需要進行壓縮和解壓處理。假設serviceinfo_00.serviceinfo、serviceinfo_00.gameinfo列具有compressed屬性,以下語句等價關係為

4.  匯入匯出優化

應用tmysql的列壓縮後,在使用mysqldump進行匯入匯出時,在匯出時會執行select操作,那麼會對所有的壓縮資料進行解壓;同樣,在匯入時也會對需要壓縮的資料執行壓縮操作。

通過改造mysqldump,增加選項enable-compress-optimization來控制壓縮的資料在匯出與匯入過程中,分別不進行解壓與壓縮,明顯縮減匯出及匯入的時間。

三、收益與展望

1、收益

互娛的遊戲db中,具有blob/text型別欄位的資料表都能夠應用compressed特性,目前已有4款遊戲使用上該特性。

上述案例二中遊戲某大區的gamedb,進行壓縮前資料大小為

160g,在使用tmysql的列壓縮屬性後,資料大小變成20g,壓縮率是12.5%。

以該遊戲乙個區的資料作壓力測試,使用壓縮特性後db效能提公升顯著:

如上圖,在100併發下,在a5機型中的qps由未壓縮的253提公升到列壓縮後的2236,提公升了8.8倍。

另外,在該業務的合服(兩個或多個大區合併成乙個大區)操作中,未壓縮與壓縮的合服時間對比為14239秒 vs 5749秒 , 時間節省為原來的40.3%。即合服操作導致的停服時間由原來4小時縮短到1.6小時。

2、展望

現階段已應用tmysql列壓縮功能的遊戲db,已明顯感受到使用列壓縮帶來的收益:包括合服、回檔中停機時長大幅度減小等。隨著越來越多的遊戲db使用列壓縮功能,列壓縮帶來的收益會越來越可觀。

這是典型的使用cpu換取記憶體和io的做法,列壓縮極大地減少了io開銷,雖說相應增加了cpu消耗,但當前遊戲db伺服器的cpu處於相對空閒狀態,這是完全可以接受的。後續會對列壓縮會提供多種壓縮演算法,可針對不同應用環境來進行選擇從而更合理地平衡io與cpu的消耗。tmysql版本未來會不斷演進和迭代,內建包括db雲化、冷熱資料分離等核心特性,提供業內領先的優質db服務。

Nginx gzip壓縮提公升效能

gzip是gnuzip的縮寫,最早用於unix系統的檔案壓縮。http協議上的gzip編碼是一種用來改進web應用程式效能的技術,web伺服器和客戶端 瀏覽器 必須共同支援gzip。目前主流的瀏覽器,chrome,firefox,ie等都支援該協議。常見的伺服器如apache,nginx,iis同樣...

InnoDB透明頁壓縮與稀疏檔案

此文已由作者王慎為授權網易雲社群發布。mysql 5.7中包括了很多讓人耳目一新的新特性,其中就包括了innodb transparent page compression,姑且稱之為innodb透明頁壓縮。其實透明頁壓縮這個東西,早就關注過,其用到了sparse file和hole punchin...

狀態壓縮DP 樹形D

動態規劃的狀態有時候比較難,不容易表示出來,需要用一些編碼技術,把狀態壓縮的用簡單的方式表示出來。典型方式 當需要表示乙個集合有哪些元素時,往往利用2進製用乙個整數表示。一般有個資料 n 16 或者 n 32 這個很可能就是狀態dp的標誌,因為我們要用乙個int的二進位制來表示這些狀態。要注意好這些...