docker-compose搭建mysql高可用主从集群
新建mysql文件夹和其他文件如图:
编写docker-compose.yml文件
version: '3' services: mysql-slave-lb: image: nginx:latest container_name: mysql-slave-lb ports: - 3307:3307 volumes: - /usr/local/mysql/nginx/nginx.conf:/etc/nginx/nginx.conf networks: - mysql depends_on: - mysql-master - mysql-slave1 - mysql-slave2 mysql-master: image: mysql:8.0 container_name: mysql-master environment: MYSQL_ROOT_PASSWORD: "123456" MASTER_SYNC_USER: "sync_admin" #设置脚本中定义的用于同步的账号 MASTER_SYNC_PASSWORD: "123456" #设置脚本中定义的用于同步的密码 ADMIN_USER: "root" #当前容器用于拥有创建账号功能的数据库账号 ADMIN_PASSWORD: "123456" ALLOW_HOST: "10.10.%.%" #允许同步账号的host地址 TZ: "Asia/Shanghai" #解决时区问题 ports: - 3306:3306 networks: mysql: ipv4_address: "10.10.10.10" #固定ip,因为从库在连接master的时候,需要设置host volumes: - /usr/local/mysql/master:/docker-entrypoint-initdb.d #挂载master脚本 - /usr/local/mysql/master/data:/var/lib/mysql command: - "--server-id=1" - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" - "--log-bin=mysql-bin" - "--sync_binlog=1" mysql-slave1: image: mysql:8.0 container_name: mysql-slave1 environment: MYSQL_ROOT_PASSWORD: "123456" SLAVE_SYNC_USER: "sync_admin" #用于同步的账号,由master创建 SLAVE_SYNC_PASSWORD: "123456" ADMIN_USER: "root" ADMIN_PASSWORD: "123456" MASTER_HOST: "10.10.10.10" #master地址,开启主从同步需要连接master TZ: "Asia/Shanghai" #设置时区 networks: mysql: ipv4_address: "10.10.10.20" #固定ip volumes: - /usr/local/mysql/slave1:/docker-entrypoint-initdb.d #挂载slave脚本 - /usr/local/mysql/slave1/data:/var/lib/mysql command: - "--server-id=2" - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" mysql-slave2: image: mysql:8.0 container_name: mysql-slave2 environment: MYSQL_ROOT_PASSWORD: "123456" SLAVE_SYNC_USER: "sync_admin" SLAVE_SYNC_PASSWORD: "123456" ADMIN_USER: "root" ADMIN_PASSWORD: "123456" MASTER_HOST: "10.10.10.10" TZ: "Asia/Shanghai" networks: mysql: ipv4_address: "10.10.10.30" #固定ip volumes: - /usr/local/mysql/slave2:/docker-entrypoint-initdb.d #挂载slave脚本 - /usr/local/mysql/slave2/data:/var/lib/mysql command: #这里需要修改server-id,保证每个mysql容器的server-id都不一样 - "--server-id=3" - "--character-set-server=utf8mb4" - "--collation-server=utf8mb4_unicode_ci" networks: mysql: driver: bridge ipam: driver: default config: - subnet: "10.10.0.0/16"
编写master用于创建同步账号的脚本create_sync_user.sh
#!/bin/bash #定义用于同步的用户名 MASTER_SYNC_USER=${MASTER_SYNC_USER:-sync_admin} #定义用于同步的用户密码 MASTER_SYNC_PASSWORD=${MASTER_SYNC_PASSWORD:-123456} #定义用于登录mysql的用户名 ADMIN_USER=${ADMIN_USER:-root} #定义用于登录mysql的用户密码 ADMIN_PASSWORD=${ADMIN_PASSWORD:-123456} #定义运行登录的host地址 ALLOW_HOST=${ALLOW_HOST:-%} #定义创建账号的sql语句 CREATE_USER_SQL="CREATE USER '$MASTER_SYNC_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_SYNC_PASSWORD';" #定义赋予同步账号权限的sql,这里设置两个权限,REPLICATION SLAVE,属于从节点副本的权限,REPLICATION CLIENT是副本客户端的权限,可以执行show master status语句 GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '$MASTER_SYNC_USER'@'$ALLOW_HOST';" #定义刷新权限的sql FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;" #执行sql mysql -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL $GRANT_PRIVILEGES_SQL $FLUSH_PRIVILEGES_SQL"
编写slave脚本slave.sh
#定义连接master进行同步的账号 SLAVE_SYNC_USER="${SLAVE_SYNC_USER:-sync_admin}" #定义连接master进行同步的账号密码 SLAVE_SYNC_PASSWORD="${SLAVE_SYNC_PASSWORD:-123456}" #定义slave数据库账号 ADMIN_USER="${ADMIN_USER:-root}" #定义slave数据库密码 ADMIN_PASSWORD="${ADMIN_PASSWORD:-123456}" #定义连接master数据库host地址 MASTER_HOST="${MASTER_HOST:-%}" #等待10s,保证master数据库启动成功,不然会连接失败 sleep 10 #连接master数据库,查询二进制数据,并解析出logfile和pos,这里同步用户要开启 REPLICATION CLIENT权限,才能使用SHOW MASTER STATUS; RESULT=`mysql -u"$SLAVE_SYNC_USER" -h$MASTER_HOST -p"$SLAVE_SYNC_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'` #解析出logfile LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'` #解析出pos LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'` #设置连接master的同步相关信息 SYNC_SQL="change master to master_host='$MASTER_HOST',master_user='$SLAVE_SYNC_USER',master_password='$SLAVE_SYNC_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;" #开启同步 START_SYNC_SQL="start slave;" #查看同步状态 STATUS_SQL="show slave status\G;" mysql -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$SYNC_SQL $START_SYNC_SQL $STATUS_SQL"
加入nginx,实现slave的负载均衡
nginx下创建nginx.conf
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } # 添加stream模块,实现tcp反向代理 stream { proxy_timeout 30m; upstream mysql-slave-cluster{ #docker-compose.yml里面会配置固定mysql-slave的ip地址,这里就填写固定的ip地址 server 10.10.10.20:3306 weight=1; server 10.10.10.30:3306 weight=1 backup; #备用数据库,当上面的数据库挂掉之后,才会使用此数据库,也就是如果上面的数据库没有挂,则所有的流量都很转发到上面的主库 } server { listen 0.0.0.0:3307; proxy_pass mysql-slave-cluster; } }
启动容器docker-compose up -d
成功后测试一下