OceanBase學習之路14|體驗並行匯入 & 資料壓縮

老樹樁12發表於2023-01-16

本文介紹了並行匯入和資料壓縮相關的使用及說明。

並行匯入

除了分析查詢,Operational OLAP 中還有很重要的一個部分,那就是大量資料的並行匯入,也就是資料批處理能力。OceanBase 資料庫的並行執行框架能夠將 DML 語句也透過併發的方式進行執行(Parallel DML),對於多節點的資料庫,實現多機併發寫入,並且保證大事務的一致性。結合非同步轉儲機制,還能在很大程度上最佳化 LSM tree 儲存引擎在記憶體緊張的情況下對大事務的支援。

我們透過這樣一個例子來體驗 PDML:仍然以 TPC-H 的  lineitem 表為基礎,建立一張相同表結構的空表  lineitem2。然後以  INSERT INTO ...SELECT 的方式,用一條 SQL 語句將  lineitem 的全部 600 萬行資料插入到新表  lineitem2 中。下面我們分別用關閉和開啟 PDML 的方式執行,觀察其效果和區別。

首先,複製  lineitem 的表結構,建立  lineitem2。注意,在 OceanBase 資料庫中我們使用分割槽表進行資料擴充套件,此處的例子中我們使用 16 個分割槽,那麼對應的  lineitem2 也應完全相同:

obclient> SHOW CREATE TABLE lineitem\G;
*************************** 1. row ***************************
       Table: lineitem
Create Table: CREATE TABLE `lineitem` (
  `l_orderkey` bigint(20) NOT NULL,
  `l_partkey` bigint(20) NOT NULL,
  `l_suppkey` bigint(20) NOT NULL,
  `l_linenumber` bigint(20) NOT NULL,
  `l_quantity` bigint(20) NOT NULL,
  `l_extendedprice` bigint(20) NOT NULL,
  `l_discount` bigint(20) NOT NULL,
  `l_tax` bigint(20) NOT NULL,
  `l_returnflag` char(1) DEFAULT NULL,
  `l_linestatus` char(1) DEFAULT NULL,
  `l_shipdate` date NOT NULL,
  `l_commitdate` date DEFAULT NULL,
  `l_receiptdate` date DEFAULT NULL,
  `l_shipinstruct` char(25) DEFAULT NULL,
  `l_shipmode` char(10) DEFAULT NULL,
  `l_comment` varchar(44) DEFAULT NULL,
  PRIMARY KEY (`l_orderkey`, `l_linenumber`),
  KEY `I_L_ORDERKEY` (`l_orderkey`) BLOCK_SIZE 16384 LOCAL,
  KEY `I_L_SHIPDATE` (`l_shipdate`) BLOCK_SIZE 16384 LOCAL
) DEFAULT CHARSET = utf8mb4 ROW_FORMAT = COMPACT COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 TABLEGROUP = 'x_tpch_tg_lineitem_order_group'
 partition by key(l_orderkey)
  (partition p0,
  partition p1,
  partition p2,
  partition p3,
  partition p4,
  partition p5,
  partition p6,
  partition p7,
  partition p8,
  partition p9,
  partition p10,
  partition p11,
  partition p12,
  partition p13,
  partition p14,
  partition p15)
1 row in set

預設方式執行,不開啟 PDML

建立好  lineitem2 後,我們先以預設配置不開啟並行的方式插入, 因為這是一個 600 萬行的大事務,我們需要將 OceanBase 資料庫預設的事務超時時間調整到更大的值(單位為 μs):

SET ob_query_timeout = 1000000000;  
SET ob_trx_timeout = 1000000000;

插入資料,執行結果如下:

MySQL [test]> INSERT INTO lineitem2 SELECT * FROM lineitem;
Query OK, 6001215 rows affected (1 min 47.312 sec)
Records: 6001215  Duplicates: 0  Warnings: 0

不開啟 PDML

可以看到,不開啟並行的情況下,單個事務插入 600 萬行資料,OceanBase 的耗時為 107 秒。

開啟 PDML 執行

下面我們透過新增一個 Hint,開啟 PDML 的執行選項。注意再次插入前,我們先將上次插入的資料清空。

TRUNCATE TABLE lineitem2;
INSERT /*+ parallel(16) enable_parallel_dml */ INTO lineitem2 SELECT * FROM lineitem;

來看這次的執行耗時:

obclient> TRUNCATE TABLE lineitem2;
Query OK, 0 rows affected (0.108 sec)
obclient> INSERT /*+ parallel(16) enable_parallel_dml */ INTO lineitem2 SELECT * FROM lineitem;
Query OK, 6001215 rows affected (22.117 sec)
Records: 6001215  Duplicates: 0  Warnings: 0

開啟 PDML

可以看到開啟 PDML 後,相同的表插入 600 萬行資料,OceanBase 資料庫的耗時縮短為 22 秒左右。PDML 特性帶來的效能提升大約為 5 倍。這一特性可以在使用者在需要批次資料處理的場景提供幫助。

資料壓縮

OceanBase 資料庫基於 LSM Tree 結構開發了自己的儲存引擎。其中資料大致被分為基線資料(SSTable)和增量資料(MemTable)兩部分,基線資料被儲存在磁碟中,增量修改在記憶體中進行。這使得一方面資料在磁碟中能夠以更緊湊的方式儲存。除此之外由於在磁碟中的基線資料不會頻繁更新,OceanBase 資料庫又基於通用壓縮演算法對基線資料進行了再次壓縮,使得資料儲存在 OceanBase 資料庫中可以獲得非常好的壓縮比。同時這種資料壓縮並未帶來查詢和寫入效能的下降。下面我們介紹 OceanBase 資料庫匯入大量外部資料並且觀察資料壓縮比的方法。

資料準備

首先我們使用資料準備工具   生成 5 千萬行模擬資料到  /home/soft 目錄下,生成資料大概需要十幾分鍾時間,您也可以使用其他工具生成測試資料。

#mkdir /home/soft/
#java -jar CreateData.jar /home/soft/ 50000000
filePath is : /home/soft/
Start Time : 2022-07-10 15:33:00
End Time : 2022-07-10 15:52:53
#du -sh *
10G     t_bigdata_loader.unl

OceanBase 資料庫支援多種方式將 csv 格式的資料匯入到 OceanBase 資料庫中,本文我們介紹透過 Load Data 命令執行。

  1. 首先您需對生成的檔案進行命名,並確認實際大小。

    mv t_bigdata_loader.unl t_f1.csv
    du -sh t_f1.csv
    10G     t_f1.csv
  2. 對  t_f1.csv 檔案內容檢視可知,預先生成好的 csv 檔案,透過隨機演算法,獲取了 8 列資料,可對應不同的資料型別。因此在體驗 OceanBase 資料壓縮特性時,需要在租戶下先建立一張表,將 csv 檔案中的記錄,匯入到表中。

    1|1896404182|1980-06-01|2004-10-25 13:30:39|7470.689|33062564.9527|nOLqnBYtnp|BzWYjZjeodtBNzXSMyBduMNzwDPSiVmhVgPJMeEkeAwKBCorzblwovIHDKBsQhbVjQnIdoeTsiLXTNwyuAcuneuNaol|
    2|572083440|2018-11-09|1998-07-11 01:23:28|6891.054|66028434.4013|UzqteeMaHP|vQWbWBXEWgUqUTzqsOSciiOuvWVcZSrlEOQDwDVGmvGRQYWmhCFdEkpsUsqrWEpKtmxSwURHIHxvmlXHUIxmfelYboeGEuScKKqzpuNLryFsStaFTTRqSsVlCngFFjHnEnpaCnWsdwztbiHJyoGkaxrFmyPAmVregfydArrUZsgRqBpQ|
    3|1139841892|2006-10-07|1999-06-26 17:02:22|286.43692|51306547.5055|KJJtylgxkv|BuBdFTBIIFsEPVxsVBRqAnFXSBdtZDgfumUhIx|
    4|1777342512|1982-12-18|2017-11-19 07:56:35|2986.242|85860387.8696|rTkUBWhdPt|JSazOTAmvtCBrINttDwublNJNRFDIiWkHtWZXmWgKHoZCKGqmmETkIcYLXiSgKkoaATNgjvPxVGjeCOODLEWqrQHqowbMjOLOKrtirWEOpUSxiUudZduTCUvZElKzZfggvCBNthwzKJc|
    ....
  3. 在租戶  test 下的  test 資料庫中建立一張表,表名為  t_f1。詳細的租戶建立過程,請參考管理租戶內容。

    obclient -h127.0.0.1 -P2881 -uroot@test  -Dtest -A -p -c
    obclient [test]> CREATE TABLE t_f1(id DECIMAL(10,0),id2 DECIMAL(10,0),id3 DATE,id4 DATE,id5 FLOAT,id6 FLOAT,id7 VARCHAR(30),id8 VARCHAR(300));

資料匯入

我們可以使用 OceanBase 資料庫內建的 Load Data 命令匯入資料,Load Data 同樣支援並行匯入。開始匯入前進行如下設定。Load Data 命令僅支援資料檔案在 OBServer 本地執行,如果您希望遠端進行資料匯入,可以參考使用 OceanBase 資料庫的 obloader 工具。

SET ob_query_timeout=1000000000;
SET ob_trx_timeout=1000000000;
SET GLOBAL secure_file_priv = "";
GRANT FILE ON *.* to username;

注意

由於安全原因,以上授權 SQL 只能使用本地訪問執行,不能使用遠端 OBClient 執行。即需要在 OBServer 所在機器上登入 OBClient (或者 MySQL 客戶端) 執行。

設定完成後,重連會話使設定生效。然後執行匯入語句:

load data /*+ parallel(16) */ infile '/home/soft/t_f1.csv' into table t_f1 fields terminated by '\|' lines terminated by '\n';

可以看到,開啟並行匯入後,10 GB 資料耗時大約 4 分鐘。 本文中租戶的 CPU 配置為 16 GB,可以根據您的具體配置設定合適的並行度,配置越高匯入速度越快。

匯入後,進入資料庫對該表記錄條數及佔用空間大小進行檢視。

  1. 檢視錶記錄數有 5 千萬條。

    obclient [test]> SELECT COUNT(*) FROM t_f1;
    +----------+
    | count(*) |
    +----------+
    | 50000000 |
    +----------+
  2. 對資料庫合併。

    為了檢視基線資料的壓縮效果,我們使用  sys 租戶管理員登入,主動觸發對資料庫進行合併,使增量資料可以和基線資料進行合併與壓縮。您可以透過如下的方式手動觸發合併。

    obclient -h127.0.0.1 -P2881 -uroot@sys  -Doceanbase -A -p -c
    obclient[oceanbase]> ALTER SYSTEM MAJOR FREEZE;
  3. 當看到如下查詢返回 IDLE 時,表示合併完成。

    obclient> SELECT name,info FROM __all_zone WHERE zone='' AND name = 'merge_status';
    +--------------+------+
    | name         | info |
    +--------------+------+
    | merge_status | IDLE |
    +--------------+------+
    1 row in set
  4. 使用 sys 租戶查詢如下語句,可檢視匯入至 OceanBase 後的資料儲存佔用情況。

    obclient [oceanbase]> SELECT b.table_name,svr_ip,role,a.data_size/1024/1024/1024 FROM __all_virtual_meta_table a,__all_virtual_table b WHERE a.role=1 AND a.table_id=b.table_id AND b.table_name='T_F1';
    +------------+---------------+------+----------------------------+
    | table_name | svr_ip        | role | a.data_size/1024/1024/1024 |
    +------------+---------------+------+----------------------------+
    | t_f1       | xxx.xx.xxx.xx |    1 |             6.144531250000 |
    +------------+---------------+------+----------------------------+複製

壓縮後的表大小約為 6.145 G,壓縮比為 = 10/6.145 = 1.62。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026075/viewspace-2932348/,如需轉載,請註明出處,否則將追究法律責任。

相關文章