Proxy實現mysql讀寫分離

1. mysql實現讀寫分離的方式

mysql 實現讀寫分離的方式有以下幾種:

  • 程序修改mysql操作,直接和數據庫通信,簡單快捷的讀寫分離和隨機的方式實現的負載均衡,權限獨立分配,需要開發人員協助。
  • amoeba,直接實現讀寫分離和負載均衡,不用修改代碼,有很靈活的數據解決方案,自己分配賬戶,和後端數據庫權限管理獨立,權限處理不夠靈活。
  • mysql-proxy,直接實現讀寫分離和負載均衡,不用修改代碼,master和slave用一樣的帳號,效率低
  • mycat中間件
  • proxysql中間件(推薦使用)

2. ProxySQL簡介

ProxySQL 是一款可以實際用於生產環境的 MySQL 中間件,它有官方版和 percona 版兩種。percona版是在官方版的基礎上修改的,添加了幾個比較實用的工具。生產環境建議用官方版。

ProxySQL 是用 C++ 語言開發的,雖然也是一個輕量級產品,但性能很好(據測試,能處理千億級的數據),功能也足夠,能滿足中間件所需的絕大多數功能,包括:

  • 最基本的讀/寫分離,且方式有多種
  • 可定製基於用戶、基於schema、基於語句的規則對SQL語句進行路由。換句話說,規則很靈活。基於schema和與語句級的規則,可以實現簡單的sharding(分庫分表)
  • 可緩存查詢結果。雖然ProxySQL的緩存策略比較簡陋,但實現了基本的緩存功能,絕大多數時候也夠用了。此外,作者已經打算實現更豐富的緩存策略
  • 監控後端節點。ProxySQL可以監控後端節點的多個指標,包括:ProxySQL和後端的心跳信息,後端節點的read-only/read-write,slave和master的數據同步延遲性(replication lag)

3. ProxySQL安裝

//配置yum源
[root@proxysql ~]# cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
name= ProxySQL
baseurl=http://repo.proxysql.com/ProxySQL/proxysql-1.4.x/centos/7
gpgcheck=1
gpgkey=http://repo.proxysql.com/ProxySQL/repo_pub_key
EOF

[root@proxysql ~]# yum install mariadb -y
[root@proxysql ~]# yum install proxysql -y

4. ProxySQL的Admin管理接口

當 ProxySQL 啓動後,將監聽兩個端口:

  • admin管理接口,默認端口爲6032。該端口用於查看、配置ProxySQL
  • 接收SQL語句的接口,默認端口爲6033,這個接口類似於MySQL的3306端口

在這裏插入圖片描述
ProxySQL 的 admin 管理接口是一個使用 MySQL 協議的接口,所以,可以直接使用 mysql 客戶端、navicat 等工具去連接這個管理接口,其默認的用戶名和密碼均爲 admin

例如,使用 mysql 客戶端去連接 ProxySQL 的管理接口:

[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> 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 |
+-----+---------------+-------------------------------------+

由於 ProxySQL 的配置全部保存在幾個自帶的庫中,所以通過管理接口,可以非常方便地通過發送一些SQL命令去修改 ProxySQL 的配置。 ProxySQL 會解析通過該接口發送的某些對ProxySQL 有效的特定命令,並將其合理轉換後發送給內嵌的 SQLite3 數據庫引擎去運行

ProxySQL 的配置幾乎都是通過管理接口來操作的,通過 Admin 管理接口,可以在線修改幾乎所有的配置並使其生效。只有兩個變量的配置是必須重啓 ProxySQL 才能生效的,它們是:
mysql-threadsmysql-stacksize

5.1 admin-admin_credentials

admin-admin_credentials 變量控制的是admin管理接口的管理員賬戶。默認的管理員賬戶和密碼爲admin:admin,但是這個默認的用戶只能在本地使用。如果想要遠程連接到ProxySQL,例如用windows上的navicat連接Linux上的ProxySQL管理接口,必須自定義一個管理員賬戶。

添加管理員帳戶

查看當前用戶名和密碼
MySQL [(none)]> select @@admin-admin_credentials;
+---------------------------+
| @@admin-admin_credentials |
+---------------------------+
| admin:admin               |
+---------------------------+
//設置管理員帳號myadmin,密碼shuai.com
MySQL [(none)]> set admin-admin_credentials='admin:admin;myadmin:shuai.com';
MySQL [(none)]> select @@admin-admin_credentials;
+-------------------------------+
| @@admin-admin_credentials     |
+-------------------------------+
| admin:admin;myadmin:shuai.com |
+-------------------------------+
//使修改立即生效
MySQL [(none)]> load admin variables to runtime;
//使修改永久保存到磁盤
MySQL [(none)]> save admin variables to disk;

修改後,就可以使用該用戶名和密碼連接管理接口
[root@proxysql ~]# mysql -umyadmin -pshuai.com -h192.168.230.30 -P6032
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> 
所有的配置操作都是在修改main庫中對應的表
MySQL [(none)]> select * from global_variables where variable_name='admin-admin_credentials';
+-------------------------+-------------------------------+
| variable_name           | variable_value                |
+-------------------------+-------------------------------+
| admin-admin_credentials | admin:admin;myadmin:shuai.com |
+-------------------------+-------------------------------+

必須要區分admin管理接口的用戶名和mysql_users中的用戶名

  • admin管理接口的用戶是連接到管理接口(默認端口6032)上用來管理、配置ProxySQL的
  • mysql_users表中的用戶名是應用程序連接ProxySQL(默認端口6033),以及ProxySQL連接後端MySQL Servers使用的用戶。它的作用是發送、路由SQL語句,類似於MySQL Server的3306端口。所以,這個表中的用戶必須已經在後端MySQL Server上存在且授權了

admin管理接口的用戶必須不能存在於mysql_users中,這是出於安全的考慮,防止通過admin管理接口用戶猜出mysql_users中的用戶

5.2 admin-stats_credentials

admin-stats_credentials 變量控制admin管理接口的普通用戶,這個變量中的用戶沒有超級管理員權限,只能查看monitor庫和main庫中關於統計的數據,其它庫都是不可見的,且沒有任何寫權限

默認的普通用戶名和密碼均爲 stats ,與admin一樣,它默認也只能用於本地登錄,若想讓人遠程查看則要添加查看的專有用戶

MySQL [(none)]> select @@admin-stats_credentials;
+---------------------------+
| @@admin-stats_credentials |
+---------------------------+
| stats:stats               |
+---------------------------+
//添加專有的查看用戶
MySQL [(none)]> set admin-stats_credentials='stats:stats;mystats:shuai.com';
MySQL [(none)]> select @@admin-stats_credentials;
+-------------------------------+
| @@admin-stats_credentials     |
+-------------------------------+
| stats:stats;mystats:shuai.com |
+-------------------------------+
MySQL [(none)]> load admin variables to runtime;
MySQL [(none)]> save admin variables to disk;

使用mystats用戶遠程連接查看
這種用戶只能讀,不能寫,而且讀的表業有限
[root@proxysql ~]# mysql -umystats -pshuai.com -h192.168.230.30 -P6032
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> show databases;
+-----+---------------+-------------------------------------+
| seq | name          | file                                |
+-----+---------------+-------------------------------------+
| 0   | main          |                                     |
| 2   | monitor       |                                     |
| 3   | stats_history | /var/lib/proxysql/proxysql_stats.db |
+-----+---------------+-------------------------------------+

5.3 admin-mysql_ifaces

admin-mysql_ifaces 變量指定admin接口的監聽地址,格式爲分號分隔的hostname:port列表。默認監聽在 0.0.0.0:6032

注意,允許使用UNIX的domain socket進行監聽,這樣本主機內的應用程序就可以直接被處理。
例如:

MySQL [(none)]> SET admin-mysql_ifaces='0.0.0.0:6032;/tmp/proxysql_admin.sock';
MySQL [(none)]> load admin variables to runtime;
MySQL [(none)]> save admin variables to disk;

6. 多層配置系統

6.1 proxysql中的庫

使用ProxySQL的Admin管理接口連上ProxySQL,可查看ProxySQL擁有的庫

[root@proxysql ~]# mysql -umyadmin -pshuai.com -h192.168.230.30 -P6032
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.5.30 (ProxySQL Admin Module)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]> 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 |
+-----+---------------+-------------------------------------+

其中:

  • main庫是ProxySQL最主要的庫,是需要修改配置時使用的庫,它其實是一個內存數據庫系統。所以,修改main庫中的配置後,必須將其持久化到disk上才能永久保存
  • disk庫是磁盤數據庫,該數據庫結構和內存數據庫完全一致。當持久化內存數據庫中的配置時,其實就是寫入到disk庫中。磁盤數據庫的默認路徑爲 $DATADIR/proxysql.db
  • stats庫是統計信息庫。這個庫中的數據一般是在檢索其內數據時臨時填充的,它保存在內存中。因爲沒有相關的配置項,所以無需持久化
  • monitor庫是監控後端MySQL節點相關的庫,該庫中只有幾個log類的表,監控模塊收集到的監控信息全都存放到對應的log表中
  • stats_history庫是1.4.4版新增的庫,用於存放歷史統計數據。默認路徑爲 $DATADIR/proxysql_stats.db

ProxySQL 內部使用的是 SQLite3 數據庫,無論是內存數據庫還是磁盤數據庫,都是通過SQLite3引 擎進行解析、操作的。它和 MySQL 的語法可能稍有不同,但ProxySQL會對不兼容的語法自動進行調整,最大程度上保證MySQL語句的有效率。
上面描述main庫的時候,只是說了內存數據庫需要持久化到disk庫才能永久保存配置。但實際上,修改了main庫中的配置後,並不會立即生效,它還需要load到runtime的數據結構中才生效,只有在runtime數據結構中的配置纔是對ProxySQL當前有效的配置

6.2 ProxySQL多層配置系統

ProxySQL 的配置系統非常強大,它能在線修改幾乎所有配置(僅有的兩個需要重啓才能生效的變量爲 mysql-threads 和 mysql-stacksize ),並在線生效、持久化保存。這得益於它採用的多層配置系統。
多層配置系統結構如下:

       +-------------------------+
       |         RUNTIME         |
       +-------------------------+
              /|\          |
               |           |
           [1] |       [2] |
               |          \|/
       +-------------------------+
       |         MEMORY          |
       +-------------------------+ _
              /|\          |      |\
               |           |        \
           [3] |       [4] |         \ [5]
               |          \|/         \
       +-------------------------+  +---------------+
       |          DISK           |  |  CONFIG FILE  |
       +-------------------------+  +---------------+

最底層的是 disk 庫和 config file 。這裏需要注意,這裏的 config file 就是傳統的配置文件,默認爲 /etc/proxysql.cnf , ProxySQL 啓動時,主要是從 disk 庫中讀取配置加載到內存並最終加載到 runtime 生效,只有極少的幾個特定配置內容是從 config file 中加載的,除非是第一次初始化 ProxySQL 運行環境(或者disk庫爲空)。

中間層的是 memory ,表示的是內存數據庫,其實就是 main 庫。通過管理接口修改的所有配置,都保存在內存數據庫(main)中。當 ProxySQL 重啓或者崩潰時,這個內存數據庫中的數據會丟失,所以需要 save 到 disk 庫中。

最上層的是 runtime ,它是 ProxySQL 有關線程運行時讀取的數據結構。換句話說,該數據結構中的配置都是已生效的配置。所以,修改了 main 庫中的配置後,必須 load 到 runtime 數據結構中才能使其生效。
在上面的多層配置系統圖中,標註了[1]、[2]、[3]、[4]、[5]的序號。每個序號都有兩個操作方向from/to,其實只是所站角度不同而已。以下是各序號對應的操作:

[1] :將內存數據庫中的配置加載到RUNTIME數據結構中
        LOAD XXX FROM MEMORY
        LOAD XXX TO RUNTIME

[2] :將RUNTIME數據結構中的配置持久化到內存數據庫中
        SAVE XXX FROM RUNTIME
        SAVE XXX TO MEMORY

[3] :將磁盤數據庫中的配置加載到內存數據庫中
        LOAD XXX FROM DISK
        LOAD XXX TO MEMORY

[4] :將內存數據庫中的配置持久化到磁盤數據庫中
        SAVE XXX FROM MEMORY
        SAVE XXX TO DISK

[5] :從傳統配置文件中讀取配置加載到內存數據庫中
        LOAD XXX FROM CONFIG

另外,上面的XXX是什麼?這表示要加載/保存的是哪類配置。目前的ProxySQL支持以下幾種:

mysql users
mysql servers
mysql variables
mysql query rules
admin variables
scheduler
proxysql_servers:目前ProxySQL集羣功能還處於實驗階段,所以該類配置不應該去使用

這些從main庫或disk庫中就可以查看到

MySQL [(none)]> show tables from disk;
+------------------------------------+
| tables                             |
+------------------------------------+
| global_variables                   |  # (1)
| mysql_collations                   |  # (N)
| mysql_group_replication_hostgroups |  # (2)
| mysql_query_rules                  |  # (3)
| mysql_query_rules_fast_routing     |  # (4)
| mysql_replication_hostgroups       |  # (5)
| mysql_servers                      |  # (6)
| mysql_users                        |  # (7)
| proxysql_servers                   |  # (8)
| scheduler                          |  # (9)
+------------------------------------+

上面的結果中我給這些表都標註了一些序號,其所對應的表的內容有以下講究:

  • (1)中包含兩類變量,以amdin-開頭的表示admin variables,以mysql-開頭的表示mysql variables。修改哪類變量,前文的XXX就代表哪類
  • (2,5,6)對應的都是mysql servers
  • (3,4)對應的是mysql query rules
  • (7)對應的mysql users
  • (9)對應的scheduler
  • (N)只是一張表,保存的是ProxySQL支持的字符集和排序規則,它是不用修改的
  • (8)是ProxySQL的集羣配置表,該功能目前還處於實驗階段。如果想要配置該功能,則load/save proxysql_servers to/from …
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章