经过小编两三年的使用,Mysql Innodb Cluster 的稳定性和可靠性还是值得信赖的。 下文有Mysql 5.7.23为例讲解, 本博文讲述的步骤同样适用于Mysql8 和 Mysql 5.7 的其他版本。 本文分四个部分进行讲解:
- 环境初始化
- Mysql数据库安装
- 安装部署MySQL Shell及集群搭建
- 部署实施Mysql-router
一、环境初始化
1. 修改系统最大文件打开数,直接执行下列脚本即可
说明: 数据库服务器建议都要调整此参数
# 可参考 https://blog.youkuaiyun.com/robin90814/article/details/86705155
cat <<EOF >>/etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
EOF
验证:
ulimit -n
2. 卸载mysql和mariadb资源包
2.1 卸载mysql
rpm -qa | grep mysql
rpm -qa | grep -i mysql | xargs rpm -e --nodeps
2.2 卸载mariadb并删除目录(CentOS7 默认安装了mariadb客户端)
# 卸载mariadb
rpm -qa | grep mariadb
rpm -qa | grep mariadb | xargs rpm -e --nodeps
# 删除遗留目录
rm -rf /var/lib/mysql
rm -rf /usr/share/mysql
2.3. 时钟同步(这步真的很重要,以笔者的经验但凡做集群,一定要做时钟同步,这就是规范)参考博文: 使用chrony安装chrony - pycod - 博客园
# 具体参考博文 https://www.cnblogs.com/xuanbjut/p/11758445.html
yum install -y chrony
二、Mysql数据库安装
2.1 将rpm安装包上传到搭建集群的宿主机上
mkdir -p /usr/local/src/mysql
cd /usr/local/src/mysql
# 上传rpm包,并分别拷贝到其他主机上
scp /usr/local/src/mysql/*rpm root@192.168.2.33:/usr/local/src/mysql/
scp /usr/local/src/mysql/*rpm root@192.168.2.34:/usr/local/src/mysql/
2.2 安装Mysql数据库,如下:
ll /usr/local/src/mysql
rpm -ivh mysql-community-common-5.7.23-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.23-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.23-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-common-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-libs-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-client-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-server-5.7.23-1.el7.x86_64.rpm
yum install mysql-community-devel-5.7.23-1.el7.x86_64
2.3 配置配置文件:my.cnf
# 备份原始文件,这是个好习惯
cp /etc/my.cnf /etc/my.cnf.bak
# 写入默认配置
cat <<EOF >/etc/my.cnf
[client]
port = 13306 # 不建议默认密码
default-character-set = utf8mb4
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 13306
read_only=0
log_bin_trust_function_creators=TRUE
datadir = /var/lib/mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
log-error = /var/log/mysqld.log
character_set_server = utf8mb4
user = mysql
bind-address = *
default_storage_engine = InnoDB
max_allowed_packet = 512M
max_connections = 20480
open_files_limit = 65535
symbolic-links=0
key_buffer_size = 64M
connect_timeout = 3600
wait_timeout = 3600
interactive_timeout = 3600
explicit_defaults_for_timestamp = true
innodb_buffer_pool_size = 4G # 物理内存的 75% 左右
innodb_buffer_pool_instances=4 # 平均一个实例1G就行
EOF
2.4 启动mysql服务
systemctl start mysqld
systemctl enable mysqld
systemctl status mysqld
2.5 登录mysql
MySQL_PASS=$(cat /var/log/mysqld.log | grep "A temporary password" | awk '{print $NF}')
mysql -u root -p"${MySQL_PASS}"
2.6 更新密码,需要关闭Binlog:
# 关闭Bin log很重要,避免各个节点之间出现GTID不一致
SET SQL_LOG_BIN=0;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'sysroot123?';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'sysroot123?' WITH GRANT OPTION;
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
exit
三、 安装部署MySQL Shell及集群搭建
MySQL Shell是MySQL InnoDB Cluster集群的管理工具,负责管理维护整改InnoDB Cluster,MySQL Shell是MySQL Server的高级客户端和代码编辑器。除了提供的SQL功能,类似于 mysql,MySQL Shell还提供了JavaScript和Python的脚本功能,并包含用于MySQL的API。
3.1 安装mysql-shell
所有Innodb节点都需要安装,这里以192.168.2.32节点为例说明
rpm -ivh mysql-shell-8.0.13-1.el7.x86_64.rpm
3.2 连接本地的MySQL Server:
mysqlsh --uri root@192.168.2.32:13306
3.3 检查当前实例的配置:
mysql-js> dba.checkInstanceConfiguration('root@192.168.2.32:13306')
3.4 配置实例:
mysql-js> dba.configureLocalInstance('root@192.168.2.32:13306')
# 保存本地配置文件,默认为/etc/my.cnf,请输入: Y 确认
3.5 退出连接:
mysql-js> \exit
3.6 重启MySQL服务使刚才的配置生效:
systemctl restart mysqld.service && systemctl status mysqld.service
3.7 重新检测每个实例的状态:
mysqlsh --uri root@192.168.2.32:13306
mysql-js> dba.checkInstanceConfiguration('root@192.168.2.32:13306')
# 输出如下结果,即说明检查通过
The instance '192.168.2.32:13306' is valid for InnoDB cluster usage.
{
"status": "ok"
}
退出
mysql-js> \exit
3.8 创建集群 mycluster(只在192.168.2.32一个节点上执行)
# 只在主节点上执行即可
mysqlsh --uri root@192.168.2.32:13306
var c= dba.createCluster('mycluster')
# 添加实例
c.addInstance('root@192.168.2.33:13306')
c.addInstance('root@192.168.2.34:13306')
# 检查结果
c.status()
3.9 持久化集群配置:
注意: 每个Innodb节点 一定要持久化集群配置,所以在所有Innodb节点执行以下操作:
mysqlsh --uri root@192.168.2.32:13306
dba.configureLocalInstance('root@192.168.2.32:13306')
四、 部署实施Mysql-router
MySQL Router通过智能地将客户端连接路由到MySQL服务器来简化应用程序开发。MySQL使用组复制在多个服务器之间复制数据,当服务器发生故障时执行自动故障转移,基于paxos协议在剩余实例中选举一个新的主库。这里存在一个问题,如果应用程序直连主库,当发生主库切换时可用的数据库IP地址发生变化,客户端应用程序必须自行修改它的连接配置。这种方案极不现实,因为需要应用程序了解组复制的拓扑结构并知道哪个MySQL实例是主库,对于应用程序显然是强人所难,这些处理逻辑本应对应用透明。
而这正是MySQL Router的用武之地。当与InnoDB Cluster一起使用时,MySQL Router充当代理,向应用程序隐藏网络上的多个MySQL实例,并将数据请求映射到其中一个集群实例。只要有足够的在线副本并且组件之间的通信完好无损,客户端就能够连接其中一个实例,保持对外服务的连续性。应用程序要做的只是连接到Router,而不是直连MySQL数据库实例,其它的交给Router处理即可。
MySQL Router的推荐部署模型是与InnoDB Cluster集成,其中Router与应用程序最好位于同一主机上。
参考: MySQL Router 8 详解_wzy0623的专栏-优快云博客_mysql-router
这里我们在所有的Innodb节点上都部署上mysql-router,如下以192.168.2.32为例说明:
rpm -ivh mysql-router-community-8.0.13-1.el7.x86_64.rpm
初始化:
mysqlrouter --bootstrap root@192.168.2.32:13306 --user=mysqlrouter --force
重启:
systemctl start mysqlrouter.service && systemctl enable mysqlrouter.service && systemctl status mysqlrouter.service
验证:
在任意一个集群节点上执行如下操作:
$ mysqlsh --uri root@192.168.2.32:6446
mysql-js> \sql
mysql-sql> select @@port;
mysql-sql> \js
mysql-js> var c= dba.getCluster("mycluster")
mysql-js> c.status()
mysql-js> \exit
- 到这里集群搭建完毕了,为了应用程序的高可用,建议通过K8s Service 或nginx 代理 访问所有的 router节点
- 如何在K8s中创建代理Mysql的集群服务,请阅读笔者的另一篇博文:Kubernetes(k8s)中Service代理容器外服务(Mysql、Redis、MongoDB)_bhl120的博客-优快云博客_k8s 代理mysql
- 如何用nginx中代理Mysql的集群服务,本周五提供。