StoneDB讀寫分離實踐方案

来源:https://www.cnblogs.com/yangwilly/archive/2022/10/10/16776449.html
-Advertisement-
Play Games

在 StoneDB 1.0 版本中,InnoDB 引擎處理 OLTP 的事務型業務,Tianmu 引擎處理 OLAP 的分析型業務。因此,需要在主從複製環境的基礎上做讀寫分離,所有的寫操作和部分讀操作走 InnoDB 引擎,所有的分析類查詢走 Tianmu 引擎。讀寫分離方案既可以使用第三方中間件, ...


在 StoneDB 1.0 版本中,InnoDB 引擎處理 OLTP 的事務型業務,Tianmu 引擎處理 OLAP 的分析型業務。因此,需要在主從複製環境的基礎上做讀寫分離,所有的寫操作和部分讀操作走 InnoDB 引擎,所有的分析類查詢走 Tianmu 引擎。讀寫分離方案既可以使用第三方中間件,也可以在業務前端實現。本文介紹的是較為常用的中間件 ProxySQL。

伺服器配置說明

IP Memory CPU OS version
192.168.30.40 8G 8C CentOS Linux release 7.9
192.168.30.41 8G 8C CentOS Linux release 7.9
192.168.30.42 8G 8C CentOS Linux release 7.9
192.168.30.46 16G 16C CentOS Linux release 7.9

註:主從環境中的各個伺服器的配置一般情況下建議是一致的,但由於 StoneDB 不管重放 binlog,還是用於 OLAP 場景的查詢,都是較消耗系統資源的,建議 StoneDB 配置略高於 MySQL。

主從環境說明

IP DATABASE ROLE DB version
192.168.30.40 MySQL master MySQL 5.7
192.168.30.41 / ProxySQL /
192.168.30.42 MySQL slave MySQL 5.7
192.168.30.46 StoneDB slave StoneDB 5.7

註:MySQL 與 StoneDB 的版本建議保持一致。

架構圖說明
file
推薦採用一主兩從的架構,上層的 ProxySQL 用於讀寫分離:

1)master(192.168.30.40)使用 InnoDB 引擎,可讀寫,提供 OLTP 場景的讀寫業務;
2)slave1(192.168.30.42)使用 InnoDB 引擎,只讀,同時作為 standby,當 master 發生宕機時,可切換至 slave1,保證業務正常運行;
3)slave2(192.168.30.46)使用 Tianmu 引擎,只讀,提供 OLAP 場景的讀業務。

1、操作系統環境檢查

操作系統環境檢查的步驟在四個節點均需要執行。

1.1 關閉防火牆

# systemctl stop firewalld 
# systemctl disable firewalld

1.2 關閉SELINUX

# vim /etc/selinux/config
SELINUX = disabled

1.3 設置Swap分區

修改vm.swappiness的值為1,表示儘量不使用Swap。

# vi /etc/sysctl.conf
vm.swappiness = 1

1.4 修改操作系統的限制

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 1031433
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

修改操作系統的軟硬限制
# vim /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
mysql soft nproc 1028056
mysql hard nproc 1028056

1.5 創建用戶

# groupadd mysql
# useradd -g mysql mysql
# passwd mysql

ProxySQL 節點無需創建,以上步驟執行完之後,重啟操作系統。

2、部署MySQL

在 master 節點和 slave1 節點安裝 MySQL。

2.1 下載安裝包

https://downloads.mysql.com/archives/community/
從官網下載 MySQL 5.7 的安裝包。

2.2 卸載mariadb

# rpm -qa|grep mariadb
mariadb-5.5.56-2.el7.x86_64
mariadb-server-5.5.56-2.el7.x86_64
mariadb-libs-5.5.56-2.el7.x86_64
# yum remove mariadb*
# rpm -qa|grep mariadb

2.3 上傳tar包並解壓

# tar -zxvf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
# cd /usr/local/
# mv mysql-5.7.36-linux-glibc2.12-x86_64 mysql

2.4 創建目錄

# mkdir -p /mysql/data/
# mkdir -p /mysql/log
# chown -R mysql:mysql /mysql/

2.5 配置參數文件 my.cnf

master

# vim /etc/my.cnf
[client]
port    = 3306
socket  = /mysql/data/mysql.sock

[mysqld]
port      = 3306
basedir   = /usr/local/mysql
datadir   = /mysql/data
socket    = /mysql/data/mysql.sock
pid_file  = /mysql/data/mysqld.pid
log_error = /mysql/log/mysqld.log
log_bin   = /mysql/log/mybinlog
server_id = 40
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
max_connections = 1000
binlog_format = row
default_storage_engine = innodb
read_only=0

innodb_buffer_pool_size = 4096000000
innodb_log_file_size = 1024000000
innodb_log_files_in_group = 3
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000

#開啟GTID模式
gtid_mode = on
enforce_gtid_consistency = 1

#並行複製
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction = XXHASH64

slave1

# vim /etc/my.cnf
[client]
port    = 3306
socket  = /mysql/data/mysql.sock

[mysqld]
port      = 3306
basedir   = /usr/local/mysql
datadir   = /mysql/data
socket    = /mysql/data/mysql.sock
pid_file  = /mysql/data/mysqld.pid
log_error = /mysql/log/mysqld.log
log_bin   = /mysql/log/mybinlog
server_id = 42
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
max_connections = 1000
binlog_format = row
default_storage_engine = innodb
read_only=1

innodb_buffer_pool_size = 4096000000
innodb_log_file_size = 1024000000
innodb_log_files_in_group = 3
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000

#開啟GTID模式
gtid_mode = on
enforce_gtid_consistency = 1

#並行複製
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 4

2.6 初始化實例

/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql

2.7 啟動實例

/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

註:管理員用戶的臨時密碼在 mysqld.log 中,第一次登陸後需要修改管理員用戶的密碼。

3、部署StoneDB

3.1 下載安裝包

https://stonedb.io/zh/docs/download/
從官網下載 StoneDB 5.7 的安裝包。

3.2 上傳tar包並解壓

# cd /
# tar -zxvf stonedb-ce-5.7-v1.0.0.el7.x86_64.tar.gz

用戶可根據安裝規範將安裝包上傳至伺服器,解壓出來的目錄是 stonedb57,示例中的安裝路徑是 /stonedb57。

3.3 檢查依賴文件

# cd /stonedb57/install/bin
# ldd mysqld
# ldd mysql

如果檢查返回有關鍵字"not found",說明缺少文件,需要安裝對應的依賴包。例如:

libsnappy.so.1 => not found

在 Ubuntu 上使用命令 "sudo apt search libsnappy" 檢查,說明需要安裝 libsnappy-dev。在 RedHat 或者 CentOS 上使用命令 "yum search all snappy" 檢查,說明需要安裝 snappy-devel、snappy。

3.4 創建目錄

mkdir -p /stonedb57/install/data
mkdir -p /stonedb57/install/binlog
mkdir -p /stonedb57/install/log
mkdir -p /stonedb57/install/tmp
mkdir -p /stonedb57/install/redolog
mkdir -p /stonedb57/install/undolog
chown -R mysql:mysql /stonedb57

3.5 配置參數文件 my.cnf

# vim /stonedb57/install/my.cnf
[client]
port    = 3306
socket  = /stonedb57/install/tmp/mysql.sock

[mysqld]
port      = 3306
basedir   = /stonedb57/install/
datadir   = /stonedb57/install/data
socket    = /stonedb57/install/tmp/mysql.sock
pid_file  = /stonedb57/install/data/mysqld.pid
log_error = /stonedb57/install/log/mysqld.log
log_bin   = /stonedb57/install/binlog/binlog
server_id = 46
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
max_connections = 1000
binlog_format = row
default_storage_engine = tianmu
read_only=1

innodb_buffer_pool_size = 2048000000
innodb_log_file_size = 1024000000
innodb_log_files_in_group = 3
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_log_group_home_dir   = /stonedb57/install/redolog/
innodb_undo_directory       = /stonedb57/install/undolog/
innodb_undo_log_truncate    = 1
innodb_undo_tablespaces     = 3
innodb_undo_logs            = 128

#開啟GTID模式
gtid_mode = on
enforce_gtid_consistency = 1

#並行複製
slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 8  

3.6 初始化實例

/stonedb57/install/bin/mysqld --defaults-file=/stonedb57/install/my.cnf --initialize --user=mysql

3.7 啟動實例

/stonedb57/install/bin/mysqld_safe --defaults-file=/stonedb57/install/my.cnf --user=mysql &

註:管理員用戶的臨時密碼在 mysqld.log 中,第一次登陸後需要修改管理員用戶的密碼。

4、配置主從

4.1 創建複製用戶

create user 'repl'@'%' identified by 'mysql123';
grant replication slave on *.* to 'repl'@'%';

4.2 備份主庫

/usr/local/mysql/bin/mysqldump -uroot -pmysql123 --single-transaction --set-gtid-purged=on -B aa > /tmp/aa.sql

4.3 傳輸備份文件

scp /tmp/aa.sql [email protected]:/tmp
scp /tmp/aa.sql [email protected]:/tmp

註:如果數據較大,建議使用 mydumper.

4.4 slave1節點

/usr/local/mysql/bin/mysql -uroot -pmysql123 -S /mysqldb/data/mysql.sock
source /tmp/aa.sql

註:恢復前需要確保 gtid_executed 為空。

4.5 slave2節點

在恢復前,需要修改存儲引擎,註釋鎖表語句。

sed -i 's/UNLOCK TABLES/-- UNLOCK TABLES/g' /tmp/aa.sql
sed -i 's/LOCK TABLES `/-- LOCK TABLES `/g' /tmp/aa.sql
sed -i 's/ENGINE=InnoDB/ENGINE=tianmu/g' /tmp/aa.sql

/stonedb57/install/bin/mysql -uroot -pmysql123 -S /stonedb57/install/tmp/mysql.sock
source /tmp/aa.sql

註:恢復前需要確保 gtid_executed 為空。

4.6 建立主從複製

slave1節點

CHANGE MASTER TO
MASTER_HOST='192.168.30.40',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='mysql123',
MASTER_AUTO_POSITION = 1;

start slave;
show slave status\G

slave2節點

CHANGE MASTER TO
MASTER_HOST='192.168.30.40',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='mysql123',
MASTER_AUTO_POSITION = 1;

start slave;
show slave status\G

5、配置ProxySQL

5.1 安裝ProxySQL

# mkdir -p /home/ProxySQL
# cd /home/ProxySQL
# yum install proxysql-2.2.0-1-centos7.x86_64.rpm
# rpm -qa|grep proxysql
# rpm -ql proxysql

註:/etc/proxysql.cnf 為 ProxySQL 的配置文件。

5.2 啟動ProxySQL

# systemctl start proxysql
# netstat -lntp|grep proxysql
tcp        0      0 0.0.0.0:6032            0.0.0.0:*               LISTEN      17957/proxysql      
tcp        0      0 0.0.0.0:6033            0.0.0.0:*               LISTEN      17957/proxysql 

註:6032是管理埠,6033是服務埠。

5.3 管理員登錄ProxySQL

# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt='ProxySQL>'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

ProxySQL>show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | disk          | /var/lib/proxysql/proxysql.db       |
| 3   | stats         |                                     |
| 4   | monitor       |                                     |
| 5   | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+
5 rows in set (0.00 sec)

註:ProxySQL 的用戶名和密碼預設都是 admin,加參數 prompt 是為了便於區分環境。

5.4 創建ProxySQL所需用戶

在 master 上創建 ProxySQL 的監控用戶和對外訪問用戶,其中監控用戶只需要有 replication client 許可權即可。

###監控用戶
create user 'monitor'@'%' identified by 'MySQL_123';
grant replication client on *.* to 'monitor'@'%';

###對外訪問用戶(用於連接ProxySQL)
create user 'proxysql'@'%' identified by 'MySQL_123';
grant select,delete,update,insert on *.* to 'proxysql'@'%';

5.5 配置ProxySQL主從分組信息

1)創建分組

表 mysql_replication_hostgroups 的欄位 writer_hostgroup、reader_hostgroup 分別代表寫組和讀組,都要大於0且不能相同,該環境中定義寫組為10,讀組為20。

ProxySQL 會根據 read_only 的取值將 server 進行分組,read_only=0為 master,被分到編號為10的寫組,read_only=1為 slave,被分到編號為20的讀組。

###創建分組
insert into mysql_replication_hostgroups(writer_hostgroup,reader_hostgroup,comment) values(10,20,'proxy');
load mysql servers to runtime;
save mysql servers to disk;

###查看三層配置系統是否都寫入數據
ProxySQL>select * from mysql_replication_hostgroups;
+------------------+------------------+------------+---------+
| writer_hostgroup | reader_hostgroup | check_type | comment |
+------------------+------------------+------------+---------+
| 10               | 20               | read_only  | proxy   |
+------------------+------------------+------------+---------+
1 row in set (0.00 sec)

ProxySQL>select * from runtime_mysql_replication_hostgroups;
+------------------+------------------+------------+---------+
| writer_hostgroup | reader_hostgroup | check_type | comment |
+------------------+------------------+------------+---------+
| 10               | 20               | read_only  | proxy   |
+------------------+------------------+------------+---------+
1 row in set (0.00 sec)

ProxySQL>select * from mysql_replication_hostgroups;
+------------------+------------------+------------+---------+
| writer_hostgroup | reader_hostgroup | check_type | comment |
+------------------+------------------+------------+---------+
| 10               | 20               | read_only  | proxy   |
+------------------+------------------+------------+---------+
1 row in set (0.00 sec)

2)添加主從節點

insert into mysql_servers(hostgroup_id,hostname,port) values(10,'192.168.30.40',3306);
insert into mysql_servers(hostgroup_id,hostname,port) values(20,'192.168.30.46',3306);
load mysql servers to runtime;
save mysql servers to disk;

###查看狀態
ProxySQL>select * from mysql_servers;
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| hostgroup_id | hostname      | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
| 20           | 192.168.30.40 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
| 20           | 192.168.30.46 | 3306 | 0         | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              |         |
+--------------+---------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+
2 rows in set (0.00 sec)

3)為ProxySQL創建監控用戶

###創建監控用戶(在ProxySQL創建)
set mysql-monitor_username='monitor';
set mysql-monitor_password='MySQL_123';
load mysql variables to runtime;
save mysql variables to disk;

###對連接用戶監控
ProxySQL>select * from monitor.mysql_server_connect_log;
+---------------+------+------------------+-------------------------+------------------------------------------------------------------------+
| hostname      | port | time_start_us    | connect_success_time_us | connect_error                                                          |
+---------------+------+------------------+-------------------------+------------------------------------------------------------------------+
| 192.168.30.40 | 3306 | 1664183920198998 | 0                       | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183920926981 | 0                       | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.46 | 3306 | 1664183970671663 | 1616                    | NULL                                                                   |
| 192.168.30.40 | 3306 | 1664183971672625 | 2089                    | NULL                                                                   |
+---------------+------+------------------+-------------------------+------------------------------------------------------------------------+
4 rows in set (0.00 sec)

註:在沒有創建監控用戶前,會有很多的connect_error,這是因為沒有配置監控信息時的錯誤,配置後如果connect_error的結果為NULL,則表示正常。

###對心跳信息的監控
ProxySQL>select * from mysql_server_ping_log limit 10;
+---------------+------+------------------+----------------------+------------------------------------------------------------------------+
| hostname      | port | time_start_us    | ping_success_time_us | ping_error                                                             |
+---------------+------+------------------+----------------------+------------------------------------------------------------------------+
| 192.168.30.40 | 3306 | 1664183880229349 | 0                    | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183880427787 | 0                    | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183890229405 | 0                    | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183890336793 | 0                    | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183900229529 | 0                    | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183900357491 | 0                    | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.46 | 3306 | 1664183910229710 | 0                    | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183910406115 | 0                    | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183920229740 | 0                    | Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183920346638 | 0                    | Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
+---------------+------+------------------+----------------------+------------------------------------------------------------------------+
10 rows in set (0.00 sec)

###對read_only值監控
ProxySQL>select * from mysql_server_read_only_log limit 10;
+---------------+------+------------------+-----------------+-----------+------------------------------------------------------------------------------------------------------------+
| hostname      | port | time_start_us    | success_time_us | read_only | error                                                                                                      |
+---------------+------+------------------+-----------------+-----------+------------------------------------------------------------------------------------------------------------+
| 192.168.30.46 | 3306 | 1664183876942878 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183876961694 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183878441697 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183878461063 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183879941587 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183879961993 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183881441750 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
| 192.168.30.40 | 3306 | 1664183881461890 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.40 | 3306 | 1664183882942044 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'192.168.30.41' (using password: YES) |
| 192.168.30.46 | 3306 | 1664183882958866 | 0               | NULL      | timeout on creating new connection: Access denied for user 'monitor'@'HAMI02' (using password: YES)        |
+---------------+------+------------------+-----------------+-----------+------------------------------------------------------------------------------------------------------------+
10 rows in set (0.00 sec)

註:monitor就會開始監控後端的read_only值,然後按照read_only的值將某些節點自動移到讀寫組。

4)為ProxySQL配置對外訪問用戶

insert into mysql_users(username,password,default_hostgroup) values('proxysql','MySQL_123',10);
insert into mysql_users(username,password,default_hostgroup) values('proxysql2','*0815E74A768849A6CCF0E9C1C5B940FB4D9F839E',20);
load mysql users to runtime;
save mysql users to disk;

ProxySQL>select * from mysql_users\G
*************************** 1. row ***************************
              username: proxysql
              password: MySQL_123
                active: 1
               use_ssl: 0
     default_hostgroup: 10
        default_schema: NULL
         schema_locked: 0
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000
            attributes: 
               comment: 
*************************** 2. row ***************************
              username: proxysql2
              password: *0815E74A768849A6CCF0E9C1C5B940FB4D9F839E
                active: 1
               use_ssl: 0
     default_hostgroup: 20
        default_schema: NULL
         schema_locked: 0
transaction_persistent: 1
          fast_forward: 0
               backend: 1
              frontend: 1
       max_connections: 10000
            attributes: 
               comment: 
2 rows in set (0.00 sec)

mysql_users 表最主要的三個欄位 username、password、default_hostgroup 解釋。

username:前端連接 ProxySQL 的資料庫用戶

password:用戶對應的密碼,即可以是明文密碼,也可以是 hash 密碼,如果想使用 hash 密碼,可以先在某個節點上執行 select password('password'),然後將加密結果複製到該欄位。

default_hostgroup:用戶預設的路由目標,例如:若用戶 proxysql2 是個只讀用戶,則該欄位值可以設置為20,表示所有的SQL語句預設情況下將路由到 hostgroup_id=20 的組;若用戶不是只讀用戶,則該欄位必須設置為10,表示 DML 語句會路由到 hostgroup_id=10 的組,查詢語句即會路由到 hostgroup_id=10 的組,也會路由到 hostgroup_id=20 的組。

5.6 配置讀寫分離策略

ProxySQL 的路由規則配置比較靈活,可以基於用戶級別,資料庫級別等。由於 StoneDB 提供的是 OLAP 分析型查詢業務場景,建議將聚合類查詢、即席查詢、複雜查詢等分發到 StoneDB。由於只是測試,因此只配置了幾個簡單的路由規則。

與查詢規則有關的表有兩個:mysql_query_rules 和 mysql_query_rules_fast_routing,表mysql_query_rules_fast_routing 是 mysql_query_rules 的擴展,併在以後評估快速路由策略和屬性(僅在ProxySQL 1.4.7+中可用)。

mysql_query_rules 表的幾個欄位解釋。

active:是否啟用這個規則,1表示啟用,0表示禁用

match_pattern:設置規則

destination_hostgroup:預設指定的分組

apply:真正執行應用規則

###創建規則
這裡我創建兩個規則:
1)把所有以select開頭的語句分配到編號為20的讀組中;
2)把select...for update語句分配到編號為10的寫組中,其他所有操作都會預設路由到寫組。
insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(1,1,'^select.*for update$',10,1);
insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(2,1,'^select',20,1);
insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(3,1,'^select*sum',20,1);
load mysql query rules to runtime;
save mysql query rules to disk;

###查看規則
ProxySQL>select * from mysql_query_rules\G
*************************** 1. row ***************************
              rule_id: 1
               active: 1
             username: NULL
           schemaname: NULL
               flagIN: 0
          client_addr: NULL
           proxy_addr: NULL
           proxy_port: NULL
               digest: NULL
         match_digest: NULL
        match_pattern: ^select.*for update$
 negate_match_pattern: 0
         re_modifiers: CASELESS
              flagOUT: NULL
      replace_pattern: NULL
destination_hostgroup: 10
            cache_ttl: NULL
   cache_empty_result: NULL
        cache_timeout: NULL
            reconnect: NULL
              timeout: NULL
              retries: NULL
                delay: NULL
    next_query_flagIN: NULL
       mirror_flagOUT: NULL
     mirror_hostgroup: NULL
            error_msg: NULL
               OK_msg: NULL
          sticky_conn: NULL
            multiplex: NULL
  gtid_from_hostgroup: NULL
                  log: NULL
                apply: 1
           attributes: 
              comment: NULL
*************************** 2. row ***************************
              rule_id: 2
               active: 1
             username: NULL
           schemaname: NULL
               flagIN: 0
          client_addr: NULL
           proxy_addr: NULL
           proxy_port: NULL
               digest: NULL
         match_digest: NULL
        match_pattern: ^select
 negate_match_pattern: 0
         re_modifiers: CASELESS
              flagOUT: NULL
      replace_pattern: NULL
destination_hostgroup: 20
            cache_ttl: NULL
   cache_empty_result: NULL
        cache_timeout: NULL
            reconnect: NULL
              timeout: NULL
              retries: NULL
                delay: NULL
    next_query_flagIN: NULL
       mirror_flagOUT: NULL
     mirror_hostgroup: NULL
            error_msg: NULL
               OK_msg: NULL
          sticky_conn: NULL
            multiplex: NULL
  gtid_from_hostgroup: NULL
                  log: NULL
                apply: 1
           attributes: 
              comment: NULL
*************************** 3. row ***************************
              rule_id: 3
               active: 1
             username: NULL
           schemaname: NULL
               flagIN: 0
          client_addr: NULL
           proxy_addr: NULL
           proxy_port: NULL
               digest: NULL
         match_digest: NULL
        match_pattern: ^select*sum
 negate_match_pattern: 0
         re_modifiers: CASELESS
              flagOUT: NULL
      replace_pattern: NULL
destination_hostgroup: 20
            cache_ttl: NULL
   cache_empty_result: NULL
        cache_timeout: NULL
            reconnect: NULL
              timeout: NULL
              retries: NULL
                delay: NULL
    next_query_flagIN: NULL
       mirror_flagOUT: NULL
     mirror_hostgroup: NULL
            error_msg: NULL
               OK_msg: NULL
          sticky_conn: NULL
            multiplex: NULL
  gtid_from_hostgroup: NULL
                  log: NULL
                apply: 1
           attributes: 
              comment: NULL
3 rows in set (0.00 sec)

註:select...for update 規則的 rule_id 必須要小於普通的 select 規則的 rule_id,因為 ProxySQL 是根據 rule_id的順序進行規則匹配的。

5.7 讀寫分離測試

1)讀操作

# mysql -uproxysql -pMySQL_123 -h127.0.0.1 -P6033
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.30 (ProxySQL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

proxysql@HAMI02 17:21:  [(none)]> select sum(money) from aa.ttt;
+------------+
| sum(money) |
+------------+
|    88888.8 |
+------------+
1 row in set (0.01 sec)

proxysql@HAMI02 17:21:  [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          46 |
+-------------+
1 row in set (0.00 sec)

2)寫操作

# mysql -uproxysql -pMySQL_123 -h127.0.0.1 -P6033
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 5.5.30 (ProxySQL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

proxysql@HAMI02 19:53:  [(none)]> begin;
Query OK, 0 rows affected (0.00 sec)

proxysql@HAMI02 19:54:  [(none)]> insert into aa.t1 values(7);
Query OK, 1 row affected (0.00 sec)

proxysql@HAMI02 19:54:  [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|          40 |
+-------------+
1 row in set (0.00 sec)

6、建議項

1)建議設置為 GTID 模式,好處是從庫發生 crash 後,不需要去找位點,系統會自動拉起複制線程;

2)在從庫的並行 worker 相同的情況下,從庫 StoneDB 相比從庫 InnoDB 會消耗更多的CPU資源,如果未來上生產環境,建議 StoneDB 的配置略比 InnoDB 的配置高;

3)若從庫 StoneDB 的延遲較高,可臨時關閉參數 tianmu_enable_rowstore,待追上主庫後再開啟參數。關閉該參數帶來的風險是如果在同步過程中 StoneDB 發生重啟,重啟後會出現丟數據的情況;

4)建議將聚合類查詢、即席查詢、複雜查詢等分發到 StoneDB。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 很多使用泛型的小伙伴,都會有一個疑惑:為什麼有的方法返回值前帶<T>、<K, V>之類的標記,而有的方法返回值前又什麼都不帶呢?就像這樣: // 實體基類 class Entity { public String toString() { return "Entity"; } } // 用戶類 cl ...
  • 一:背景 1.講故事 最近分享了好幾篇關於 非托管記憶體泄漏 的文章,有時候就是這麼神奇,來求助的都是這類型的dump,一飲一啄,莫非前定。讓我被迫加深對 NT堆, 頁堆 的理解,這一篇就給大家再帶來一篇記憶體泄漏。 前段時間有位朋友找到我,說他的程式出現了非托管泄漏,某一塊的操作會導致非托管記憶體上漲的 ...
  • ​ 本周MASA Framework 進行了第四次課程直播,課程主題為類目管理的開發,直播中進行了理論講解和實戰演練(CQRS實踐的演示可直達推文底部觀看直播回放) 開始環節我們圍繞三個點介紹CQRS的原理 首先,我們先對之前的事件流概念進行簡單的回顧 事件風暴回顧 - 事件流 接下來到我們本節課的 ...
  • Linux目錄與路徑 1.絕對路徑與相對路徑 ​ 與Windows一樣,linux也有絕對路徑與相對路徑的區別: ​ Windows的絕對路徑是以某個盤為起點,如win的桌面的絕對路徑為: cd C:\Users\Administrator\Desktop ​ 而win的相對路徑,如桌面上有兩個文件 ...
  • Mac哪款觸控板手勢增強軟體好用呢?Multitouch mac是Mac平臺上一款mac觸控板手勢增強軟體,Multitouch mac版添加了各種不同的觸控板手勢,手指輕點、輕掃等就能快速進行操作,使用非常便捷。 詳情:Multitouch for Mac(觸控板手勢增強軟體) 簡單介紹 Mult ...
  • Mac上哪款策略游戲好玩?鋼鐵戰隊Iron Marines for mac推薦給大家,這是一款Mac平臺上好玩的策略游戲,該游戲的創作者同《王國保衛戰》三部曲相同,又是一款超凡的太空奇幻歷險之作。玩家將在游戲中指導你的部隊參加3個不同世界的21次任務,準備好發動英勇的攻擊,堅守陣地,拯救平民,潛入超 ...
  • 視圖和用戶許可權 1.視圖(view) 看一個需求 emp表的列信息很多,有些信息是個人重要信息(比如:sal、comm、mgr、hiredate),如果我們希望某個用戶只能查詢emp表的empno、enamel、job和deptno信息,有什麼辦法呢? 答案是使用視圖。 1.1基本原理 視圖是一個虛 ...
  • 我們偶爾需要在已有表,並且有數據的情況下,修改其某個欄位的類型或改變他的長度,但是因為表中有數據,所以不可以直接修改,需要換個思路。 -- Create table create table TABLE1 ( col1 number(9), col2 char(20) ); -- 嘗試修改 -- 修 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...