OneProxy實現MySQL讀寫分離

系列文章: 1.MySQL主從複製 2.OneProxy實現MySQL讀寫分離javascript

讀寫分離方案,其實咱們能夠經過配置動態數據源來實現。也能夠經過一些中間件來實現,好比OneProxy,MaxScale,MysqlProxy來實現。下面咱們要講的是如何經過OneProxy來實現MySQL的讀寫分離。html

從OneProxy的官網上,咱們能看到OneProxy的介紹:java

MySQL的邏輯複製技術可輕鬆構建多個數據副原本提供服務,並能夠消除數據庫單點,但須要應用做出相應的代碼調整,才能充分利用它的優點。而網絡交換機/路由器在理解TCP協議和目的IP地址的狀況下,能夠幫助人們輕鬆地組建大大小小的網絡, OneProxy for MySQL在理解MySQL通訊協議和SQL語句分析的基礎上,能夠幫助輕鬆組建數據庫集羣,避免代價昂貴的應用代碼調整。mysql

OneProxy for MySQL能夠複用不一樣應用到後端數據庫的鏈接,有效下降數據庫的併發鏈接數;能夠即時踢除不可用的節點,將應用請求轉發到其餘可用節點,保證業務服務的穩定性。 可透明地將查詢語句分發到多個MySQL備庫執行,用讀寫分離方案支持上千萬的併發訪問;也能夠根據SQL語句中的值進行分庫分表路由, 均勻分散到多個MySQL主庫上,以支持每秒上百萬個小事務的併發執行;可實時透明地分析流量數據,統計SQL和事務的運行時間,分析事務的結構,獲得各類不一樣維度的實時性能報告; 還能夠進行流理QoS控制,做爲數據庫防火牆抵擋SQL注入式攻擊;根據分片的SQL並行執行,解決了大數據量下的彙總統計性能問題;跨多分片的結果集合並, 極大地簡化了應用程序的開發工做量。web

更多介紹能夠看Oneproxy介紹sql

首先,搭好Mysql的主從複製結構: master 192.168.10.21 slave 192.168.10.6數據庫

1.在master和slave中建立test用戶而且給其分配權限。vim

grant all privileges on *.* to test@'%' identified by 'test'

2.修改demo.sh後端

image.png安全

3.給demo.sh賦權限

chmod 777 demo.sh

4.修改啓動的腳本,將ONEPROXY_HOME設置你安裝的oneproxy的路徑

vim oneproxy.service

image.png

5.調用mysqlpwd進行密碼加密

[root@localhost oneproxy]# ls bin demo.sh oneproxy.service sql testautocommit.sql trantest.sql conf log README testadmin.sql testproxy.sql [root@localhost oneproxy]# cd bin [root@localhost bin]# ls mysqlpwd oneproxy [root@localhost bin]# ./mysqlpwd test 1378F6CC3A8E8A43CA388193FBED5405982FBBD3

6.配置oneproxy

[oneproxy] keepalive = 1 event-threads = 4 log-file = log/oneproxy.log pid-file = log/oneproxy.pid lck-file = log/oneproxy.lck proxy-auto-readonly = 1 proxy-forward-clientip = 1 proxy-trans-debug = 1 mysql-version = 5.7.17 admin-address = 0.0.0.0:4041 proxy-address = 0.0.0.0:3307 proxy-master-addresses = 192.168.10.21:3306@oneproxy proxy-slave-addresses = 192.168.10.6:3306@oneproxy proxy-user-list.1 = oneproxy:test/1378F6CC3A8E8A43CA388193FBED5405982FBBD3@rap_test proxy-part-template = conf/template.txt proxy-part-tables = conf/part.txt proxy-charset = utf8mb4_general_ci proxy-secure-client = 127.0.0.1 proxy-license = A2FF461456A67F28,D2F6A5AD70C9042D proxy-httpserver = 0.0.0.0:8080 proxy-httpauth = admin:admin proxy-httptitle = oneProxy[cmazxiaoma] proxy-group-security = oneproxy:0 proxy-group-policy = oneproxy:2 proxy-sequence-group = oneproxy proxy-sequence.1 = seq1 network-blocking= 0

配置參數說明:

[oneproxy] keepalive = 1 event-threads = 4 #指定日誌文件路徑 log-file = log/oneproxy.log #指定PID文件路徑 pid-file = log/oneproxy.pid #指定LCK文件路徑 lck-file = log/oneproxy.lck proxy-auto-readonly = 1 proxy-forward-clientip = 1 proxy-trans-debug = 1 #MySQL服務版本 mysql-version = 5.7.17 admin-address = 0.0.0.0:4041 proxy-address = 0.0.0.0:3307 #指定主服務器的IP地址 格式:IP地址:端口@oneproxy組 proxy-master-addresses = 192.168.10.21:3306@oneproxy #指定從服務器的IP地址 格式:IP地址:端口@oneproxy組 proxy-slave-addresses = 192.168.10.6:3306@oneproxy #用戶列表 格式:用戶名/密文密碼@數據庫名稱 proxy-user-list.1 = oneproxy:test/1378F6CC3A8E8A43CA388193FBED5405982FBBD3@rap_test proxy-part-template = conf/template.txt #指定分表分庫的配置文件 proxy-part-tables = conf/part.txt #指定數據庫字符集 proxy-charset = utf8mb4_general_ci proxy-secure-client = 127.0.0.1 proxy-license = A2FF461456A67F28,D2F6A5AD70C9042D 指定Web服務的監聽端口 proxy-httpserver = 0.0.0.0:8080 #指定Web訪問認證信息 格式:用戶名:密碼 proxy-httpauth = admin:admin #指定Web頁面名稱 proxy-httptitle = oneProxy[cmazxiaoma] #設定安全級別,0默認值,1禁止DDL,2禁止不帶條件的查詢語句,3只容許SELECT proxy-group-security = oneproxy:0 #設定預約義策略 #0表明由Lua Script來決定 1表明Read Failover 2表明主節點不參與讀 3表明雙主結構 4表明主節點參與讀操做 5表明隨機讀取 proxy-group-policy = oneproxy:2 proxy-sequence-group = oneproxy proxy-sequence.1 = seq1 network-blocking = 0

關於proxy-group-policy這個參數我要重點提一下, 它是用來指定MySQL實例的流量切換和分擔的策略,具體以下:

  • master_only:master進行讀寫操做。
  • read_failover:寫流量同「master-only」,針對讀流量,若是Master節點可用則從Master節點訪問,若是Master節點不可用,則從Slave節點訪問。此策略經常使用於關鍵配置數據的高可用。
  • read_slave:寫流量同「master-only」,針對讀流量,先從Slave節點讀取,若是沒有Slave可用,則從Master節點訪問。此策略即一主多備狀況下的讀寫分離策略。
  • read_balance:寫流量同「master-only」,針對讀流量,先從任一可用節點讀取,包括Master和Slave類型。此策略即一主一備狀況下的讀寫分離策略。
  • big_slave:寫流量和簡單SQL查詢流量同「master-only」,針對複雜的SQL語句,先從Slave節點讀取,若是沒有Slave可用,則從Master節點訪問。此策略爲一主多備狀況下的複雜SQL語句讀寫分離。
  • big_balance:寫流量和簡單SQL查詢同「master-only」,針對複雜的SQL語句,先從任一可用節點讀取,包括Master和Slave類型。此策略爲一主一備狀況下的複雜SQL語句讀寫分離。
  • write_failover:寫流量同「master-only」,但一般配有多個Master類型節點,能夠預防寫操做失敗;針對讀流量,先從任一可用節點讀取。
  • write_balance:針對每次寫操做,任挑一臺Master節點提供服務;針對讀流量,先從任一可用節點讀取。

若是配置有問題的話是啓動不了的,並且oneproxy.log也不會輸出任何異常。

7.啓動oneproxy,能夠看到3307,8080,4041端口信息,說明啓動成功了。

[root@localhost oneproxy]# ./demo.sh [root@localhost oneproxy]# netstat -ntlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 5693/oneproxy tcp 0 0 0.0.0.0:9100 0.0.0.0:* LISTEN 2115/grunt tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 5693/oneproxy tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 979/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1193/master tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 5693/oneproxy tcp6 0 0 :::22 :::* LISTEN 979/sshd tcp6 0 0 ::1:25 :::* LISTEN 1193/master tcp6 0 0 :::3306 :::* LISTEN 4739/mysqld [root@localhost oneproxy]# 

8.咱們能夠進入OneProxy的admin模式。默認帳號是admin,密碼是OneProxy

image.png

  1. 查看讀寫分離狀態。
mysql> list backend\g
+------+--------------------+------+--------+--------+----------+----------+---------+------------------+ | INDX | ADDRESS | TYPE | STATUS | MARKUP | REQUESTS | GROUP | Seconds | SyncTime | +------+--------------------+------+--------+--------+----------+----------+---------+------------------+ | 2 | 192.168.10.21:3306 | RW | UP | 1 | 0 | oneproxy | 22639 | 1540957748819753 | | 3 | 192.168.10.6:3306 | RW | UP | 1 | 0 | oneproxy | 0 | 1540980388023589 | +------+--------------------+------+--------+--------+----------+----------+---------+------------------+ 2 rows in set (0.00 sec) mysql> list pool\g +------+--------------------+------+--------+------+---------+---------+----------+ | INDX | ADDRESS | USER | LENGTH | SIZE | MINIDLE | MAXIDLE | REQUESTS | +------+--------------------+------+--------+------+---------+---------+----------+ | 2 | 192.168.10.21:3306 | test | 20 | 20 | 20 | 200 | 0 | | 3 | 192.168.10.6:3306 | test | 20 | 20 | 20 | 200 | 40 | +------+--------------------+------+--------+------+---------+---------+----------+ 2 rows in set (0.00 sec) mysql> 

10.經過訪問8080端口,咱們能夠經過Web界面可視化數據,更好的觀察讀寫分離狀態。

image.png

11.訪問3307端口,也就是oneProxy代理的地址。rap_test庫和date_demo是咱們以前測試MySQL主從複製創建的數據庫和表。咱們能夠看到多了一個oneproxy_replication_timestamp。在咱們的master和slave中的rap_test庫也能夠看到這張表。這張表用來檢測讀節點的複製延遲。

image.png

master.png

slave.png

12.咱們經過web界面和oneProxy.log發現延遲了。也就是oneproxy_replication_timestamp裏面的時間戳不一致。

image.png

image.png

13.咱們進入3307端口,看一下master和slave的狀態。slave的狀態是ok的。

mysql> show slave status\G
*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.10.21 Master_User: sync Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 178305 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 589 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 178305 Relay_Log_Space: 800 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 21 Master_UUID: 67ccaaf1-e4b4-11e7-a07f-c8d3ffc0c026 Master_Info_File: /usr/local/mysql/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)

查看master的狀態,咱們發現OneProxy依賴的是master的mysql-bin.000001文件,而slave複製依賴的是master的mysql-bin.000002文件。

mysql> ^C mysql> show master status\g +------------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+-----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 129901019 | | | | +------------------+-----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> 

14.咱們在master上,查看master 的狀態。發現master的binlog文件時mysql-bin.000002文件。

image.png

15.查看master的全部binlog文件

mysql> show binary logs\g
+------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 201 | | mysql-bin.000002 | 178305 | +------------------+-----------+ 2 rows in set (0.00 sec)

16.查看binlog文件中的事件

mysql> show binlog events in 'mysql-bin.000001'\g +------------------+-----+----------------+-----------+-------------+---------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+---------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 21 | 123 | Server ver: 5.7.17-log, Binlog ver: 4 | | mysql-bin.000001 | 123 | Previous_gtids | 21 | 154 | | | mysql-bin.000001 | 154 | Rotate | 21 | 201 | mysql-bin.000002;pos=4 | +------------------+-----+----------------+-----------+-------------+---------------------------------------+ 3 rows in set (0.00 sec)
mysql> show binlog events in 'mysql-bin.000002' limit 10\g +------------------+-----+----------------+-----------+-------------+----------------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+----------------------------------------------------------------------------+ | mysql-bin.000002 | 4 | Format_desc | 21 | 123 | Server ver: 5.7.17-log, Binlog ver: 4 | | mysql-bin.000002 | 123 | Previous_gtids | 21 | 154 | | | mysql-bin.000002 | 154 | Anonymous_Gtid | 21 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' | | mysql-bin.000002 | 219 | Query | 21 | 353 | use `rap_master`; DROP TABLE `date_demo` /* generated by server */ | | mysql-bin.000002 | 353 | Anonymous_Gtid | 21 | 418 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' | | mysql-bin.000002 | 418 | Query | 21 | 517 | drop database `rap_master` | | mysql-bin.000002 | 517 | Anonymous_Gtid | 21 | 582 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' | | mysql-bin.000002 | 582 | Query | 21 | 738 | create database `rap_test`character set utf8mb4 collate utf8mb4_general_ci | | mysql-bin.000002 | 738 | Anonymous_Gtid | 21 | 803 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' | | mysql-bin.000002 | 803 | Query | 21 | 898 | drop database `rap_test` | +------------------+-----+----------------+-----------+-------------+----------------------------------------------------------------------------+ 10 rows in set (0.00 sec)

17.重置master的binlog

mysql> reset master\g
Query OK, 0 rows affected (0.82 sec)
mysql> show binary logs\g
+------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 154 | +------------------+-----------+ 1 row in set (0.00 sec) mysql> 

18.從新配置slave

mysql> reset slave\g
Query OK, 0 rows affected (0.01 sec) mysql> change master to -> master_host="192.168.10.21", -> master_user="sync", -> master_password="sync", -> master_log_file="mysql-bin.000001", -> master_log_pos=154\g Query OK, 0 rows affected, 2 warnings (0.10 sec)

19.重啓oneproxy,經過web界面查看仍是存在延遲。咱們還忽略了一個點,master地址居然是192.168.10.6。master地址應該是192.168.10.21。

image.png

20.咱們鏈接192.168.10.6:3306,查看是否配置過master。難怪,oneproxy顯示master的binlog一直是mysql-bin.000001(這個binlog是slave開啓master模式所產生的binglog)。slave居然是slave仍是master,雌雄同體,WTF。

mysql> show master status\g
+------------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+-----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 138280148 | | | | +------------------+-----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> 

21.感受這是oneproxy的一個bug,我重啓oneProxy,再經過web界面查看,一切正常。

image.png

22.咱們鏈接OneProxy的3307端,調用select @@server_id語句,返回的是6,證實查詢語句是在slave端執行。由於以前配置主從複製的時候,master的server_id是21,slave的server_id是6.

mysql> show master status\g
+------------------+-----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+-----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 141160929 | | | | +------------------+-----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> select @@server_id\g +-------------+ | @@server_id | +-------------+ | 6 | +-------------+ 1 row in set (0.00 sec) mysql> 

23.咱們在3307端口插入2條記錄。而後咱們在master和slave查看是否成功插入這2條記錄。

mysql> select * from oneproxy_replication_timestamp \g +--------------------------+------------------+ | proxy_uuid | proxy_stamp | +--------------------------+------------------+ | AYCE-ZUSM-OIIN-UYAW-CZEG | 1541038193999142 | +--------------------------+------------------+ 1 row in set (0.00 sec) mysql> INSERT INTO date_demo VALUES(NULL,NOW(),NOW(),NOW(),NOW(),NOW())\g Query OK, 1 row affected, 1 warning (1.06 sec) mysql> INSERT INTO date_demo VALUES(NULL,NOW(),NOW(),NOW(),NOW(),NOW())\g Query OK, 1 row affected, 1 warning (0.46 sec) mysql> select * from date_demo\g +----+----------+---------------------+---------------------+------------+----------------+ | id | time | timestamp | datetime | date | int_date | +----+----------+---------------------+---------------------+------------+----------------+ | 1 | 10:18:07 | 2018-10-30 10:18:07 | 2018-10-30 10:18:07 | 2018-10-30 | 20181030101807 | | 2 | 11:18:57 | 2018-10-30 11:18:57 | 2018-10-30 11:18:57 | 2018-10-30 | 20181030111857 | | 3 | 18:45:40 | 2018-10-31 18:45:40 | 2018-10-31 18:45:40 | 2018-10-31 | 20181031184540 | | 4 | 10:10:08 | 2018-11-01 10:10:08 | 2018-11-01 10:10:08 | 2018-11-01 | 20181101101008 | | 5 | 10:10:36 | 2018-11-01 10:10:36 | 2018-11-01 10:10:36 | 2018-11-01 | 20181101101036 | +----+----------+---------------------+---------------------+------------+----------------+ 5 rows in set (0.00 sec)

master.png

slave.png

24.咱們能夠用OneProxy Web界面查看SQLS、TableS、DMLS可視化數據統計。能夠發現date_demo執行Insert語句有3次。

image.png

image.png

25.將binlog轉換成SQL語句,咱們在output.sql能夠看到咱們剛纔插入的sql語句。

#mysqlbinlog -d rap_test mysql-bin.000001 -r output.sql

image.png

image.png

26.最後記錄一下MySQL性能監控的一些參數。

SHOW GLOBAL VARIABLES LIKE '%max_connections%'
SHOW GLOBAL STATUS LIKE '%Threads_created%' SHOW GLOBAL STATUS LIKE '%threads_running%' SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table' SHOW GLOBAL VARIABLES LIKE 'show_query_log' SHOW VARIABLES LIKE '%partition%' SHOW VARIABLES LIKE "%innodb_buffer_pool_size%";
相關文章
相關標籤/搜索