TerarkDB 基於 Sysbench效能測試

sysbench 是一個模組化的、跨平臺、多執行緒基準測試工具,主要用於評估測試各種不同系統引數下的資料庫負載情況。本測試使用修改版的 sysbench 分別向官方原版 MySQL 和 MySQL on TerarkDB 匯入 38,508,221 條 wikipedia 文章資料,並測試在不同記憶體下兩者的讀寫效能。非常值得注意的是,sysbench 測試中預設的資料分佈是 special,表示熱點非常集中的資料,從而測試結果主要體現的是快取的效能。這就是為什麼大家經常發現 sysbench 測試出來效能很高,一到生產環境,效能就跪了。好在 sysbench 也有對其它資料分佈的支援,例如 uniform,即均勻分佈,其測試結果主要體現的是隨機訪問的效能。本文中所有的測試均使用 uniform 分佈。測試程式使用 terark/sysbench 1。0。1,我們在原版 sysbench 的基礎上添加了讀取文字檔案作為資料來源的功能,以及一個次級索引範圍查詢測試。測試的資料庫有:MySQL on TerarkDB (下簡稱 TerarkDB),官方原版 MySQL(下簡稱 InnoDB)。MySQL 開啟壓縮。測試平臺CPU: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2。40GHz x2 (共 16 核 32 執行緒)記憶體: DDR4 16G @ 1866 MHz x 12 (共 192 G)SSD: INTEL SSDSC2BP48 0420 IOPS 89000作業系統: CentOS 7測試中使用的官方原版 MySQL 版本為 Ver 5。6。35 for linux-glibc2。5 on x86_64。下文 G, GB 指 230,而非 109。資料匯入sysbench 原版只能匯入自動生成的資料,這樣的資料無法體現壓縮演算法的優劣,所以我們修改了 sysbench 原始碼,以支援匯入指定檔案中的資料。我們使用 wikipedia dump 出來的文章資料,並提取出其中的文章標題和文章內容作為資料來源(資料示例可見附錄1),這些資料共有 38,508,221 條,總大小為 94。8GB,平均每條約 2。6KB。每張表(表結構可見附錄2)中還有一個自增主鍵以及一個 Secondary Index,也會佔用空間,因為輔助索引列和主鍵索引列都是 int32,所以資料來源的大小為 94。8G+8*38,508,221=95。1G。另外,對於每條資料,輔助索引的空間佔用也是 8 位元組,從而輔助索引的邏輯空間佔用就是 8*38,508,221=0。29G。所以,資料來源的等效尺寸為 95。4G。資料匯入後,資料庫尺寸大小比較如下:資料庫尺寸 壓縮率 資料條數 單條尺寸 總尺寸 索引+資料InnoDB 55。4 G 58。1% 或 1。72倍 38,508,221 2。6 K 95。1 G 95。4 GTerarkDB 20。7 G 21。7% 或 4。61倍匯入資料所使用的 sysbench 命令如下:sysbench ——report-interval=1 ——db-driver=mysql \ ——mysql-port=3306 ——mysql-user=root \ ——mysql-db=sysbench ——mysql-host=127。0。0。1 \ ——tables=1 ——mysql_storage_engine=innodb \ ——table-size=38508221 ——rand-type=uniform \ ——create_secondary=on ——use-file=on \ ——filename=/path/to/wikipedia-article。txt \ /path/to/share/sysbench/oltp_insert。lua prepare注1:插入時一定要指定 ——rand-type 為 uniform,因為其預設值 special 為熱點分佈,其輔助索引以及查詢分佈為熱點分佈,從而不能反映出隨機讀寫的效能。測試結果我們進行了四種測試:主鍵等值查詢(point_select)讀寫混合查詢(point_select90_update10)次級索引等值查詢(secondary_random_points100)次級索引範圍查詢(secondary_random_limit100)這四種測試分別在 192G、32G、24G、8G 的記憶體限制下執行。不同的記憶體限制使用記憶體擠佔工具實現,記憶體擠佔工具擠佔一定數量的記憶體(不可換出)確保資料庫所能使用的記憶體為以上指定值。每次測試中 InnoDB 的 innodb_buffer_pool_size 總是設定為可用記憶體的 70%,TerarkDB 的 softZipWorkingMemLimit 和 hardZipWorkingMemLimit 分別設定為可用記憶體的 1/8 和 1/4。所有的測試均使用 32 個執行緒,每次測試前先 warm up 30 秒,每次測試持續 15 分鐘。下表中僅記錄各測試結果的 RPS(Rows Per Second)。記憶體 測試型別 TerarkDB InnoDB192G point_select 151,250 269,841point_select90_update10 90,764 21,387secondary_random_points100 484,432 712,815secondary_random_limit100 791,500 2,284,20032G point_select 151,730 95,090point_select90_update10 68,299 8,098secondary_random_points100 473,500 107,348secondary_random_limit100 782,300 152,80424G point_select 151,844 80,775point_select90_update10 54,843 6,411secondary_random_points100 476,500 87,863secondary_random_limit100 784,500 123,7008G point_select 96,688 57,570point_select90_update10 28,673 5,477secondary_random_points100 112,237 51,651secondary_random_limit100 143,800 72,800將上表中的資料做成更直觀的圖表,如下:192G 記憶體對 TerarkDB 和 InnoDB 都夠用,實際上,TerarkDB 只使用了大約 21G,InnoDB 則使用了 134G 記憶體(程序記憶體 + 系統快取)。TerarkDB 的只讀效能低於 InnoDB,主要是因為 MyRocks 適配層帶來的效能損失(相比引擎層損失了 10 倍以上的效能)。MyRocks 適配層的開發一直很活躍,版本更新經常會發生效能驟變(提高或降低都會發生,該測試使用的這個版本效能比之前就有所下降,但隨著時間的推移,總的趨勢是向上的)。TerarkDB 的讀寫混合性能高於 InnoDB,是因為 TerarkDB 透過 RocksDB 使用了 LSM Tree,隨機寫效能從根上就遠優於 InnoDB 的 BTree。32G 記憶體,TerarkDB 夠用,但 InnoDB 不夠用,TerarkDB 儘管有 MyRocks 適配層帶來的效能損失,但 InnoDB 因為記憶體不夠受限於 IO 瓶頸 ,從而 TerarkDB 的效能遠高於 InnoDB。24G 記憶體,TerarkDB 仍然夠用,但 InnoDB 很不夠用,InnoDB 效能進一步下降,而 TerarkDB 效能基本不受影響,高壓縮率帶來的優勢由此可見。8G 記憶體對 TerarkDB 和 InnoDB 都很不夠用,TerarkDB 的 IO 也成為瓶頸,但 InnoDB 的記憶體缺口更大,從而 TerarkDB 的效能仍遠高於 InnoDB。測試型別說明1。 point_select主鍵等值查詢,測試程式每次隨機生成一個 ID 值,然後查詢主鍵與之相等的記錄。測試的每個 transaction 裡包含 100 個主鍵等值查詢 query,故每個 transaction 會訪問 100 行資料。示例 SQL:select c from sbtest1 where id = ID;sysbench 命令:sysbench ——time=900 ——report-interval=1 \ ——db-driver=mysql ——mysql-port=3306 \ ——mysql-user=root ——mysql-db=sysbench \ ——mysql-host=127。0。0。1 ——threads=32 \ ——warmup-time=30 ——distinct_ranges=0 \ ——sum_ranges=0 ——index_updates=0 \ ——range_size=100 ——delete_inserts=0 \ ——tables=1 ——mysql_storage_engine=rocksdb \ ——non_index_updates=0 ——table-size=38508221 \ ——simple_ranges=0 ——secondary_ranges=0\ ——order_ranges=0 ——range_selects=off \ ——point_selects=100 ——rand-type=uniform \ ——skip_trx=on \ /path/to/share/sysbench/oltp_read_only。lua run2。 point_select90_update10讀寫混合測試,除上述主鍵等值查詢外,還會隨機生成一個 ID,然後更新主鍵與該 ID 相等的記錄的 c 值為一個隨機的 119 位元組長的隨機字串。測試的每個 transaction 包含 90 個主鍵等值查詢 query,和 10 個非主鍵更新 query,故每個 transaction 會訪問 100 行資料,並更新 10 行資料。示例 SQL:select c from sbtest1 where id = ID;update sbtest1 set c = C where id = ID;sysbench 命令:sysbench ——time=900 ——report-interval=1 \ ——db-driver=mysql ——mysql-port=3306 \ ——mysql-user=root ——mysql-db=sysbench \ ——mysql-host=127。0。0。1 ——threads=32 \ ——warmup-time=30 ——distinct_ranges=0 \ ——sum_ranges=0 ——index_updates=0 \ ——range_size=100 ——delete_inserts=0 \ ——tables=1 ——mysql_storage_engine=rocksdb \ ——non_index_updates=10 ——table-size=38508221 \ ——simple_ranges=0 ——secondary_ranges=0 \ ——order_ranges=0 ——range_selects=off \ ——point_selects=90 ——rand-type=uniform \ ——skip_trx=on \ /path/to/share/sysbench/oltp_read_write。lua run3。 secondary_random_points100次級索引等值查詢,測試程式隨機生產 100 個 key,然後使用 where in 語法隨機讀取這 100 個 key 對應的 100 行資料。測試的每個 transaction 包含一個 Query,每個 Query 對次級索引進行 100 次隨機搜尋,每次都需要進行回表操作(先從次級鍵拿到主鍵,再用主鍵取資料),從而每個 transaction 需要對儲存引擎進行 200 次隨機訪問。示例 SQL:select id, k, c, pad from sbtest1 where k in (k1, k2, k3, 。。。, k100);sysbench 命令:sysbench ——time=900 \ ——report-interval=1 \ ——db-driver=mysql ——mysql-port=3306 \ ——mysql-user=root ——mysql-db=sysbench \ ——mysql-host=127。0。0。1 \ ——threads=32 ——warmup-time=30 \ ——tables=1 ——table-size=38508221 \ ——rand-type=uniform ——skip_trx=on \ ——random_points=100 \ /path/to/share/sysbench/select_random_points。lua run4。 secondary_random_limit100次級索引範圍查詢,該查詢為我們新新增的測試,用來測試主索引的隨機讀效能:次級 Key 是隨機生成的,次級 Key 按大小順序對映到主鍵,得到的主鍵序列就是隨機順序,所以,這樣的訪問,就是次級 Key 的順序訪問再加主鍵的隨機訪問。測試的每個 transaction 包含 100 個次級索引範圍查詢 query,每個 query 會訪問 100 行資料,從而每個 transaction 會訪問 10,000 行資料。示例 SQL:select c from sbtest1 where k >= K limit 100;sysbench 命令:sysbench ——time=900 ——report-interval=1 \ ——db-driver=mysql ——mysql-port=3306 \ ——mysql-user=root ——mysql-db=sysbench \ ——mysql-host=127。0。0。1 \ ——threads=32 ——warmup-time=30 \ ——distinct_ranges=0 ——sum_ranges=0 \ ——index_updates=0 ——range_size=100 \ ——delete_inserts=0 ——tables=1 \ ——mysql_storage_engine=rocksdb \ ——non_index_updates=0 ——table-size=38508221 \ ——simple_ranges=0 ——secondary_ranges=100 \ ——order_ranges=0 ——range_selects=on \ ——point_selects=0 ——rand-type=uniform \ ——skip_trx=on \ /path/to/share/sysbench/oltp_read_only。lua run附錄1:資料來源示例:‘AccessibleComputing’ ‘#REDIRECT [[Computer accessibility]]\n\n{{Redr|move|from CamelCase|up}}’‘Anarchism’ ‘{{Redirect2|Anarchist|Anarchists|the fictional character|Anarchist (comics)|other uses|Anarchists (disambiguation)}}\n{{pp-move-indef}}\n …… [[Category:Far-left politics]]’‘Liberty_Hall_(Lamoni,_Iowa)’ ‘{{WikiProject National Register of Historic Places|class=Stub|importance=Low}}\n{{WikiProject Iowa|class=Stub|importance=Low}}\n{{reqphoto|in=Decatur County, Iowa}}’附錄2:表結構:CREATE TABLE sbtest1 ( id int(11) NOT NULL AUTO_INCREMENT, k int(11) NOT NULL DEFAULT ‘0’, c varchar(512) NOT NULL DEFAULT ‘’, pad mediumtext, PRIMARY KEY (id), KEY k_1 (k));

TerarkDB 基於 Sysbench效能測試