diff --git "a/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234OceanBase \345\257\271\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\347\232\204\346\224\257\346\214\201\350\203\275\345\212\233\350\257\204\346\265\213\344\270\216\345\210\206\346\236\220.md" "b/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234OceanBase \345\257\271\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\347\232\204\346\224\257\346\214\201\350\203\275\345\212\233\350\257\204\346\265\213\344\270\216\345\210\206\346\236\220.md" new file mode 100644 index 0000000000000000000000000000000000000000..e8e272b6266788a00ed506c3511c8aa41af0e267 --- /dev/null +++ "b/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234OceanBase \345\257\271\345\210\206\345\270\203\345\274\217\344\272\213\345\212\241\347\232\204\346\224\257\346\214\201\350\203\275\345\212\233\350\257\204\346\265\213\344\270\216\345\210\206\346\236\220.md" @@ -0,0 +1,599 @@ + +# 往期征文分享|OceanBase 对分布式事务的支持能力评测与分析 + +> **瞿璐祎(笔名 Andrea):** 研究生期间在华东师范大学数据学院 DBHammer 组致力于事务型数据库评测工作,已经在面向应用的事务数据库评测场景模拟以及分布式事务型数据库的评测上取得了一定的成果,其本人将继续致力于为国产数据库的发展添砖加瓦。 + +分布式数据库的一大设计目标是通过增加分布式节点来提高数据库的性能,如吞吐。但是分布式环境给事务处理带来的优势有可能会由于分布式事务的产生而削弱,甚至会造成性能的恶化。接下来本文将 OceanBase 对分布式事务的支持能力进行评测,并详细阐述 OceanBase 提出的 tablegroup 技术对分布式事务执行性能产生的影响。 + +## 01 初探 TPC-C 中NewOrder 事务 + +在 TPC-C 中,NewOrder 事务负责下订单任务,它会在 Stock 表中更新 5-15 个 items 的库存。NewOrder 事务平均 10 个操作,每个操作会有 1% 的概率更新远程的仓库的 Stock 信息,因此会产生 10% 的分布式事务。NewOrder 的事务模板如下所示。 + +```sql + +TX[NewOrder] +SELECT C_DISCOUNT, C_LAST, C_CREDIT FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ?; +SELECT W_TAX FROM WAREHOUSE WHERE W_ID = ?; +SELECT D_NEXT_O_ID, D_TAX FROM DISTRICT WHERE D_W_ID = ? AND D_ID = ? FOR UPDATE; +UPDATE DISTRICT SET D_NEXT_O_ID = D_NEXT_O_ID + 1 WHERE D_W_ID = ? AND D_ID = ?; +INSERT INTO OORDER (O_ID, O_D_ID, O_W_ID, O_C_ID, O_ENTRY_D, O_OL_CNT, O_ALL_LOCAL) VALUES (?, ?, ?, ?, ?, ? , ?); +INSERT INTO NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) VALUES ( ?, ?, ?); +Multiple +SELECT I_PRICE, I_NAME, I_DATA FROM ITEM WHERE I_ID = ?; C_DISCOUNT +SELECT S_QUANTITY, S_DATA, S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04, S_DIST_05, S_DIST_06, S_DIST_07, S_DIST_08, S_DIST_09, S_DIST_10 FROM STOCK WHERE S_I_ID = ? AND S_W_ID = ? FOR UPDATE; +//此处有1%的可能s_w_id != w_id,从而产生分布式事务 +UPDATE STOCK SET S_QUANTITY = ?, S_YTD = S_YTD + ?, S_ORDER_CNT = S_ORDER_CNT + 1, S_REMOTE_CNT = S_REMOTE_CNT + ? WHERE S_I_ID = ? AND S_W_ID = ?; +INSERT INTO ORDER_LINE (OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER, OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, OL_DIST_INFO) VALUES (?,?,?, ?,?,?,?,?,?); +EndMultiple +EndTX +``` + +为了分析 OceanBase 对分布式事务的支持能力,我们将分布式事务比例进行参数化,将它分别设为 1%,10%,20%,40%,80%和100%。关于 BenchmarkSQL 的代码修改见实验配置。 + +## 02 实验准备及实验配置 + +BenchmarkSQL 运行 TPC-C 中的 NewOrder 事务,为了合理设置分布式事务比例,对 NewOrder 事务做了略微的改动,改动内容以及 benchmarkSQL 的配置参数在下方。(必选) + +OceanBase v3.1.2版本(必须) + +**关于实验配置主要包括以下三个部分:** + +### 一、机器配置 + +为测试分布式事务的影响,本次实验将 OceanBase 部署在 10 台机器上。其中 9台机器的配置为:8 核 CPU,32G 内存,上面各部署了一个 OBServer;其中 1 台机器的配置为:16 核 CPU, 16G 内存,上面部署了一个 OBProxy,同时也作为实验的客户端。 + +下面介绍了我们的集群配置情况,对 BenchmarkSQL 修订的内容和配置文件。运行 BenchmarkSQL 对 OceanBase 的系统变量和用户变量的调整见官网。 + +本实验中使用的是 mysql mode,需要将 BenchmarkSQL 和 OceanBase 适配,可见官网。 + +### 二、OceanBase 集群配置 + +```sql +## Only need to configure when remote login is required +user: + username: xxx + password: xxx + #key_file: .ssh/authorized_keys +oceanbase-ce: + servers: + - name: host1 + ip: 10.24.14.8 + - name: host2 + ip: 10.24.14.136 + - name: host3 + ip: 10.24.14.75 + - name: host4 + ip: 10.24.14.178 + - name: host5 + ip: 10.24.14.60 + - name: host6 + ip: 10.24.14.120 + - name: host7 + ip: 10.24.14.126 + - name: host8 + ip: 10.24.14.171 + - name: host9 + ip: 10.24.14.181 + global: + devname: eth0 + cluster_id: 1 + memory_limit: 28G + system_memory: 8G + stack_size: 512K + cpu_count: 16 + cache_wash_threshold: 1G + __min_full_resource_pool_memory: 268435456 + workers_per_cpu_quota: 10 + schema_history_expire_time: 1d + net_thread_count: 4 + major_freeze_duty_time: Disable + minor_freeze_times: 10 + enable_separate_sys_clog: 0 + enable_merge_by_turn: FALSE + datafile_disk_percentage: 35 + syslog_level: WARN + enable_syslog_recycle: true + max_syslog_file_count: 4 + appname: ob209 + host1: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data/obdata + zone: zone0 + host2: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data/obdata + zone: zone0 + host3: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data/obdata + zone: zone0 + host4: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data/obdata + zone: zone1 + host5: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data/obdata + zone: zone1 + host6: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data1/obdata + zone: zone1 + host7: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data1/obdata + zone: zone2 + host8: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data1/obdata + zone: zone2 + host9: + mysql_port: 2883 + rpc_port: 2882 + home_path: /data1/obdata + zone: zone2 + +obproxy: + servers: + - 10.24.14.215 + global: + listen_port: 2883 + home_path: /data/obproxy + rs_list: 10.24.14.8:2883;10.24.14.136:2883;10.24.14.75:2883;10.24.14.178:2883;10.24.14.60:2883;10.24.14.120:2883;10.24.14.126:2883;10.24.14.171:2883;10.24.14.181:2883 + enable_cluster_checkout: false + cluster_name: ob209 +``` + +### 三、BenchmarkSQL 修改内容和配置文件 + +下载 [BenchmarkSQL](https://sourceforge.net/projects/benchmarksql/files/latest/download) 后,查看 BenchmarkSQL 修改内容,如下: + +- 修改 benchmark-5.0/src/client/jTPCC.java 文件,增加分布式事务比例的参数化。 + + ```sql + private double tpmC; + private jTPCCRandom rnd; + private OSCollector osCollector = null; + //声明neworder事务中的分布式事务比例 + private static double newOrderDistributedRate; + ``` + + ```sql + + String iWarehouses = getProp(ini,"warehouses"); + String iTerminals = getProp(ini,"terminals"); + //获取配置文件参数 + newOrderDistributedRate = Double.parseDouble(getProp(ini, "newOrderDistributedRate")); + + String iRunTxnsPerTerminal = ini.getProperty("runTxnsPerTerminal"); + String iRunMins = ini.getProperty("runMins"); + + ``` + + ```sql + + private String getFileNameSuffix() + { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + return dateFormat.format(new java.util.Date()); + } + + //创建外部类的访问接口 + public static double getNewOrderDistributedRate() { + return newOrderDistributedRate; + } + ``` + +- 修改 benchmark-5.0/src/client/jTPCCTData.java 文件,修改 NewOrder 的分布式事务比例。 + + ```sql + while (i < o_ol_cnt) // 2.4.1.5 + { + newOrder.ol_i_id[i] = rnd.getItemID(); + //更改分布式事务比例 + if (rnd.nextInt(1, 100) <= 100-jTPCC.getNewOrderDistributedRate()*100) + newOrder.ol_supply_w_id[i] = terminalWarehouse; + else + newOrder.ol_supply_w_id[i] = rnd.nextInt(1, numWarehouses); + newOrder.ol_quantity[i] = rnd.nextInt(1, 10); + ``` + +- 修改benchmark-5.0/run/probs.ob文件 + + ```sql + + db=oracle + driver=com.alipay.oceanbase.obproxy.mysql.jdbc.Driver + conn=jdbc:oceanbase://10.24.14.188:2883/tpcc_100?useUnicode=true&characterEncoding=utf-8 + user=tpcc@test + password= + + warehouses=100 + loadWorkers=30 + + terminals=100 + //To run specified transactions per terminal- runMins must equal zero + runTxnsPerTerminal=0 + //To run for specified minutes- runTxnsPerTerminal must equal zero + runMins=5 + //Number of total transactions per minute + limitTxnsPerMin=0 + + //将生成的数据放在该目录 + fileLocation=/data/ob/tpcc_100/ + + //Distributed Transaction Ratio For NewOrder Transaction + newOrderDistributedRate=0.01 + + //Set to true to run in 4.x compatible mode. Set to false to use the + //entire configured database evenly. + terminalWarehouseFixed=false + + //The following five values must add up to 100 + newOrderWeight=100 + paymentWeight=0 + orderStatusWeight=0 + deliveryWeight=0 + stockLevelWeight=0 + + // Directory name to create for collecting detailed result data. + // Comment this out to suppress. + resultDirectory=my_result_%tY-%tm-%td_%tH%tM%tS + osCollectorScript=./misc/os_collector_linux.py + osCollectorInterval=1 + ``` + +- 修改benchmark-5.0/run/sql.oceanbase/tableCreates.sql 文件 + + ```sql + create table bmsql_config ( + cfg_name varchar(30) primary key, + cfg_value varchar(50) + ); + + create tablegroup tpcc_group binding true partition by hash partitions 128; + + create table bmsql_warehouse ( + w_id integer not null, + w_ytd decimal(12,2), + w_tax decimal(4,4), + w_name varchar(10), + w_street_1 varchar(20), + w_street_2 varchar(20), + w_city varchar(20), + w_state char(2), + w_zip char(9), + primary key(w_id) + )tablegroup='tpcc_group' partition by hash(w_id) partitions 128; + + create table bmsql_district ( + d_w_id integer not null, + d_id integer not null, + d_ytd decimal(12,2), + d_tax decimal(4,4), + d_next_o_id integer, + d_name varchar(10), + d_street_1 varchar(20), + d_street_2 varchar(20), + d_city varchar(20), + d_state char(2), + d_zip char(9), + PRIMARY KEY (d_w_id, d_id) + )tablegroup='tpcc_group' partition by hash(d_w_id) partitions 128; + + create table bmsql_customer ( + c_w_id integer not null, + c_d_id integer not null, + c_id integer not null, + c_discount decimal(4,4), + c_credit char(2), + c_last varchar(16), + c_first varchar(16), + c_credit_lim decimal(12,2), + c_balance decimal(12,2), + c_ytd_payment decimal(12,2), + c_payment_cnt integer, + c_delivery_cnt integer, + c_street_1 varchar(20), + c_street_2 varchar(20), + c_city varchar(20), + c_state char(2), + c_zip char(9), + c_phone char(16), + c_since timestamp, + c_middle char(2), + c_data varchar(500), + PRIMARY KEY (c_w_id, c_d_id, c_id) + )tablegroup='tpcc_group' partition by hash(c_w_id) partitions 128; + + + create table bmsql_history ( + hist_id integer, + h_c_id integer, + h_c_d_id integer, + h_c_w_id integer, + h_d_id integer, + h_w_id integer, + h_date timestamp, + h_amount decimal(6,2), + h_data varchar(24) + )tablegroup='tpcc_group' partition by hash(h_w_id) partitions 128; + + create table bmsql_new_order ( + no_w_id integer not null , + no_d_id integer not null, + no_o_id integer not null, + PRIMARY KEY (no_w_id, no_d_id, no_o_id) + )tablegroup='tpcc_group' partition by hash(no_w_id) partitions 128; + + create table bmsql_oorder ( + o_w_id integer not null, + o_d_id integer not null, + o_id integer not null, + o_c_id integer, + o_carrier_id integer, + o_ol_cnt integer, + o_all_local integer, + o_entry_d timestamp, + PRIMARY KEY (o_w_id, o_d_id, o_id) + )tablegroup='tpcc_group' partition by hash(o_w_id) partitions 128; + + create table bmsql_order_line ( + ol_w_id integer not null, + ol_d_id integer not null, + ol_o_id integer not null, + ol_number integer not null, + ol_i_id integer not null, + ol_delivery_d timestamp, + ol_amount decimal(6,2), + ol_supply_w_id integer, + ol_quantity integer, + ol_dist_info char(24), + PRIMARY KEY (ol_w_id, ol_d_id, ol_o_id, ol_number) + )tablegroup='tpcc_group' partition by hash(ol_w_id) partitions 128; + + create table bmsql_item ( + i_id integer not null, + i_name varchar(24), + i_price decimal(5,2), + i_data varchar(50), + i_im_id integer, + PRIMARY KEY (i_id) + ) locality='F,R{all_server}@zone0, F,R{all_server}@zone1, F,R{all_server}@zone2' duplicate_scope='cluster'; + -- ); + + create table bmsql_stock ( + s_w_id integer not null, + s_i_id integer not null, + s_quantity integer, + s_ytd integer, + s_order_cnt integer, + s_remote_cnt integer, + s_data varchar(50), + s_dist_01 char(24), + s_dist_02 char(24), + s_dist_03 char(24), + s_dist_04 char(24), + s_dist_05 char(24), + s_dist_06 char(24), + s_dist_07 char(24), + s_dist_08 char(24), + s_dist_09 char(24), + s_dist_10 char(24), + PRIMARY KEY (s_w_id, s_i_id) + )tablegroup='tpcc_group' partition by hash(s_w_id) partitions 128; + ``` + +## 03 实验过程 + +### 一、创建schema并在本地生成数据文件 + +```sql +cd benchmark-5.0/run +./runDatabaseBuild.sh props.ob +``` + +### 二、导入数据 + +这里采用的是外部 load infile 方式导入数据库,因为我们导入的数据量比较大,这种方式更加快速。首先,需要将生成的数据文件如 customer.csv 等移动到 rootserver 所在的机器上,我们这边放在 10.24.14.245(rootserver) 上的 /data/ob/tpcc_100/ 目录。此外,schema 的创建方式 + +```sql + +obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/warehouse.csv' into table bmsql_warehouse fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/district.csv' into table bmsql_district fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/config.csv' into table bmsql_config fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/item.csv' into table bmsql_item fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/order.csv' into table bmsql_oorder fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/stock.csv' into table bmsql_stock fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/cust-hist.csv' into table bmsql_history fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/new-order.csv' into table bmsql_new_order fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/order-line.csv' into table bmsql_order_line fields terminated by ',';" + obclient -h10.24.14.245 -P2883 -uroot@test -c -D tpcc_100 -e "load data /*+ parallel(80) */ infile '/data/ob/tpcc_100/customer.csv' into table bmsql_customer fields terminated by ',';" +``` + +### 三、分布式事务比例实验的运行负载 + +实验中分别将 NewOrderDistributedRate 设为 0.01,0.1,0.2,0.4,0.6,0.8,1 分别代表不同的 NewOrder 事务的分布式事务比例。 + +```sql +./runBenchmark.sh probs.ob +``` + +## 04 实验结果展示与分析 + +我们将上方运行的分布式事务的实验结果列在下方,横坐标是不同的分布式事务比例,纵坐标是每分钟的吞吐数。我们可以观察到,分布式事务比例从 0.01 一直到 1,吞吐从 188639 下降到 64699,下降了 65.7%。实验结果符合我们的预期,分布式事务对分布式数据库的性能会造成比较大的影响。 + +![blog-first-1.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/first/blog-first-1.png) + +为了尽量减少分布式事务比例的影响,OceanBase 其实提出了 tablegroup 机制,它能让经常被一起访问的记录尽可能地放在用一个 partition 中。比如,一个歌手名下有多张唱片,如果一个事务更新歌手及其名下的唱片,那么将该歌手和其唱片放在一起,就可以减少分布式事务。OceanBase 中的 tablegroup 机制就是基于这样的想法创建出来的,为了验证 tablegroup 机制提升性能的效果,我们将去掉原始的 tablegroup 机制,来看性能下降了多少。 + +## 05 进一步实验 + +第一步,为了完成这个实验,需要修改 benchmark-5.0/run/sql.oceanbase/tableCreates.sql 文件。 + +```sql + +create table bmsql_config ( + cfg_name varchar(30) primary key, + cfg_value varchar(50) +); + + +create table bmsql_warehouse ( + w_id integer not null, + w_ytd decimal(12,2), + w_tax decimal(4,4), + w_name varchar(10), + w_street_1 varchar(20), + w_street_2 varchar(20), + w_city varchar(20), + w_state char(2), + w_zip char(9), + primary key(w_id) +)partition by hash(w_id) partitions 128; + +create table bmsql_district ( + d_w_id integer not null, + d_id integer not null, + d_ytd decimal(12,2), + d_tax decimal(4,4), + d_next_o_id integer, + d_name varchar(10), + d_street_1 varchar(20), + d_street_2 varchar(20), + d_city varchar(20), + d_state char(2), + d_zip char(9), + PRIMARY KEY (d_w_id, d_id) +)partition by hash(d_w_id) partitions 128; + +create table bmsql_customer ( + c_w_id integer not null, + c_d_id integer not null, + c_id integer not null, + c_discount decimal(4,4), + c_credit char(2), + c_last varchar(16), + c_first varchar(16), + c_credit_lim decimal(12,2), + c_balance decimal(12,2), + c_ytd_payment decimal(12,2), + c_payment_cnt integer, + c_delivery_cnt integer, + c_street_1 varchar(20), + c_street_2 varchar(20), + c_city varchar(20), + c_state char(2), + c_zip char(9), + c_phone char(16), + c_since timestamp, + c_middle char(2), + c_data varchar(500), + PRIMARY KEY (c_w_id, c_d_id, c_id) +)partition by hash(c_w_id) partitions 128; + + +create table bmsql_history ( + hist_id integer, + h_c_id integer, + h_c_d_id integer, + h_c_w_id integer, + h_d_id integer, + h_w_id integer, + h_date timestamp, + h_amount decimal(6,2), + h_data varchar(24) +)partition by hash(h_w_id) partitions 128; + +create table bmsql_new_order ( + no_w_id integer not null , + no_d_id integer not null, + no_o_id integer not null, + PRIMARY KEY (no_w_id, no_d_id, no_o_id) +)partition by hash(no_w_id) partitions 128; + +create table bmsql_oorder ( + o_w_id integer not null, + o_d_id integer not null, + o_id integer not null, + o_c_id integer, + o_carrier_id integer, + o_ol_cnt integer, + o_all_local integer, + o_entry_d timestamp, + PRIMARY KEY (o_w_id, o_d_id, o_id) +)partition by hash(o_w_id) partitions 128; + +create table bmsql_order_line ( + ol_w_id integer not null, + ol_d_id integer not null, + ol_o_id integer not null, + ol_number integer not null, + ol_i_id integer not null, + ol_delivery_d timestamp, + ol_amount decimal(6,2), + ol_supply_w_id integer, + ol_quantity integer, + ol_dist_info char(24), + PRIMARY KEY (ol_w_id, ol_d_id, ol_o_id, ol_number) +)partition by hash(ol_w_id) partitions 128; + +create table bmsql_item ( + i_id integer not null, + i_name varchar(24), + i_price decimal(5,2), + i_data varchar(50), + i_im_id integer, + PRIMARY KEY (i_id) +) locality='F,R{all_server}@zone0, F,R{all_server}@zone1, F,R{all_server}@zone2' duplicate_scope='cluster'; +-- ); + +create table bmsql_stock ( + s_w_id integer not null, + s_i_id integer not null, + s_quantity integer, + s_ytd integer, + s_order_cnt integer, + s_remote_cnt integer, + s_data varchar(50), + s_dist_01 char(24), + s_dist_02 char(24), + s_dist_03 char(24), + s_dist_04 char(24), + s_dist_05 char(24), + s_dist_06 char(24), + s_dist_07 char(24), + s_dist_08 char(24), + s_dist_09 char(24), + s_dist_10 char(24), + PRIMARY KEY (s_w_id, s_i_id) +)partition by hash(s_w_id) partitions 128; +``` + +第二步,为了简化实验,这边将props.ob中的变量 newOrderDistributedRate=0.01 ; + +第三步,加载数据和运行负载; + +第四步,即为实验展示与分析。 + +我们将运行的实验结果列在下方,横坐标是两种不同的 schema 方法,纵坐标表是 NewOrder 事务的每分钟的吞吐。我们可以看到不建立 tablegroup 的时候,吞吐为 61977,而建立 tablegroup 之后,吞吐提高了 3 倍左右,为 188639。可见,OceanBase 提供的 tablegroup 机制能大大提升性能。 + +![blog-first-2.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/first/blog-first-2.png) + +## 结语 + +经过上方的实验,我们可以将 OceanBase 在分布式事务的支持能力上的实验表现总结为两点: + +在良好分区下,OceanBase 能提供非常高的吞吐,表现十分优异。随着分布式事务比例的增长,OceanBase 的性能会呈现下降的趋势,这也是大多数分布式事务型数据库所面临的难题和挑战。 + +> 参考 Are Current Benchmarks Adequate to Evaluate Distributed Transactional Databases? https://doi.org/10.1016/j.tbench.2022.100031。 + +OceanBase 所提供的 tablegroup 技术能够迎合业务的需求,将数据和业务进行良好的绑定。在我们的实验中,加入 tablegroup 机制让整个吞吐上升了整整 3 倍。 diff --git "a/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234\345\233\275\344\272\247\346\225\260\346\215\256\345\272\223 OceanBase \350\207\252\347\231\275.md" "b/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234\345\233\275\344\272\247\346\225\260\346\215\256\345\272\223 OceanBase \350\207\252\347\231\275.md" new file mode 100644 index 0000000000000000000000000000000000000000..7efa2f63343cef5ffbb05ed8817b30d61dd128a0 --- /dev/null +++ "b/\345\276\200\346\234\237\345\276\201\346\226\207\345\210\206\344\272\253\357\275\234\345\233\275\344\272\247\346\225\260\346\215\256\345\272\223 OceanBase \350\207\252\347\231\275.md" @@ -0,0 +1,53 @@ +# 往期征文分享|国产数据库 OceanBase 自白 + +大家好,我是 OceanBase,截至2021年12月13日,我最新版本是3.1.1。通过官网地址可以下载,https://open.oceanbase.com/softwareCenter/community 。 + +目前有社区版和企业版,两者都是同样的内核处理引擎,但是商业版提供更多的功能服务和技术支持,保障你生产集群稳定健康的运行,当然喜欢白嫖的同事可以使用社区版,免费的东西也很香。2021年6月1日,我正式开源,这次我是认真的,生态环境在大力建设,社区在布道解惑, 我们努力构建开发者和用户生态。我的目标是打造中国人的数据库,事实上在阿里巴巴内部,我们已经成功把 Oracle替代下来,在保障业务顺利平滑的基础上,而且运行得更快。既然这么好,为什么我不出来奉献社会,发挥更大的价值空间。公司领导决定把我商业化、产品化,下面我把我的故事,我的前世今生和各位观众一一阐述。 + +2008年,信息业务的高速发展,集团感受巨大的威胁,集团对国外基础设施的需求越来越多。终于发起轰轰烈烈的去 IOE 运动,我的库生信仰很明确,那就是把 Oracle 取替下来。我的其中一个爸爸就是杨传辉,为了我还写一本书《大规模分布式存储系统》 ,里面介绍单机数据库的数据模型、事务与并发、故障恢复、存储引擎、数据压缩以及分布式数据库的数据分布、数据复制、一致性、容错性、可扩展性等工程特性,包括其它系统如分布式文件系统、分布式键值系统 、分布式列簇系统以及分布式数据相关代表作品的技术原理和架构设计,调研对象有世界 OLTP 第一的 spanner,以及 OLAP 的皇者 vertica,还有数据分析领域的的长青树 Greeplum 。我的爸爸妈妈生我的时候多少辛苦啊,那时我还不到1.0.0版本。在众多位爸爸妈妈咬牙切齿,日夜奋斗的情况下,2011年8月底,我悄悄开源,当时开源力量不是很大,所以知道的人也比较少。既然我能够开源见人,当然是已经在集团关键核心业务稳定运行的前提下。 + +虽然我开源了,但是我还没有给大众接受,因为我还有很多问题,尤其可用性和易运维性特别严重,只有阿里工程师才能操作使用这套数据库,而且阿里工程师还要努力与研发工程师配合协调一致才能够把这套数据库系统稳定下来。领导发话,这个不是世界的数据库,这只是阿里的数据库,严重违背设计我的初衷。我0.4的时候开源,但是接近1.0.0却闭源,很大一个原因是架构设计臃肿,普通工程师难以使用。当时我是由 mergeServer、UpdateServer、RootServer、ChunkServer 四大块组成,架构设计如下。 + +![blog-second-1.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/second/blog-second-1.png) + +- 客户端: 用户使用 OceanBase 的方式和 MySQL 数据库完全相同,支持 JDBC、C 客户端使用。基于 MySQL 数据库开发的应用程序、工具能够直拉迁移到 OceanBase。 + +- RootServer: 管理集群所有的服务器,子表数据分布以及副本管理,RootServer 一般为一主一备,主备之间数据强同步。 + +- UpdateServer: 存储 OceanBase 系统的增量更新数据。UpdateServer 一般为一主一备,主备之间可以配置不同的同步模式。部署时,UpdateServer 进程和 RootServer 进程可以选择共用物理服务器。 + +- ChunkServer:存储 OceanBase 系统的基线数据,基线数据一般 存储两分或者 三份,可配置。 + +- MergeServer: 接受并解析用户的 SQL 请求,经过词法分析、语法分析、查询优化等一系列操作转发给相应的我 ChunkServer 或者 UpdateServer 。如果请求的数据分布在多个 ChunkServer 上, MergeServer 还要对多个 ChunkServer 返回的结果进行合并。客户端和 MergeServer 之用原生的 MySQL 通信协议,MySQL 客户端可以直接访问 MergeServer 。 + +如果要实现异地多机房方案,每个机房部署一个包括 RootServer、MergeServer 、ChunkServer 以及 UpdateServer 的完赖 OceanBase 集群,每个集群由各自的 RootServer 负责数据划分、负载均衡、集群服务器管理等操作,集群之间数据同步通过主集群的主UpdateServer往备集群同步增量更新操作日志实现。客户端配置了多个集群的RootServer地址列表,使用者可以设置每个集群的流量分配比例,客户端根据这个比例将读写操作发往不同的集群。 +当时我非常膨胀,由于我支持双十一的高峰流量和众多产品线,我不仅性能好,还有异地容灾等强大功能,有人称我为水利工程的三峡大坝。 + +直到一天工程师带我去见客户,客户的需求是一个小水库。在方案演讲时,工程师介绍,我们都可以做到,要把这里炸掉,那里填平,运输十万吨花岗石,二十万吨钢材,客户面面相觑。 + +我才惊讶我这么多缺点,因为参考了vertica的存储机制,我在读写上解耦分离,UpdateServer专门写增量数据,ChunkServer专门读数据,UpdateServer按策略把数据写入到ChunkServer,UpdateServer有且只有一个存储服务器,一个优点是面对高并发的OLTP请求,OceanBase进行事务处理不需要跨行跨表,不需要进行任何分布式活动, 你不需要考虑 raft协义和paxios协议,不需要考虑两阶段提交,直接写进去就完了。缺点是面向OceanBase的读写请求都必须经过 UpdateServer,这个对UpdateServer提出更高的要求。为此,集团对UpdateServer进行了个性化定制软硬件改造,在内存操作、网络运行、磁盘操作方面做了大量的优化。大量的个性化使我变成了复杂的工程性作品,而不是简单的产品性作品,无法进入客户的心。 + +在深入了解民间疾苦后,我的爸爸妈妈决心在我回炉重造,不对公众开放,却有指向性对一些企业投入经营试点,例如南京银行、天津银行等等,根据客户的需求,产品更轻量级,架构重新组织,更关心交易处理时数据的完整性和数据审核性。2019年10月2日,我在TPC-C测试中打破了Oracle保持的世界纪录,以6088万tpmC值的成绩,成为首个登顶TPC-C榜单的中国数据库。 + +这时侯我的架构设计与以前大不一样了,既追求力量性能,又追求平衡协调。如下。 + +![blog-second-2.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/second/blog-second-2.png) + +淬火重铸后,我由中心化架构演变成去中心架构,过去分为紫白金青,各有所职,现在每个节点的角色都是平等的。我用上改良后的分布式一致性算法,由标准的两阶段(4次日志延心+2次RPC延迟)到OB两阶段(1次日志延迟+2次RPC延迟)。另外我使用了现在非常流行的 LSM Tree 作为存储引擎保存数据的基本数据结构,LSM Tree 更适合写多读少的应用场景。在 LSM 的基础上,我额外开发了数据分发功能 ,当内存中的数据合并到硬盘之前,我提前预先分发数据到硬盘上,这样提高了性能。 + +我的主业依然是 OLTP 业务场景,毕竟我出身电子商务世家,在我埋首闭源不见世人的时候,我经常与各个银行打交道,了解它们的业务需求并满足它们的需求。我也有一个副业 OLAP,副业是为我的主业服务,为此我的存储引擎打造就与orc一样,先按行组织排列,再按列分组,这样虽然不是100%的列式存储,但是你们不要忘了,每个数据产品的列式引擎处理时都需要加载数据,必须要ETL花费大量的时间。而我的数据是交易分析同位一体,这样省掉了大量的时间。 +这次我卷土重来,特别关注了开发者的使用体验,毕竟我是为码民服务,所以我加强了索引设计和分区设计。我有唯一索引、全局索引、本地索引,分区有我一级分区和二级分区,索引细粒度划分是让你去指定的范围去找还是整个集群去找,分区的细致划分也是电商复杂业务的需求,某些查询需要更精确的划分。同时我们提供 Oracle 和 Mysql 的协议访问,让 Oracle 和 Mysql 的开发者可以轻易接入我们。 + +我最大的一个变化是去中心化,市面上去中心化的数据产品也不少,例 如 Cassandra 和 ElasticSearch 都是去中心化,他们都有不俗的性能。为什么 Cassandra 会比 hbase 快,除了 Cassandr 副本一致性可协调策 略,Cassandr 充分使用了每个节点的IO性能,而 hbase 的 master 节点很空闲。去中心化是对外说的,对内部而某些节点上面有 rootservice,这个就是管理节点,你不用提心,如果它宕掉了会自动选择一个出来。但是去中心化有一个坏处,如何保障数据一致性和副本复制协同,我通过改良的分布性一致性算法和行业最出名的 paxos 保障这一点。paxos 理论上可比 raft、zap 等难多了,我的爸爸妈妈非常刻苦才克服了这个难题。 + +我还有一个特性是资源管理,如何把硬件资源(cpu、内存)分配到最需要数据上,如何实现不同租户之间资源分配,我都已经在数据库层面实现了,相对其它厂商都是在云上或者应用层面实现的。我这个可是了不起的亮点,试想一下僧多了,我这碗小粥也可以按需分配,不至于某些人会饿死,某些人撑得太多。 + +我是100%独立自主研发,知名 TiDB 基于 rocketsDB 研发的,而 GaussDB 也是立足 postgres9.2.4 上,我不一定是他们之中最优秀的,但可能是吃苦最多的,毕竟我从0开始,一开场我拿到手是一个 sstable 文件,这是啥玩意啊?裁判说你把它组成一个数据库,凭什么他们都有选择参考,我却要从无到有开发一个 DBMS ,裁判叼着一根雪茄,说我的使命与众不同,多年奋斗,我获得的奖项如下。 + +![blog-second-3.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/second/blog-second-3.png) + +![blog-second-4.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/blog/second/blog-second-4.png) + +下面我介绍一下我在蚂蚁集团的内部应用,首先是支付宝核心交易,支付宝最常用的模块,如交易,支付,积分等业务的核心链路都运行在 OceanBase 上,日常每秒都有上万笔交易,双十一期间,每秒可以达到几十万笔交易。支付宝是典型的在线 OLTP 数据库场景,支付宝对 OceanBase 所有核心特性进行了验证,包括响应时间、处理速度、事务的完整性、并发量等,将 OceanBase 真正打磨成了金融级数据库。从产品成熟度上来讲,证明了 OceanBase 能够承担金融在线交易的场景。国内其他的数据库产品很少有机会能够在这么大的场景下,进行实实在在的打磨。第二个应用收藏夹是典型的“写少读多”场景(一次写入、多次读取),峰值的数据读取请求量达到数百万次/秒;而且,由于淘宝巨大的活跃用户体量,这些读请求要访问几个数据量很大的表才能拿到所需数据,其中最大的表保存了数千亿条记录。OceanBase 数据库借助完备的分布式事务能力、完备的 SQL 引擎、优异的性能以及线性水平扩展等能力,很好地解决了海量数据下的在线、高并发、低延时查询等等需求,为数亿淘宝用户提供了良好的使用体验。 + +2013年斯诺登事件,2018年孟晚舟事件,老外靠不住,国货当自强,敢做领头羊,我是 OceanBase,我是中国人打造的数据库,从复杂工程级走到简单产品级,以后我会努力走下去,走入千万家,谢谢大家。