Mysql分庫分表方案之spider存儲引擎(一)

1.什麼是Spider?

SpiderMariaDB10.0.4版本開始引入的存儲引擎,最近更新版本是MariaDB 10.3.4Spider內置分片(sharding)特性,還支持分區(partition)和XA兩階段分佈式事務,而且能夠把不一樣實例上的表看成一個實例上的表處理。node

2.Spider基本實現原理

當咱們在Spider引擎上建立一個表時,這個表會被連接到一個遠程服務器上,這個遠程服務器的存儲引擎能夠是任何類型。具體來講,表連接是經過創建從本地Mariadb服務​器到遠程Mariadb服務器的鏈接來實現的。連接對於同一個事務的全部表都是共享的。mysql

3. 使用

3.1 基本使用

經過使用Create tableComment和/或者Connection子句傳遞遠程服務器的信息,咱們能夠建立一個spider存儲引擎格式的表。linux

好比遠程服務器上存在下面這個表(這個遠程節點是用Mysql Sandbox工具建立的,這個工具可以很容易的建立多個實例):算法

node1 >CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id));
複製代碼

在本地服務器上,可使用以下命令建立一個表:sql

CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id)
)
ENGINE=SPIDER 
COMMENT 'host "127.0.0.1", user "msandbox", password "msandbox", port "8607"';
複製代碼

如今咱們就能夠在本地服務器(spider服務器)上插入一條記錄,這條記錄最終會被保存到相應的遠程服務器上:數據庫

INSERT INTO s(code) VALUES ('a');

node1 > SELECT * FROM s;
+----+------+
| id | code |
+----+------+
|  1 | a    |
+----+------+
複製代碼

進階示例

準備

  1. 使用sysbench工具,準備1000萬條數據:
/usr/local/skysql/sysbench/bin/sysbench --test=oltp  --db-driver=mysql  --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.202 --mysql-port=5054 --oltp-table-size=10000000  --mysql-db=test  prepare
複製代碼
  1. 咱們首先進行第一個基準測試,來檢查一個剛初始化的單一節點的性能:
/usr/local/skysql/sysbench/bin/sysbench --test=oltp  --db-driver=mysql  --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.202 --mysql-port=5054 --mysql-db=test --oltp-table-size=10000000 --num-threads=4 --max-requests=100000 --oltp-read-only=on run
複製代碼

測試結果以下:後端

sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 4

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 100000
Threads started!
Done.

OLTP test statistics:
    queries performed:
        read:                            1400196
        write:                           0
        other:                           200028
        total:                           1600224
    transactions:                        100014 (1095.83 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 1400196 (15341.58 per sec.)
    other operations:                    200028 (2191.65 per sec.)

Test execution summary:
    total time:                          91.2681s
    total number of events:              100014
    total time taken by event execution: 364.3693
    per-request statistics:
         min:                                  1.85ms
         avg:                                  3.64ms
         max:                                 30.70ms
         approx.  95 percentile:               4.66ms

Threads fairness:
    events (avg/stddev):           25003.5000/84.78
    execution time (avg/stddev):   91.0923/0.00
複製代碼
  1. 接下來爲了測試方便,經過別名定義一個訪問mariadb或者mysql客戶端的快捷方式:
alias backend1='/usr/local/skysql/mysql-client/bin/mysql --user=skysql --password=skyvodka --host=192.168.0.202 --port=5054'
alias backend2='/usr/local/skysql/mysql-client/bin/mysql --user=skysql --password=skyvodka --host=192.168.0.203 --port=5054' 
alias spider1='/usr/local/skysql/mysql-client/bin/mysql --user=skysql --password=skyvodka --host=192.168.0.201 --port=5054' 

複製代碼
  1. 在全部backend節點上重複建立存儲數據所用的數據庫和空表
backend1 << EOF 
CREATE DATABASE backend;
CREATE TABLE backend.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF

backend2 << EOF 
CREATE DATABASE backend;
CREATE TABLE backend.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF
複製代碼

Spider支持的不一樣集羣模式

1. Federation Setup模式

Federation Setup模式

  1. spider1節點上定義backend服務器配置信息
  2. spider1節點上建立與backend服務器連接的表,經過comment定義服務器,表的存儲引擎要爲spider
spider1 << EOF
CREATE SERVER backend 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.202', 
  DATABASE 'test',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);

CREATE  TABLE test.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql",srv "backend"';
SELECT * FROM test.sbtest LIMIT 10;
EOF

複製代碼

性能測試

在沒有鏈接池或者mariadb線程池的狀況下,HaProxyspider一直在保護TCP套接字溢出,而沒有進行特定的TCP調整。在現實中,對於調優良好的TCP堆棧或線程池,曲線不該如此忽然地減小到0。請參閱[Mariadb線程池](Refer to the MariaDB Thread Pool to explore this feature)以瞭解此功能.bash

2. 分片模式

分片模式架構圖

  1. 在spider上配置backend1,相似Federation模式中的配置backend
  2. 在spider上配置backend2,同上
  3. 建立須要分片的表,與Federation模式的區別時增長了分區配置
#spider1 << EOF
CREATE SERVER backend1 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.202', 
  DATABASE 'backend',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE SERVER backend2 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.203', 
  DATABASE 'backend',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE DATABASE IF NOT EXISTS backend;
CREATE  TABLE backend.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1"',
 PARTITION pt2 COMMENT = 'srv "backend2"' 
) ;
EOF
複製代碼
性能測試
  1. 把最初的sysbench表裏的數據拷貝到spider表裏
#/usr/local/skysql/mariadb/bin/mysqldump --user=skysql --password=skyvodka --host=192.168.0.202 --port=5054 --no-create-info test sbtest | spider1 backend 

#backend2 -e"select count(*) from backend.sbtest;"
+----------+
| count(*) |
+----------+
|  3793316 |
+----------+
#backend1 -e"select count(*) from backend.sbtest;"
+----------+
| count(*) |
+----------+
|  6206684 |
+----------+
複製代碼

咱們觀察到分區的一個常見問題是基於分區鍵散列算法,形成的後端之間的數據分佈不均勻。服務器

  1. 使用更少的查詢進行基準測試
#/usr/local/skysql/sysbench/bin/sysbench --test=oltp --db-driver=mysql --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.201 --mysql-port=5054 --mysql-db=backend --mysql-engine-trx=yes --oltp-table-size=10000000 --num-threads=4 --max-requests=100 --oltp-read-only=on run
複製代碼

結果以下:網絡

OLTP test statistics:
    queries performed:
        read:                            1414
        write:                           0
        other:                           202
        total:                           1616
    transactions:                        101    (22.95 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 1414   (321.30 per sec.)
    other operations:                    202    (45.90 per sec.)

Test execution summary:
    total time:                          4.4009s
    total number of events:              101
    total time taken by event execution: 17.2960
    per-request statistics:
         min:                                114.48ms
         avg:                                171.25ms
         max:                                200.98ms
         approx.  95 percentile:             195.12ms

Threads fairness:
    events (avg/stddev):           25.2500/0.43
    execution time (avg/stddev):   4.3240/0.04
複製代碼

響應時間減小到了0.04。正如預期,由於查詢延遲是由多個網絡往返增長的,而且條件下推還沒有實現。sysbench執行了大量的範圍查詢。如今考慮一下,這個範圍查詢多是一個比較差的優化查詢。

咱們須要提升併發度以得到更好的吞吐量

分片模式性能
相關文章
相關標籤/搜索