MySQL Fabric 是一個用於管理 MySQL 服務器羣的可擴展框架。該框架實現了兩個特性 — 高可用性 (HA) 以及使用數據分片的橫向擴展。這兩個特性既能夠單獨使用,也能夠結合使用。本文只測試高可用性。
html
測試環境java
centos 6.5node
192.168.17.177 mysql數據庫python
192.168.17.178 Fabric服務器和mysql數據庫mysql
192.168.17.179 mysql數據庫sql
192.168.17.180 mysql數據庫shell
防火牆數據庫
重啓後永久性生效:vim
開啓:chkconfig iptables oncentos
關閉:chkconfig iptables off
即時生效,重啓後失效:
開啓:service iptables start
關閉:service iptables stop
一、安裝mysql,4臺服務器安裝相同版本mysql和相同配置
先刪除centos6.5自帶mysql
rpm -qa | grep mysql rpm -e --nodeps mysql-libs-5.1.71-1.el6.x86_64
下載mysql,http://dev.mysql.com/downloads/mysql/
MySQL-client-5.6.28-1.el6.x86_64.rpm MySQL-devel-5.6.28-1.el6.x86_64.rpm MySQL-server-5.6.28-1.el6.x86_64.rpm MySQL-shared-5.6.28-1.el6.x86_64.rpm MySQL-shared-compat-5.6.28-1.el6.x86_64.rpm
安裝mysql
yum localinstall –-nogpgcheck *.rpm
配置mysql
more /root/.mysql_secret //查看默認自帶密碼 service mysql start //啓動mysql /usr/bin/mysql_secure_installation //初始化mysql
fabric是基於GTID主從複製,因此這些實例中必需要啓用GTID,在mysql的配置文件要加上下邊參數:
編輯mysql配置文件
vim /usr/my.cnf
在文件中加上
gtid_mode=ON log-bin log-slave-updates enforce-gtid-consistency server_id=1 //各個服務器的值不一樣
建立mysql管理員賬號,fabric須要使用mysql管理員級別賬號來管理數據庫,4臺mysql服務器建立相同的賬號
GRANT ALL PRIVILEGES ON *.* TO 'fabric'@'%' IDENTIFIED BY 'secret' WITH GRANT OPTION; FLUSH PRIVILEGES;
二、在192.168.17.178服務器安裝mysql fabric
Fabric已經被打包到了MySQL Utilities中,下載MySQL Utilities就能夠了,另外fabric操做mysql須要使用python鏈接器,須要同時下載mysql-utilities-1.5.6-1.el6.noarch.rpm(http://dev.mysql.com/downloads/utilities/)、
mysql-connector-python-2.1.3-1.el6.x86_64.rpm(http://dev.mysql.com/downloads/connector/python/)安裝。
安裝fabric
yum localinstall –-nogpgcheck *.rpm
vim /etc/mysql/fabric.cfg // 修改fabric配置
[DEFAULT] prefix = sysconfdir = /etc logdir = /var/log [statistics] prune_time = 3600 [logging] url = file:///var/log/fabric.log level = INFO [storage] auth_plugin = mysql_native_password database = fabric user = fabric //與上邊建立的賬號一致 address = 192.168.17.178:3306 // fabric Backing Store用的mysql connection_delay = 1 connection_timeout = 6 password = secret //與上邊建立的賬號一致 connection_attempts = 6 [failure_tracking] notification_interval = 60 notification_clients = 50 detection_timeout = 1 detection_interval = 6 notifications = 300 detections = 3 failover_interval = 0 prune_time = 3600 [servers] // 192.168.17.180、192.168.17.17九、192.168.17.177三臺mysql的管理員賬號 restore_user = fabric unreachable_timeout = 5 backup_password = secret backup_user = fabric user = fabric restore_password = secret password = secret [connector] ttl = 1 [protocol.xmlrpc] disable_authentication = yes // 關閉驗證 ssl_cert = realm = MySQL Fabric ssl_key = ssl_ca = threads = 5 user = admin address = 192.168.17.178:32274 password = [executor] executors = 5 [sharding] prune_limit = 10000 mysqldump_program = /usr/bin/mysqldump mysqlclient_program = /usr/bin/mysql [protocol.mysql] disable_authentication = yes // 關閉驗證 ssl_cert = ssl_key = ssl_ca = user = admin address = 192.168.17.178:32275 password =
初始化Backing Store數據,初始化完成後,能夠在192.168.17.178的mysql中看到fabric數據表,這個數據庫主要用來Backing Store使用。
mysqlfabric manage setup
啓動fabric
mysqlfabric manage start
創建HA服務器組
mysqlfabric group create my_group
將mysql服務器加入HA組中
mysqlfabric group add my_group 192.168.17.177:3306 mysqlfabric group add my_group 192.168.17.179:3306 mysqlfabric group add my_group 192.168.17.180:3306
添加完成後,默認狀況不會本身選出主庫(PRIMARY),可讓fabric自動選出主庫,也能夠手動選出主庫
1)執行下邊命令讓fabric選出主庫
mysqlfabric group promote my_group
2)手動指定主庫
mysqlfabric server set_status 192.168.17.179:3306 primary // set_status可手工指定4個狀態primary, secondary,spare, or faulty.
添加完成後,可使用使用下邊命令查看當前my_group組中的服務器情況
mysqlfabric group lookup_servers my_group Fabric UUID: 5ca1ab1e-a007-feed-f00d-cab3fe13249e Time-To-Live: 1 server_uuid address status mode weight ------------------------------------ ------------------- --------- ---------- ------ 086d9569-a78a-11e5-9205-005056ab3497 192.168.17.180:3306 SECONDARY READ_ONLY 1.0 452ee193-a4a7-11e5-bf33-005056ab482f 192.168.17.179:3306 PRIMARY READ_WRITE 1.0 edcbd377-a4a7-11e5-bf37-005056ab131b 192.168.17.177:3306 SECONDARY READ_ONLY 1.0
fabric經常使用相關命令
mysqlfabric group create my_group #建立HA組 mysqlfabric group destroy my_group #刪除HA組 mysqlfabric group add my_group 192.168.17.180:3306 #添加組成員 mysqlfabric group remove my_group xxxxxxxx #移出組成員 mysqlfabric group lookup_servers my_group #查看組成員 mysqlfabric group promote my_group #選舉master mysqlfabric groupactivate my_group #激活自動故障轉移 mysqlfabric group deactivate my_group #禁用自動故障轉移 mysqlfabric serverset_status server_uuid status #變動服務器狀態 mysqlfabric help manage #manage命令幫助 mysqlfabric help group #group命令幫助 mysqlfabric help server #server命令幫助
三、java測試代碼建庫,建表,插入數據,查詢操做
操做數據庫的順序改成先鏈接Fabric,再由Fabric內部操做具體的數據庫,這裏使用java例子,測試代碼來自http://dev.mysql.com/downloads/connector/j/ java驅動包中的例子
package demo.fabric; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import com.mysql.fabric.jdbc.FabricMySQLConnection; /** * Demonstrate working with employee data in MySQL Fabric with Connector/J and the JDBC APIs. */ public class EmployeesTest { public static void main(String args[]) throws Exception { String hostname = "192.168.17.178"; String port = "32274"; String database = "employees"; String user = "fabric"; String password = "secret"; String baseUrl = "jdbc:mysql:fabric://" + hostname + ":" + Integer.valueOf(port) + "/"; // Load the driver if running under Java 5 if (!com.mysql.jdbc.Util.isJdbc4()) { Class.forName("com.mysql.fabric.jdbc.FabricMySQLDriver"); System.out.println("load driver"); } Connection rawConnection = DriverManager.getConnection(baseUrl + "mysql?fabricServerGroup=my_group", user, password); Statement statement = rawConnection.createStatement(); statement.executeUpdate("create database if not exists employees"); System.out.println("create database if not exists employees"); statement.close(); rawConnection.close(); // The 1-st way is to set it's name explicitly via the "fabricServerGroup" connection property rawConnection = DriverManager.getConnection(baseUrl + database + "?fabricServerGroup=my_group", user, password); statement = rawConnection.createStatement(); statement.executeUpdate("create database if not exists employees"); statement.close(); rawConnection.close(); rawConnection = DriverManager.getConnection(baseUrl + database + "?fabricServerGroup=my_group", user, password); statement = rawConnection.createStatement(); statement.executeUpdate("drop table if exists employees"); statement.executeUpdate("create table employees (emp_no int not null, first_name varchar(50), last_name varchar(50), primary key (emp_no))"); // 2. Insert data // Cast to a Fabric connection to have access to specific methods FabricMySQLConnection connection = (FabricMySQLConnection) rawConnection; // example data used to create employee records Integer ids[] = new Integer[] { 1, 2, 10001, 10002 }; String firstNames[] = new String[] { "John", "Jane", "Andy", "Alice" }; String lastNames[] = new String[] { "Doe", "Doe", "Wiley", "Wein" }; // insert employee data PreparedStatement ps = connection.prepareStatement("INSERT INTO employees.employees VALUES (?,?,?)"); for (int i = 0; i < 4; ++i) { ps.setInt(1, ids[i]); ps.setString(2, firstNames[i]); ps.setString(3, lastNames[i]); ps.executeUpdate(); } System.out.println("Querying employees"); System.out.format("%7s | %-30s | %-30s%n", "emp_no", "first_name", "last_name"); System.out.println("--------+--------------------------------+-------------------------------"); ps = connection.prepareStatement("select emp_no, first_name, last_name from employees where emp_no = ?"); for (int i = 0; i < 4; ++i) { ps.setInt(1, ids[i]); ResultSet rs = ps.executeQuery(); rs.next(); System.out.format("%7d | %-30s | %-30s%n", rs.getInt(1), rs.getString(2), rs.getString(3)); rs.close(); } ps.close(); // connection.setServerGroupName("my_group"); // statement.executeUpdate("drop table if exists employees"); statement.close(); connection.close(); } }
若是當前PRIMARY爲192.168.17.179:3306,直接鏈接192.168.17.179進行增長修改刪除,數據能自動同步到192.168.17.177和192.168.17.180,完整的主從模式。
若是當前PRIMARY爲192.168.17.179:3306,直接鏈接192.168.17.177或192.168.17.180,會形成PRIMARY主庫的修改沒法同步到從數據,須要把從數據庫衝突數據刪除,重啓衝突的從數據庫,經過mysqlfabric server set_status修改從數據庫的狀態爲secondary,數據會從新同步。
參考