數據庫 之 Mysql主從複製的讀寫分離

1  概述前端

通常而言,主節點只有一個,從節點有多個,從節點只支持讀操做,主節點支持寫操做。java

實現讀寫分離有兩種解決,一是在程序端實現,二是加中間層實現,通常要對客戶端透明,因此建議最好加中間層來實現。mysql

中間層有以下幾個軟件:nginx

mysql-proxy : 後續的atlas是基於mysql-proxy的改進版本,atlas開源項目依然處於維護中。git

amoeba for MySQL:讀寫分離、分片;github

        cobar:分片框架,基於amoeba版本的升級,基於java開發,所以要安裝jdk正則表達式

        mycat: 後續的版本是OneProxysql

OneProxy:雙受權。有商業公司在維護,支持到mysql5.7版本。是一個較好的選擇,有開源版本vim

MaxScale:是mariadb負責維護,也是雙受權,可是配置接口使用不方便。後端

ProxySQL:是DBA團隊研發的,高性能的開源的mysql代理服務器的中間層,這個是一個較好的選擇,8大性能介紹見官網:http://www.proxysql.com/。代碼託管在github:

https://github.com/sysown/proxysql/releases

AliSQL:阿里公司開發的。已經開源。

若是不使用以上的sql 代理實現讀寫分離,由於讀寫分離由延遲,數據不一致等問題,建議可使用雙主或多主模型是無須實現讀寫分離,僅須要負載均衡,使用haproxy, nginx, lvs, ...等工具進行調度,後端mysql集羣有以下兩個方案:

使用pxc工具:Percona XtraDB Cluster

或者使用MariaDB Cluster,可是集羣可能會因爲資源爭用致使死鎖

這裏將演示proxysql進行演示

2  Proxysql配置文件介紹

proxysql的全部配置都定義在一張admin表裏。可使用sql語句進行更改配置,直接更改運行時的配置信息。認證和受權能夠由後端來實現,也能夠在在前端proxy作檢查,將有限的特定帳號放在代理服務器上來實現驗證,代理服務器訪問後端服務器也須要驗證,這個代理的權限須要擁有全部帳號訪問後端的權限

配置文件/etc/proxysql.cnf介紹以下

ProxySQL:建議經過keepalive配置成proxysql高可用,只要ProxySQL配置同樣就能夠,由於ProxySQL沒有狀態

配置示例:

datadir="/var/lib/proxysql" #放置數據

admin_variables=   #管理變量

{

admin_credentials="admin:admin" #相似varnish的6082端口,這裏是監聽在6032端口,這種接口不要開發給遠程訪問,由於該接口是管理接口

mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock" 

}

mysql_variables=  #鏈接後端服務器的變量,通常只需更改 interfaces參數,其餘採用默認值便可

{

threads=4

max_connections=2048

default_query_delay=0

default_query_timeout=36000000 

have_compress=true

poll_timeout=2000 #輪詢的超時時長

interfaces="0.0.0.0:3306;/tmp/mysql.sock"  #建議監聽標準端口

default_schema="information_schema"

stacksize=1048576

server_version="5.5.30"

connect_timeout_server=3000 #鏈接後端的超時時長

monitor_username="monitor"#後端主機須要擁有該帳號才能監控

monitor_password="monitor"

monitor_history=600000  #每一個多長時間重連一次

monitor_connect_interval=60000

monitor_ping_interval=10000

monitor_read_only_interval=1500

monitor_read_only_timeout=500

ping_interval_server=120000

ping_timeout_server=500

commands_stats=true

sessions_sort=true

connect_retries_on_failure=10 #後端主機錯誤重試的次數

}

mysql_servers =  #定義mysql服務器主機,每個主機用花括號隔開

(

{

address = "172.18.0.67" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

hostgroup = 0           # no default, required

status = "ONLINE"     # default: ONLINE

weight = 1            # default: 1

compression = 0       # default: 0

},  #注意,最後一個數據項不能跟逗號

{

address = "172.18.0.68"

port = 3306

hostgroup = 1

status = "ONLINE"     # default: ONLINE

weight = 1            # default: 1

compression = 0       # default: 0

},

{

address = "172.18.0.69" #這裏架構不同不用寫69,由於69此時是代理了,不是後端的

port = 3306

hostgroup = 1

status = "ONLINE"     # default: ONLINE

weight = 1            # default: 1

compression = 0       # default: 0

}

)

mysql_users: #支持的用戶帳號,如下定義的帳號是在後端mysql服務器上受權

(

{

username = "root"

password = "mageedu"

default_hostgroup = 0 #0表示默認發給主節點

max_connections=1000

default_schema="mydb"

active = 1  #表示用戶處於激活狀態

}

)

mysql_query_rules: #定義查詢的規則,規則的先後順序很關鍵,支持正則表達式格式,

注意,如下是通用規則,能夠啓用

(

{

    rule_id=1

    active=1

    match_pattern="^SELECT .* FOR UPDATE$"

    destination_hostgroup=0

    apply=1

},

{

    rule_id=2

    active=1

    match_pattern="^SELECT"

    destination_hostgroup=1

    apply=1

}

)

scheduler=  #定義調度器

(

)

mysql_replication_hostgroups=  #真正定義組的用途,如定義讀寫組

(

{

writer_hostgroup=0 #定義主組,寫功能

reader_hostgroup=1 #定義從組,讀功能

comment="test repl 1" #註釋信息

}

)

3  例子 Proxysql實現讀寫分離

192.168.1.75爲代理服務器,通常狀況下,生產環境代理須要有兩個網段的ip,下降IO壓力,公網ip提供給客戶端訪問,私有ip對內部mysql集羣,可是實驗,這裏僅配置一個網段的ip

192.168.1.71爲主服務器,192.168.1.73爲從服務器

75上安裝proxysql

[root@CentOS7E ~]#yum -y install /root/proxysql-1.4.5-1-centos7.x86_64.rpm 

修改配置文件

[root@CentOS7E ~]#vim /etc/proxysql.cnf

datadir="/var/lib/proxysql"

admin_variables=

{

admin_credentials="admin:admin"

mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"

}

mysql_variables=

{

threads=4

max_connections=2048

default_query_delay=0

default_query_timeout=36000000

have_compress=true

poll_timeout=2000

interfaces="0.0.0.0:3306;/tmp/mysql.sock"

default_schema="information_schema"

stacksize=1048576

server_version="5.5.30"

connect_timeout_server=3000

monitor_username="monitor"

monitor_password="monitor"

monitor_history=600000

monitor_connect_interval=60000

monitor_ping_interval=10000

monitor_read_only_interval=1500

monitor_read_only_timeout=500

ping_interval_server_msec=120000

ping_timeout_server=500

commands_stats=true

sessions_sort=true

connect_retries_on_failure=10

}

mysql_servers =

(

{

address = "192.168.1.71" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

hostgroup = 0         # no default, required

status = "ONLINE"     # default: ONLINE

weight = 1            # default: 1

compression = 0       # default: 0

},

{

address = "192.168.1.73" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

port = 3306           # no default, required . If port is 0 , address is interpred as a Unix Socket Domain

hostgroup = 1         # no default, required

status = "ONLINE"     # default: ONLINE

weight = 1            # default: 1

compression = 0       # default: 0

}

)

mysql_users:

(

{

username = "proxyadm" # no default , required

password = "pass1234" # default: ''

default_hostgroup = 0 # default: 0

active = 1            # default: 1

}

)

mysql_query_rules:

(

{

rule_id=1

active=1

match_pattern="^SELECT .* FOR UPDATE$"

destination_hostgroup=0

apply=1

},

{

rule_id=2

active=1

match_pattern="^SELECT"

destination_hostgroup=1

apply=1

}

)

scheduler=

(

)

mysql_replication_hostgroups=

(

        {

                writer_hostgroup=0

                reader_hostgroup=1

                comment="test repl 1"

       }

)


在後端全部服務器上受權能夠管理的帳號,建議密碼不包含大寫字母,可能問題,由於用管理接口查看到的mysql_users,當配置文件寫入的帳號密碼是大寫字母的時候,這張表查看到的是小寫字母,因此建議受權時密碼都用小寫

MariaDB [sunnydb]> grant all on *.* to 'proxyadm'@'192.168.1.%' identified by 'pass1234';

啓動proxysql服務

[root@CentOS7E ~]#systemctl start proxysql

查看狀態

[root@CentOS7E ~]#service proxysql status;

鏈接服務接口3306

查看proxysql的數據

[root@CentOS7E ~]#ls /var/lib/proxysql/

測試,鏈接mysql接口,Server version: 5.5.30 (ProxySQL)

[root@CentOS7E ~]#mysql -uproxyadm -ppass1234 -h 192.168.1.75

或者,打開管理接口Server version: 5.5.30 (ProxySQL Admin Module)

MySQL [sunny]> show databases;

鏈接的主服務器節點,這個是在配置中的default組定義,此時,寫操做都被調度到主節點上,讀操做都在從服務器上

注意,因爲讀寫分離,若是在mysql讀服務器(從)的表能被讀出,必須是在mysql從服務器上有對應的庫和表,若是從服務器上麼有對應的內容,主服務器上有隻能被看到表,可是不能被select出內容

鏈接管理接口6302

[root@CentOS7E ~]#mysql -S /tmp/proxysql_admin.sock -uadmin -padmin;

鏈接上proxysql後,用show databases 和show tables能夠看到相關的表和庫,可是這些數據是模擬出來的

如運行MySQL [(none)]> select * from mysql_servers;

能夠看到配置文件裏配置的mysql_servers配置段能夠看到轉化爲表裏的數據,因此直接修改表,至關因而修改了配置文件,直接是運行時生效

相關文章
相關標籤/搜索