Docker搭建InnoDB Cluster集羣

MySQL集羣架構對比

隨着平臺升級,單節點數據庫提供服務已力不從心。現在需要確定一套集羣方案用以部署mysql集羣。考慮到MySQL官方提供的MySQL Cluster(社區版不支持InnoDB引擎),其他第三方方案存在各種各樣的問題,最終選用InnoDB Cluster方案

主要功能

  • 部署維護便利
  • 遷移簡單
  • 定期備份
  • 橫向擴展
  • 主備、熱切換、易恢復
  • 讀寫分離、負載均衡

InnoDB Cluster架構

MySQL InnoDB集羣爲MySQL提供了完整的高可用性解決方案。 MySQL Shell包含AdminAPI,使您可以輕鬆配置和管理一組至少三個MySQL服務器實例,以充當InnoDB集羣。 每個MySQL服務器實例都運行MySQL Group Replication,它提供了在InnoDB集羣內複製數據的機制,具有內置故障轉移功能。Admin API無需在InnoDB集羣中直接使用組複製。 MySQL Shell可以根據您部署的集羣自動配置自身,將客戶端應用程序透明地連接到服務器實例。如果服務器實例意外故障,羣集將自動重新配置。在默認的單主模式下,InnoDB集羣具有單個讀寫服務器實例 - 主要實例。多個輔助服務器實例是主要副本的副本。如果主服務器出現故障,則輔助服務器將自動升級爲主服務器。MySQL路由器檢測到此情況並將客戶端應用程序轉發到新主服務器。高級用戶還可以將羣集配置爲多主結構。
在這裏插入圖片描述
一般採用MySQL Router、Cluster和MySQL Shell構成的Mysql InnoDB Cluster高可用方案進行搭建
結論:
InnoDB Cluster支持自動Failover、強一致性、讀寫分離、讀庫高可用、讀請求負載均衡,橫向擴展的特性,是比較完備的一套方案。但是部署起來複雜,想要解決router單點問題好需要新增組件,如沒有其他更好的方案暫考慮該方案。

基於docker-compose一鍵部署

此案例需創建自定義網絡,創建docker network create sg-net

version: '3'
services:
  mysql-server-1:
    env_file:
      - mysql-server.env
    image: mysql/mysql-server:8.0.12
    container_name: mysql-server-1
    command: ["mysqld","--server_id=1","--innodb_ft_min_token_size=1","--ft_min_word_len=1","--ngram_token_size=1","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve", "--default_authentication_plugin=mysql_native_password"]
    ports:
      - "3301:3306"
    volumes:
      - ./data/mysql-1:/var/lib/mysql
    networks:
      - sg-net
  mysql-server-2:
    env_file:
      - mysql-server.env
    image: mysql/mysql-server:8.0.12
    container_name: mysql-server-2
    command: ["mysqld","--server_id=2","--innodb_ft_min_token_size=1","--ft_min_word_len=1","--ngram_token_size=1","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve", "--default_authentication_plugin=mysql_native_password"]
    ports:
      - "3302:3306"
    volumes:
      - ./data/mysql-2:/var/lib/mysql
    depends_on:
      - mysql-server-1
    networks:
      - sg-net
  mysql-server-3:
    env_file:
      - mysql-server.env
    image: mysql/mysql-server:8.0.12
    container_name: mysql-server-3
    command: ["mysqld","--server_id=3","--innodb_ft_min_token_size=1","--ft_min_word_len=1","--ngram_token_size=1","--binlog_checksum=NONE","--gtid_mode=ON","--enforce_gtid_consistency=ON","--log_bin","--log_slave_updates=ON","--master_info_repository=TABLE","--relay_log_info_repository=TABLE","--transaction_write_set_extraction=XXHASH64","--user=mysql","--skip-host-cache","--skip-name-resolve", "--default_authentication_plugin=mysql_native_password"]
    ports:
      - "3303:3306"
    volumes:
      - ./data/mysql-3:/var/lib/mysql
    depends_on:
      - mysql-server-1
    networks:
      - sg-net
  mysql-shell:
    env_file:
      - mysql-shell.env
    image: neumayer/mysql-shell-batch
    container_name: mysql-shell
    volumes:
        - ./scripts/:/scripts/
    depends_on:
      - mysql-server-1
      - mysql-server-2
      - mysql-server-3
    networks:
      - sg-net
  mysql-router:
    env_file:
      - mysql-router.env
    image: mysql/mysql-router:8.0
    container_name: mysql-router
    restart: on-failure
    ports:
      - "6446:6446"
    depends_on:
      - mysql-server-1
      - mysql-server-2
      - mysql-server-3
      - mysql-shell
    restart: on-failure
    networks:
      - sg-net
      
networks:
  sg-net:
    external: true

點擊鏈接到github
下載完整代碼與scripts腳本

集羣重啓後無法連接錯誤解決

# 報錯信息
MySQL  mysql-server-1:3306 ssl  JS > var cluster = dba.getCluster(clusterName)
Dba.getCluster: This function is not available through a session to a standalone instance (metadata exists, but GR is not active) (RuntimeError)
# 第一步:登錄到各節點重置master屬性 
mysql>reset master;
# 第二步:重新進入mysql-shell重啓集羣
MySQL  mysql-server-1:3306 ssl  JS > dba.rebootClusterFromCompleteOutage('devCluster');
Reconfiguring the cluster 'devCluster' from complete outage...

The instance 'mysql-server-2:3306' was part of the cluster configuration.
Would you like to rejoin it to the cluster? [y/N]: y

The instance 'mysql-server-3:3306' was part of the cluster configuration.
Would you like to rejoin it to the cluster? [y/N]: y


The cluster was successfully rebooted.

<Cluster:devCluster>
# 第三步:連接集羣並查看狀態
 MySQL  mysql-server-1:3306 ssl  JS > var cluster = dba.getCluster(clusterName)
 MySQL  mysql-server-1:3306 ssl  JS > cluster.status()
 {
    "clusterName": "devCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "mysql-server-1:3306", 
        "ssl": "DISABLED", 
        "status": "OK", 
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
        "topology": {
            "mysql-server-1:3306": {
                "address": "mysql-server-1:3306", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "mysql-server-2:3306": {
                "address": "mysql-server-2:3306", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "mysql-server-3:3306": {
                "address": "mysql-server-3:3306", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }
        }
    }, 
    "groupInformationSourceMember": "mysql://root@mysql-server-1:3306"
}
# 可以看到status都是ONLINE,說明重啓成功

重啓mysql-routerdocker restart mysql-router

常用操作命令

# 檢查節點配置實例,用於加入cluster之前
dba.checkInstanceConfiguration("root@hostname:3306")
# 重啓 
dba.rebootClusterFromCompleteOutage('myCluster');
# 刪除schema
dba.dropMetadataSchema(); 
# 獲取當前集羣
var cluster = dba.getCluster('myCluster') 
# 檢查cluster裏節點狀態
cluster.checkInstanceState("root@hostname:3306") 
# 重新加入節點,我本地測試的時候發現rejoin一直無效,每次是delete後
cluster.rejoinInstance("root@hostname:3306") 
# 刪除集羣
addcluster.dissolve({force:true}) 
# 增加節點
cluster.addInstance("root@hostname:3306") 
# 刪除節點
cluster.removeInstance("root@hostname:3306") 
# 強制刪除節點
cluster.removeInstance('root@host:3306',{force:true}) 
#  解散集羣
cluster.dissolve({force:true})
# 集羣描述
cluster.describe();
# update the metadata
cluster.rescan(); 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章