注意mysql官方提供的mysql cluster方案有很多

其中有 NDB cluster 和 Innodb cluster 别混淆

NDB cluster 出来的时间更长,横向拓展性很大,但是成本更高,而且要使用NdbCluster表引擎,意味着你要将性能更加优越稳定Innodb表引擎全部换成NdbCluster

这里提供的是Innodb cluster,能让中小型创业公司平滑迁移,且成本要低廉很多,两台mysql服务器就可以实现最简单的集群,但是要注意负载均衡更强大的多主模式不支持外键,且对事务的支持有很大的局限性,除非你对你的业务代码有足够的把握,否则不要轻易在生产环境使用多主模式!!!多主模式也是基于MGR,MGR的多主模式尚不稳定。

横向拓展的话目前只能支持到9台,9台一个集群一般来说够用了。

# mysql5.7安装,这里提供yum安装示例,读者可以自行安装
#安装mysql5.7
 wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
 yum -y install mysql57-community-release-el7-10.noarch.rpm
 yum -y install mysql-community-server
 systemctl start mysqld
 systemctl enable mysqld
 #mysql初始密码在/var/log/mysqld.log
 grep "password" /var/log/mysqld.log #记住初始密码,示例sIZyvN5gWt<<
 rm -f mysql57-community-release-el7-10.noarch.rpm# mysql5.7安装方式查看简单安装
 # linux环境为centos7# 安装集群必要组件
 yum -y install mysql-shell mysql-router#假设有三台mysql服务器
 123.456.789.1 #服务器1
 123.456.789.2 #服务器2
 123.456.789.3 #服务器3# 以最高权限root进入mysql服务器
 # 配置权限,生产环境可以不是 root用户
 grant all privileges on *.* to 'root'@'%' identified by 'password';    #密码自己设定
 GRANT ALL PRIVILEGES ON mysql_innodb_cluster_metadata.* TO root@'%' WITH GRANT OPTION;
 GRANT RELOAD,SHUTDOWN,PROCESS,FILE, SUPER,REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO root@'%' WITH GRANT OPTION;
 GRANT SELECT ON *.* TO root@'%' WITH GRANT OPTION; # 修改hosts,示例服务器1
 vim /etc/hosts
 123.456.789.1 mysql1.com
 123.456.789.2 mysql2.com
 123.456.789.3 mysql3.com
 ###其他服务器也类似配置# 修改主机名
 hostnamectl set-hostname mysql1.com
 ###其他服务器也类似配置# 运行mysql-shell
 mysqlsh
 mysql-js> dba.checkInstanceConfiguration('root@mysql1.com:3306')
 #按提示输入密码
 # 此时会报错误或警告,比如数据库中存在没有主键的表,需要加上主键
 mysql-js> \quit #退出
 # 再次运行会出现json格式的错误提示
     "config_errors": [
         {
             "action": "server_update", 
             "current": "CRC32",  #参数目前的值
             "option": "binlog_checksum", #需要配置的参数
             "required": "NONE"    #需要设置的值
         }, 
         {
             "action": "config_update+restart", 
             "current": "OFF", 
             "option": "enforce_gtid_consistency", 
             "required": "ON"
         }, 
         ……
     }
 mysql-js> \quit #退出
 # 修改mysql配置文件,默认路径为
 vim /etc/my.cnf
 # 在[mysqld]中对应配置
     binlog_checksum = NONE
     enforce_gtid_consistency = ON
     ……
 ## 再加上如下参数
 # Group Replication configuration
 loose-group_replication_group_name = a38e32fd-5fb6-11e8-ad7a-00259015d941    ##使用UUID形式,集群中机器使用同一个UUID,自己生成
 loose-group_replication_start_on_boot = OFF
 #loose-group_replication_local_address = svr1:33061        #不写也可以
 #loose-group_replication_group_seeds = svr1:33061,svr2:33061,svr3:3306        #不写也可以
 loose-group_replication_bootstrap_group = OFF
 loose-group_replication_allow_local_disjoint_gtids_join = ON
 # Group Replication configuration multi-primary mode
 ####
 loose-group_replication_single_primary_mode = ON
 #loose-group_replication_single_primary_mode = OFF    ##在单主模式中为ON,在多主模式中为OFF
 ####
 loose-group_replication_enforce_update_everywhere_checks = ON
 # 重启mysql
 systemctl restart mysqld
 # 再次运行mysql-shell
 mysqlsh
 mysql-js> dba.checkInstanceConfiguration('root@mysql1.com:3306')
 # 此时显示成功
     {
         "status": "ok"
     }
 \quit #退出
 ###其他服务器也执行类似操作,注意相应地址不同# 以最高权限root进入mysql服务器
 # 配置权限,生产环境可以不是 root用户
 ###关键步骤
 change master to master_user='root',master_password='password' for channel 'group_replication_recovery';
 ###其他服务器也类似配置
 ## 安装group_replication
 INSTALL PLUGIN group_replication  SONAME 'group_replication.so';
 ##主机
 set global group_replication_bootstrap_group=on;
 start group_replication;
 set global group_replication_bootstrap_group=off;
 #其他从机
 start group_replication;## 登陆
 mysqlsh --uri root@mysql1.com:3306
 ## 创建集群节点
 # 服务器1
 # 单主模式
 mysql-js> var cluster = dba.createCluster('mycluster')##### 多主模式
 mysql-js> var cluster = dba.createCluster('mycluster',{force:1})
 ###上面的语句可能不管用,可能还是单主模式,cluster.dissolve({force:true})解散,用下面的
 mysql-js> var cluster = dba.createCluster('mycluster', {multiMaster:true})
 ##注意多主模式这里有个大坑,会报如下错误
         Dba.createCluster: The table does not comply with the requirements by an external plugin. (MySQL Error 3098)
         
 ##检查mysqld.log,类似如下错误
         ERROR] Plugin group_replication reported: 'Table instances has a foreign key with 'CASCADE' clause. This is not compatible with Group Replication'
         
 ##意思是表中有外键,多主模式是不支持外键的,但是用户的mysql即使是第一次安装也会报这个错误;
 ##其实是dba.createCluster()会创建集群库mysql_innodb_cluster_metadata,在该库中会建立五个表,其中四个表有外键!!
 ##不明白官方为什么留这么大的一个坑,总之,把表中的外键全部删除,再次执行就成功了。
 ##### 多主模式 ## 服务1添加子节点
 mysql-js> cluster.addInstance('root@mysql2.com:3306')
 mysql-js> cluster.addInstance('root@mysql3.com:3306')
 ###此时如果mysql服务器没有开启ssl的话会报错,类似如下错误(没有报错跳过下面的步骤)
         Instance '*******' does not support SSL and cannot join a cluster with SSL (encryption) enabled. ……
         
 ###开启mysql的ssl连接,(三台服务器都要开启)
 mysql_ssl_rsa_setup --user=mysql --datadir=/var/lib/mysql;
 chown mysql:mysql /var/lib/mysql -R  #确保生成的ssl连接文件拥有者是mysql用户
 systemctl restart mysqld
 ###其他服务器也类似配置
 ## 重新添加子节点,需要再次定义cluster,目前只知道删除mysql_innodb_cluster_metadata库可以解决
 mysql-js> var cluster = dba.createCluster('mycluster')
 mysql-js> cluster.addInstance('root@mysql2.com:3306')
 mysql-js> cluster.addInstance('root@mysql3.com:3306')
 ## 查看节点信息
 mysql-js> cluster.status()
 ## 将配置 持久化,写入到  my.cnf
 mysql-js> \connect mysql1.com    #按提示输入密码
 mysql-js> dba.configureLocalInstance('mysql1.com:3306')
 ## 查看基本信息
 mysql-js> cluster.describe()
 ## 退出之后,再查看节点信息
 mysql-js> \quit
 mysqlsh --uri root@mysql1.com:3306
 mysql-js> var cluster = dba.getCluster()
 mysql-js> cluster.status()#####Mysql-router设置#####
 #可以使任意一台主机,包括三台mysql服务器
 mysqlrouter --bootstrap root@mysql1.com:3306 --user mysqlrouter    #按提示输入密码
 ## 启动mysqlrouter
 systemctl start mysqlrouter
 systemctl enable mysqlrouter
 ## 查看端口
 netstat -lntup    #提示命令不存在的话先安装yum install net-tools
 ## 验证
 mysql -u root -h 127.0.0.1 -P 6446 -p    #按提示输入密码
 select @@port;
 select @@hostname;##然后业务就可以使用router服务器的地址和6446端口来连接使用mysql集群,从而实现负载均衡了
 ##不要再直接连三台msyql服务器,连接router会自动处理负载均衡
 ##推荐使用多个router节点做备用,防止单个节点挂掉
 ##官方建议router节点可以部署在应用服务器或者其内网# 节点故障重启后,需要手动加入,示例主节点故障
 cluster.rejoinInstance('root@mysql1.com:3306')
 # 此时连接节点2
 mysqlsh --uri root@mysql2.com:3306
 mysql-js> var cluster = dba.getCluster()
 mysql-js> cluster.status()
 ###此时发现已经自动切换为节点2或3(自动选举的,结果根据实际情况而定)
         "mysql1.com:3306": {
             "address": "mysql1.com:3306", 
             "mode": "n/a", 
             "readReplicas": {}, 
             "role": "HA", 
             "status": "(MISSING)"    ##已经断开
         }, 
         "mysql2.com:3306": {
             "address": "mysql2.com:3306", 
             "mode": "R/W", 
             "readReplicas": {}, 
             "role": "HA", 
             "status": "ONLINE"
         },


        ……
##节点2已经切换成主节点
##通过router连接的集群依然可以正常工作(当然由于少了一台mysql服务器,集群负载能力会相应下降)

下面是官方参考文档,完全照着做有不少坑

https://dev.mysql.com/doc/refman/5.7/en/mysql-innodb-cluster-userguide.html