Mysql複製及代理

#####################################前端

Mysql複製的做用和原理java

mysql-5.5實現主從複製node

mysql-5.6主從複製和Mysql_Proxy的實現mysql

mysql-5.6基於amoeba實現讀寫分離linux

#####################################git

Mysql複製的做用和原理
算法

複製的做用sql

  • 輔助實現備份數據庫

  • 高可用vim

  • 異地容災

  • scale out:分攤負載

  • MySQL路由:讀寫請求交由代理服務器,工做在應用層能夠理解SQL語句,從而實現讀寫分離,再結合LVS、HAPROXY等均攤讀的負載。

  • 爲了讓主服務器不會由於從服務器太多產生多線程複製致使服務器壓力過大,使用多級複製。

複製原理

184550539.png

複製流程以下:

  • Master數據發生改變以後寫入二進制日誌並經過dump線程複製到Slave。

  • Slave本地啓用I/0線程負責接受Master端dump線程發來的日誌並保存至本地中繼日誌中。

  • Slave經過啓用本地SQL線程將中繼日誌中那些複製而來的事件重放。

relaylog(中繼日誌)

  • mysql日誌傳輸默認是異步傳輸

  • mysql支持一主多從

  • mysql半同步意爲只要其中一個從服務器返回確認就認爲同步成功

  • 可使用mysql從服務器作冷備份,配合主服務器上的二進制日誌作即時點還原

  • mysql多級複製從服務器能夠記錄二進制日誌,不然通常狀況下不須要記錄二進制日誌



mysql-5.5實現主從複製

結構圖以下:

190908174.png

安裝mysql

mkdir -pv /mydata/data
useradd -r mysql
chown -R mysql.mysql /mydata/data
tar xf mysql-5.5.28-linux2.6-i686.tar.gz -C /usr/local
cd  /usr/local/
ln -sv mysql-5.5.28-linux2.6-i686 mysql
cd mysql
chown  -R root.mysql ./*
scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
cp support-files/my-large.cnf  /etc/my.cnf
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
vim /etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
. /etc/profile.d/mysql.sh

Master配置

#####修改配置文件 vim /etc/my.cnf
datadir = /mydata/data
log-bin=master-bin
log-bin-index=master-bin.index
innodb_file_per_table = 1
binlog_format=mixed
server-id       = 1
sync_binlog = 1
innodb_flush_logs_at_trx_commit = 1
#####開啓Slave權限用戶
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.1.%' IDENTIFIED BY 'replpass';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Slave配置

#####修改配置文件vim /etc/my.cnf
datadir = /mydata/data
relay-log = relay-log
relay-log-index = relay-log.index
read-only = ON
server-id       = 11
skip_slave_start = 1
read_only = 1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
#####查看主日誌文件和事件位置
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 |      340 |              |                  |
+-------------------+----------+--------------+------------------+
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
#####開啓slave複製功能
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.131',MASTER_USER='repluser', MASTER_PASSWORD='replpass',MASTER_LOG_FILE='master-bin.000001',MASTER_LOG_POS=340;
#####查看slave狀態,可得出master二進制日誌和slave中繼日誌的事件和位置對應未必贊成因此在slave備份的時候應該記錄主服務器的二進制日誌,只有二進制日誌才能夠完成即便點還原
Slave_IO_Running: No
Slave_SQL_Running: No      均爲yes表明slave複製正常
#####查看複製狀態
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.1.131
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 340
               Relay_Log_File: relay-log.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
    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: 340   #重放到的位置
              Relay_Log_Space: 107
              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: NULL
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: 0
#####開啓複製進程
mysql> START SLAVE;

測試

#####Master
mysql> create database soulboy;
Query OK, 1 row affected (0.00 sec)
#####Slave
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| soulboy            |
| test               |
+--------------------+
5 rows in set (0.00 sec)


mysql-5.6主從複製和Mysql_Proxy的實現

複製功能的改進

  • 支持多線程複製,事實上是針對每一個database開啓相應的獨立線程。即每一個庫有一個單獨的(sql thread)若是線上業務中,只有一個database或者絕大多數壓力集中在個別database的話,多線程併發複製特性就沒有意義了。

  • 支持啓用GTID,對運維人員來講應該是一件使人高興的事情,在配置主從複製,傳統的方式裏,你須要找到binlog和POS點,而後change master to指向,而不是頗有經驗的運維,每每會將其找錯,形成主從同步複製報錯,在mysql5.6裏,無須再知道binlog和POS點,須要知道master的IP、端口,帳號密碼便可,由於同步複製是自動的,mysql經過內部機制GTID自動找點同步。

結構圖以下:193003193.png

Mysql-5.6主從複製功能的實現步驟

Master配置(安裝步驟省略)

#####主節點配置文件  /etc/my.cnf
[mysqld]
binlog-format=ROW
log-bin=master-bin
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
server-id=1
report-port=3306
port=3306
datadir=/mydata/data
socket=/tmp/mysql.sock
report-host=192.168.1.201
#####配置完成重啓mysql服務,確保gitd_mode爲打開狀態
mysql> SHOW GLOBAL VARIABLES LIKE '%gtid%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| enforce_gtid_consistency | ON    |
| gtid_executed            |       |
| gtid_mode                | ON    |
| gtid_owned               |       |
| gtid_purged              |       |
+--------------------------+-------+
#####Slave用戶受權
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.1.%' IDENTIFIED BY 'replpass';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Slave節點配置(安裝步驟省略)

#####Mysql主配置文件 /etc/my.cnf
[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
server-id=11
report-port=3306
port=3306
log-bin = mysql-bin.log
datadir=/mydata/data
socket=/tmp/mysql.sock
report-host=192.168.1.202
#####Slave鏈接Master服務器
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.201',MASTER_USER='repluser',MASTER_PASSWORD='replpass',MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
#####啓動兩個線程Slave_IO_Running和Slave_SQL_Running
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)

測試主從複製成功

#####Master
mysql> create database soulboy;
Query OK, 1 row affected (0.00 sec)
#####Slave
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| soulboy            |
| test               |
+--------------------+
5 rows in set (0.01 sec)

Mysql-Proxy的實現

安裝mysql-proxy

useradd -r mysql-proxy
tar xf mysql-proxy-0.8.3-linux-glibc2.3-x86-64bit.tar.gz  -C /usr/local/
cd /usr/local/
ln -sv mysql-proxy-0.8.3-linux-glibc2.3-x86-64bit mysql-pro
cd mysql-proxy
vi /etc/profile.d/mysql-proxy.sh
export PATH=$PATH:/usr/local/mysql-proxy/bin
. /etc/profile.d/mysql-proxy.sh

主服務器建立遠程用戶

mysql> GRANT ALL ON *.* TO 'root'@'192.168.%.%' IDENTIFIED BY 'redhat';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

爲mysql-proxy提供SysV服務腳本

#!/bin/bash
#
# mysql-proxy This script starts and stops the mysql-proxy daemon
#
# chkconfig: - 78 30
# processname: mysql-proxy
# description: mysql-proxy is a proxy daemon for mysql
# Source function library.
. /etc/rc.d/init.d/functions
prog="/usr/local/mysql-proxy/bin/mysql-proxy"
# Source networking configuration.
if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
# Set default mysql-proxy configuration.
ADMIN_USER="admin"
ADMIN_PASSWD="admin"
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_OPTIONS="--daemon"
PROXY_PID=/var/run/mysql-proxy.pid
PROXY_USER="mysql-proxy"
# Source mysql-proxy configuration.
if [ -f /etc/sysconfig/mysql-proxy ]; then
    . /etc/sysconfig/mysql-proxy
fi
RETVAL=0
start() {
    echo -n $"Starting $prog: "
    daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --proxy-address="$PROXY_ADDRESS" --user=$PROXY_USER --admin-username="$ADMIN_USER" --admin-lua-script="$ADMIN_LUA_SCRIPT" --admin-password="$ADMIN_PASSWORD"
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        touch /var/lock/subsys/mysql-proxy
    fi
}
stop() {
    echo -n $"Stopping $prog: "
    killproc -p $PROXY_PID -d 3 $prog
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/mysql-proxy
        rm -f $PROXY_PID
    fi
}
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    condrestart|try-restart)
        if status -p $PROXY_PIDFILE $prog >&/dev/null; then
            stop
            start
        fi
        ;;
    status)
        status -p $PROXY_PID $prog
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status|condrestart|try-restart}"
        RETVAL=1
        ;;
esac
exit $RETVAL
#####將上述內容保存爲/etc/rc.d/init.d/mysql-proxy,給予執行權限,然後加入到服務列表。
# chmod +x /etc/rc.d/init.d/mysql-proxy
# chkconfig --add mysql-proxy

Mysql-Proxy的遠程管理依賴於lua腳本

#####vi /usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua
vi /usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua
function set_error(errmsg)
    proxy.response = {
        type = proxy.MYSQLD_PACKET_ERR,
        errmsg = errmsg or "error"
    }
end
function read_query(packet)
    if packet:byte() ~= proxy.COM_QUERY then
        set_error("[admin] we only handle text-based queries (COM_QUERY)")
        return proxy.PROXY_SEND_RESULT
    end
    local query = packet:sub(2)
    local rows = { }
    local fields = { }
    if query:lower() == "select * from backends" then
        fields = {
            { name = "backend_ndx",
              type = proxy.MYSQL_TYPE_LONG },
            { name = "address",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "state",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "type",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "uuid",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "connected_clients",
              type = proxy.MYSQL_TYPE_LONG },
        }
        for i = 1, #proxy.global.backends do
            local states = {
                "unknown",
                "up",
                "down"
            }
            local types = {
                "unknown",
                "rw",
                "ro"
            }
            local b = proxy.global.backends[i]
            rows[#rows + 1] = {
                i,
                b.dst.name,          -- configured backend address
                states[b.state + 1], -- the C-id is pushed down starting at 0
                types[b.type + 1],   -- the C-id is pushed down starting at 0
                b.uuid,              -- the MySQL Server's UUID if it is managed
                b.connected_clients  -- currently connected clients
            }
        end
    elseif query:lower() == "select * from help" then
        fields = {
            { name = "command",
              type = proxy.MYSQL_TYPE_STRING },
            { name = "description",
              type = proxy.MYSQL_TYPE_STRING },
        }
        rows[#rows + 1] = { "SELECT * FROM help", "shows this help" }
        rows[#rows + 1] = { "SELECT * FROM backends", "lists the backends and their state" }
    else
        set_error("use 'SELECT * FROM help' to see the supported commands")
        return proxy.PROXY_SEND_RESULT
    end
    proxy.response = {
        type = proxy.MYSQLD_PACKET_OK,
        resultset = {
            fields = fields,
            rows = rows
        }
    }
    return proxy.PROXY_SEND_RESULT
end

爲服務腳本提供配置文件

#####vim /etc/sysconfig/mysql-proxy
# Options for mysql-proxy
ADMIN_USER="admin"
ADMIN_PASSWORD="admin"
ADMIN_ADDRESS=""
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_ADDRESS="0.0.0.0:3306"
PROXY_USER="mysql-proxy"
PROXY_OPTIONS="--daemon --log-level=info --log-file="/var/log/mysql-proxy.log" --plugins=proxy --plugins=admin --proxy-backend-addresses=192.168.1.201:3306 --proxy-read-only-backend-addresses=192.168.1.202:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"

mysql-proxy的配置選項

mysql-proxy的配置選項大體可分爲幫助選項、管理選項、代理選項及應用程序選項幾類,下面一塊兒去介紹它們。
--help
--help-admin
--help-proxy
--help-all ———— 以上四個選項均用於獲取幫助信息;
--proxy-address=host:port ———— 代理服務監聽的地址和端口;
--admin-address=host:port ———— 管理模塊監聽的地址和端口;
--proxy-backend-addresses=host:port ———— 後端mysql服務器的地址和端口;
--proxy-read-only-backend-addresses=host:port ———— 後端只讀mysql服務器的地址和端口;
--proxy-lua-script=file_name ———— 完成mysql代理功能的Lua腳本;
--daemon ———— 以守護進程模式啓動mysql-proxy;
--keepalive ———— 在mysql-proxy崩潰時嘗試重啓之;
--log-file=/path/to/log_file_name ———— 日誌文件名稱;
--log-level=level ———— 日誌級別;
--log-use-syslog ———— 基於syslog記錄日誌;
--plugins=plugin,.. ———— 在mysql-proxy啓動時加載的插件;
--user=user_name ———— 運行mysql-proxy進程的用戶;
--defaults-file=/path/to/conf_file_name ———— 默認使用的配置文件路徑;其配置段使用[mysql-proxy]標識;
--proxy-skip-profiling ———— 禁用profile;
--pid-file=/path/to/pid_file_name ———— 進程文件名;

啓動服務並查看端口

#####重啓服務
[root@localhost ~]# service mysql-proxy restart
Stopping /usr/local/mysql-proxy/bin/mysql-proxy:           [  OK  ]
Starting /usr/local/mysql-proxy/bin/mysql-proxy:           [  OK  ]
#####查看端口,3306爲服務端口,4041爲管理端口
[root@localhost ~]# netstat -tnlp
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:22                  0.0.0.0:*                   LISTEN      1120/sshd      
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      1196/master    
tcp        0      0 0.0.0.0:4041                0.0.0.0:*                   LISTEN      2144/mysql-proxy
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      2144/mysql-proxy
tcp        0      0 :::22                       :::*                        LISTEN      1120/sshd      
tcp        0      0 ::1:25                      :::*                        LISTEN      1196/master

管理功能測試(unkown表示後端服務器情況未知)

[root@node2 ~]# mysql -uadmin -h192.168.1.208 --port=4041 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-admin
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
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.
mysql> SELECT * FROM backends;
+-------------+--------------------+---------+------+------+-------------------+
| backend_ndx | address            | state   | type | uuid | connected_clients |
+-------------+--------------------+---------+------+------+-------------------+
|           1 | 192.168.1.201:3306 | unknown | rw   | NULL |                 0 |
|           2 | 192.168.1.202:3306 | unknown | ro   | NULL |                 0 |
+-------------+--------------------+---------+------+------+-------------------+
2 rows in set (0.00 sec)

讀寫分離測試

使用mysql客戶端鏈接mysql-proxy建立數據庫

[root@node2 ~]# mysql -uroot -p -h192.168.1.208 -e 'create database mydb;'
Enter password:

再次查看Mysql_Proxy管理控制檯發現master變爲up,表徵寫請求分配到master

mysql> SELECT * FROM backends;
+-------------+--------------------+---------+------+------+-------------------+
| backend_ndx | address            | state   | type | uuid | connected_clients |
+-------------+--------------------+---------+------+------+-------------------+
|           1 | 192.168.1.201:3306 | up      | rw   | NULL |                 0 |
|           2 | 192.168.1.202:3306 | unknown | ro   | NULL |                 0 |
+-------------+--------------------+---------+------+------+-------------------+
2 rows in set (0.00 sec)

使用mysql客戶端鏈接mysql-proxy查詢操做

[root@node2 ~]#  mysql -uroot -p -h192.168.1.208 -e 'show databases;'
Enter password:
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| soulboy            |
| test               |
+--------------------+

再次查看Mysql_Proxy管理控制檯發現slave也變爲了up,表徵讀請求分配到了slave

mysql> SELECT * FROM backends;
+-------------+--------------------+-------+------+------+-------------------+
| backend_ndx | address            | state | type | uuid | connected_clients |
+-------------+--------------------+-------+------+------+-------------------+
|           1 | 192.168.1.201:3306 | up    | rw   | NULL |                 0 |
|           2 | 192.168.1.202:3306 | up    | ro   | NULL |                 0 |
+-------------+--------------------+-------+------+------+-------------------+
2 rows in set (0.00 sec)

至此Mysql_Proxy成功實現讀寫分離


mysql-5.6基於amoeba實現讀寫分離

  • Amoeba(變形蟲)項目,該開源框架於2008年 開始發佈一款 Amoeba for Mysql軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的 時候充當SQL路由功能,專一於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具備負載均衡、高可用性、SQL 過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結果。 經過Amoeba你可以完成多數據源的高可用、負載均衡、數據切片的功能,目前Amoeba已在不少 企業的生產線上面使用,除以以外變形蟲具備如下優勢:

  • 下降費用:分佈式數據庫在地理上能夠式分佈的。其系統的結構符合這種分佈的要求。容許用 戶在本身的本地錄用、查詢、維護等操做,實行局部控制,下降通訊代價,避免集中式須要更高要求 的硬件設備。並且分佈式數據庫在單臺機器上面數據量較少,其響應速度明顯提高。

  • 提升系統總體可用性:避免了由於單臺數據庫的故障而形成所有癱瘓的後果。

  • 易於擴展處理能力和系統規模:分佈式數據庫系統的結構能夠很容易地擴展系統,在分佈式數 據庫中增長一個新的節點,不影響現有系統的正常運行。這種方式比擴大集中式系統要靈活經濟。在 集中式系統中擴大系統和系統升級,因爲有硬件不兼容和軟件改變困難等缺點,升級的代價經常是昂貴和不可行的。


安裝JDK,因爲Amoeba是java程序所研發,因此須要先安裝JDK程序 jdk-6u31-linux-x64-rpm

chmod +x jdk-6u31-linux-x64-rpm.bin
./jdk-6u31-linux-x64-rpm.bin
 vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH
. /etc/profile.d/java.sh
[root@amoeba ~]# java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)

安裝Amoeba amoeba-mysql-binary-2.2.0.tar

mkdir /usr/local/amoeba
tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
vim /etc/profile.d/amoeba.sh
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$AMOEBA_HOME/bin:$PATH
/etc/profile.d/amoeba.sh
[root@amoeba ~]# amoeba
amoeba start|stop

分別在Master和Slave上執行建立遠程受權用戶amoeba,使用以前的root也能夠,這裏特地爲了區別

mysql> GRANT ALL ON *.* TO 'amoeba'@'192.168.1.%' INDENTIFIED BY 'redhat';
mysql> flush privileges;

配置vim /usr/local/amoeba/conf/dbServers.xml 定義鏈接後端Mysql服務器信息

<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd">
<amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
        <!--
            Each dbServer needs to be configured into a Pool,
            If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration:
             add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig
             such as 'multiPool' dbServer
        -->
    <dbServer name="abstractServer" abstractive="true">
        <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
            <property name="manager">${defaultManager}</property>
            <property name="sendBufferSize">64</property>
            <property name="receiveBufferSize">128</property>
            <!-- mysql port -->
            <property name="port">3306</property>       #主從mysql端口
            <!-- mysql schema -->
            <property name="schema">test</property>     #默認是的庫
            <!-- mysql user -->
            <property name="user">amoeba</property>     #遠程受權用戶
            <!--  mysql password -->                    #遠程受權密碼
            <property name="password">redhat</property>
        </factoryConfig>
        <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
            <property name="maxActive">500</property>
            <property name="maxIdle">500</property>
            <property name="minIdle">10</property>
            <property name="minEvictableIdleTimeMillis">600000</property>
            <property name="timeBetweenEvictionRunsMillis">600000</property>
            <property name="testOnBorrow">true</property>
            <property name="testOnReturn">true</property>
            <property name="testWhileIdle">true</property>
        </poolConfig>
    </dbServer>
    <dbServer name="master"  parent="abstractServer">        #主節點
        <factoryConfig>
            <!-- mysql ip -->
            <property name="ipAddress">192.168.1.201</property>
        </factoryConfig>
    </dbServer>
    <dbServer name="slave"  parent="abstractServer">         #從節點
        <factoryConfig>
            <!-- mysql ip -->
            <property name="ipAddress">192.168.1.202</property>
        </factoryConfig>
    </dbServer>
    <dbServer name="multiPool" virtual="true">
        <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
            <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
            <property name="loadbalance">1</property>        #算法
            <!-- Separated by commas,such as: server1,server2,server1 -->
            <property name="poolNames">slave</property>      #定義數據池
        </poolConfig>
    </dbServer>
</amoeba:dbServers>

配置 vim /usr/local/amoeba/conf/amoeba.xml #定義數據庫讀寫分離及節點管理信息等

<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
<amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">
    <proxy>
        <!-- service class must implements com.meidusa.amoeba.service.Service -->
        <service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager">
            <!-- port -->
            <property name="port">3306</property>     #amoeba監聽端口
            <!-- bind ipAddress -->
            <!--
            <property name="ipAddress">192.168.1.208</property>   #amoeba監聽地址
             -->
            <property name="manager">${clientConnectioneManager}</property>
            <property name="connectionFactory">
                <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
                    <property name="sendBufferSize">128</property>
                    <property name="receiveBufferSize">64</property>
                </bean>
            </property>
            <property name="authenticator">
                <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
                    <property name="user">admin</property>         #mysql客戶端鏈接amoeba使用的帳戶
                    <property name="password">password</property>  #mysql客戶端鏈接amoeba使用的密碼
                    <property name="filter">
                        <bean class="com.meidusa.amoeba.server.IPAccessController">
                            <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
                        </bean>
                    </property>
                </bean>
            </property>
        </service>
        <!-- server class must implements com.meidusa.amoeba.service.Service -->
        <service name="Amoeba Monitor Server" class="com.meidusa.amoeba.monitor.MonitorServer">
            <!-- port -->
            <!--  default value: random number
            <property name="port">9066</property>
            -->
            <!-- bind ipAddress -->
            <property name="ipAddress">127.0.0.1</property>
            <property name="daemon">true</property>
            <property name="manager">${clientConnectioneManager}</property>
            <property name="connectionFactory">
                <bean class="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean>
            </property>
        </service>
        <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">
            <!-- proxy server net IO Read thread size -->
            <property name="readThreadPoolSize">20</property>
            <!-- proxy server client process thread size -->
            <property name="clientSideThreadPoolSize">30</property>
            <!-- mysql server data packet process thread size -->
            <property name="serverSideThreadPoolSize">30</property>
            <!-- per connection cache prepared statement size  -->
            <property name="statementCacheSize">500</property>
            <!-- query timeout( default: 60 second , TimeUnit:second) -->
            <property name="queryTimeout">60</property>
        </runtime>
    </proxy>
    <!--
        Each ConnectionManager will start as thread
        manager responsible for the Connection IO read , Death Detection
    -->
    <connectionManagerList>
        <connectionManager name="clientConnectioneManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
            <property name="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property>
            <!--
              default value is avaliable Processors
            <property name="processors">5</property>
             -->
        </connectionManager>
        <connectionManager name="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">
            <property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>
            <!--
              default value is avaliable Processors
            <property name="processors">5</property>
             -->
        </connectionManager>
    </connectionManagerList>
        <!-- default using file loader -->
    <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
        <property name="configFile">${amoeba.home}/conf/dbServers.xml</property>
    </dbServerLoader>
    <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
        <property name="ruleLoader">
            <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
                <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
                <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
            </bean>
        </property>
        <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
        <property name="LRUMapSize">1500</property>
        <property name="defaultPool">master</property>   #默認池
        <property name="writePool">master</property>     #寫庫
        <property name="readPool">slave</property>       #讀庫
        <property name="needParse">true</property>
    </queryRouter>
</amoeba:configuration>

啓動amoeba服務

amoeba start &
netstat  -tnlp
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:22                  0.0.0.0:*                   LISTEN      1120/sshd        
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      1196/master      
tcp        0      0 :::22                       :::*                        LISTEN      1120/sshd        
tcp        0      0 ::1:25                      :::*                        LISTEN      1196/master      
tcp        0      0 ::ffff:127.0.0.1:41575      :::*                        LISTEN      3097/java        
tcp        0      0 :::3306                     :::*                        LISTEN      3097/java

使用客戶端鏈接amoeba

204303259.png

Master抓包

204427410.png

Slave抓包

204440751.png

至此變形蟲成功實現讀寫分離

相關文章
相關標籤/搜索