mysql-proxy實現mysql讀寫分離的配置

來源:互聯網
上載者:User


例子1

1、安裝mysql-proxy

此處下載安裝包http://ftp.ntu.edu.tw/pub/MySQL/Downloads/MySQL-Proxy/
如果是編譯安裝依賴包有    libevent2 1.x   lua 5.1.x  glibc2 2.6.0   pkg-config   libtool 1.5
這裡使用glibc的二進位包解壓即可mysql-proxy-0.8.3-linux-glibc2.3-x86-64bit.tar.gz


tar -zxvf mysql-proxy-0.8.3-linux-glibc2.3-x86-64bit.tar.gz
 mv mysql-proxy-0.8.3-linux-glibc2.3-x86-64bit  /usr/local/mysql-proxy

2、建立好mysql主從複製

master   192.168.216.133:3306
slave      192.168.216.132:3306

3、配置mysql-proxy
建立mysql-proxy設定檔,設定檔中的所有選擇都不能加引號


vim /usr/local/mysql-proxy/mysql-proxy.conf
[mysql-proxy]
 daemon=true                        #以後台守護進程方式啟動
 keepalive=true                     #當進程故障後自動重啟
 log-level=debug                  #設定記錄層級為debug,可以在調試完成後改成info
 log-file=/var/log/mysql-proxy.log                      #設定記錄檔路徑
 basedir=/usr/local/mysql-proxy                        #設定mysql-proxy的家目錄
 proxy-address=192.168.216.132:4040          #指定mysql-proxy的監聽地址
 proxy-backend-addresses=192.168.216.133:3306                                      #設定後台主伺服器
 proxy-read-only-backend-addresses=192.168.216.132:3306                   #設定後台從伺服器
 proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua     #設定讀寫分離指令碼路徑
 admin-address=192.168.216.132:4041        #設定mysql-proxy管理地址,需要家長admin外掛程式
 admin-username=admin                                  #設定登入管理地址使用者
 admin-password=admin                                   #設定系統管理使用者密碼
 admin-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua     #設定管理後台lua指令碼路徑,改指令碼預設沒有要自動定義
配置完mysql-proxy.conf後需要確保該檔案的許可權是600,並確保包含個lua指令碼
通過設定檔啟動mysql-proxy


/usr/local/mysql-proxy/bin/mysql-proxy --plugins=proxy --plugins=admin --defaults-file=mysql-proxy.conf
 --plugins=proxy        #指定proxy外掛程式,該配置寫入設定檔無法啟動
 --plugins=admin       #指定admin外掛程式
 --defaults-file=mysql-proxy.conf           #指定設定檔
4、啟動測試


登入管理地址查看目前狀態


mysql -uadmin -padmin -h192.168.216.132 -P4041

兩個後端伺服器目前狀態為unknown是因為沒有使用者通過mysql-proxy串連到後端

mysql-proxy不對使用者做身分識別驗證,而是下身分識別驗證交予後端伺服器進行驗證的,因此需要在後端伺服器上對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

5、遇到的問題

1、如果日誌中提示 (debug) [network-mysqld.c:1134]: error on a connection (fd: -1 event: 0). closing client connection.

可以修改 rw-splitting.lua中的min_idle_connections = 4和max_idle_connections = 8的只,將其調大

2、如果遇到亂碼需要調整後端mysql的設定的字元集


[mysqld]
 skip-character-set-client-handshake
 init-connect            = 'SET NAMES utf8'
 character_set_server    = utf8

例子2

用MySQL-Proxy實現讀寫分離

實現讀寫分離的LUA指令碼是簡單明了的:

  -- 讀寫分離
  --
  -- 發送所有的非事務性SELECT到一個從資料庫
  if is_in_transaction == 0 and
     packet:byte() == proxy.COM_QUERY and
     packet:sub(2, 7) == "SELECT" then
    local max_conns = -1
    local max_conns_ndx = 0

    for i = 1, #proxy.servers do
      local s = proxy.servers[i]

      -- 選擇一個擁有空閑串連的從資料庫
      if s.type == proxy.BACKEND_TYPE_RO and
         s.idling_connections > 0 then
        if max_conns == -1 or
           s.connected_clients < max_conns then
          max_conns = s.connected_clients
          max_conns_ndx = i
        end
      end
    end

    -- 我們找到了一個擁有空閑串連的從資料庫
    if max_conns_ndx > 0 then
      proxy.connection.backend_ndx = max_conns_ndx
    end
  else
    -- 發送到主要資料庫
  end

  return proxy.PROXY_SEND_QUERY
Jan提醒說這個技巧還可以用來實現其他的資料分布策略,例如分區(Sharding)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.