新手搭建项目系列——mysql集群搭建

新手搭建项目系列——mysql集群搭建

  • mysql集群搭建
    • 集群配置信息
    • 创建所需目录
    • 主从复制配置
      • mysql-master
        • 下载mysql镜像
        • 配置master同步脚本
        • 配置docker-compose.yml
        • 启动mysql-master
      • mysql-slave1
        • 与mysql-master差异
        • 配置slave同步脚本
        • 配置docker-compose.yml
        • 启动mysql-slave
      • 从库集群
        • 通过nginx实现集群
        • 修改mysql-master服务器上docker-compose.yml
        • 修改mysql-master服务器上create_sync_user.sh
      • 问题排查
      • 需要注意
  • 总结

mysql集群搭建

集群配置信息

mysql搭建主要参照了这位大牛的博客docker篇-(docker-compose搭建mysql高可用主从集群)
本文实现了一主二从的部署,第二个从库以及nginx与主库放在了一台服务器上

节点名 ip
mysql-master 192.168.136.131:3306
mysql-slave1 192.168.136.132:3306
mysql-slave2 192.168.136.131:3307

创建所需目录

  • mysql-master
# 创建mysql目录存放myslq相关文件
mkdir /docker/mysql
# 创建init目录存放init脚本
mkdir /docker/mysql/init
# 创建master目录存放master相关文件
mkdir /docker/mysql/init/master
  • mysql-slave
# 创建mysql目录存放myslq相关文件
mkdir /docker/mysql
# 创建init目录存放init脚本
mkdir /docker/mysql/init
# 创建slave目录存放slave相关文件
mkdir /docker/mysql/init/slave

主从复制配置

mysql-master

下载mysql镜像

# 下载默认latest版本mysql
# 也可以在mysql输入指定版本,如:docker pull mysql:8.0.25
docker pull mysql

配置master同步脚本

#将master初始化脚本写入到init/master目录下
cat > docker/mysql/init/master/create_sync_user.sh <<EOF
  #!/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语句,mysql8以下版本 【WITH mysql_native_password】这段需要删除
  CREATE_USER_SQL="CREATE USER '\$MASTER_SYNC_USER'@'\$ALLOW_HOST' IDENTIFIED WITH mysql_native_password 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"
EOF

配置docker-compose.yml

# 创建并编辑docker-compose.yml
vi /docker/mysql/docker-compose.yml


# 填写如下内容
version: '3'
services:
  mysql-master:
    image: mysql:latest
    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: "192.168.136.%"
      TZ: "Asia/Shanghai"
    ports:
      - 3306:3306
    restart: always
    hostname: mysql-master
    volumes:
      - ./init/master:/docker-entrypoint-initdb.d
    command:
      - "--server-id=1"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"
      - "--log-bin=mysql-bin"
      - "--sync_binlog=1"

启动mysql-master

# 进入mysql文件夹
cd /docker/mysql
# docker-compose命令启动
docer-compose up -d
# 使用docker ps查看正在运行的container
docker ps

在这里插入图片描述

# 使用docker logs命令查看容器的运行情况
docker logs mysql-master

查看到初始化脚本允许后,mysql重新启动成果,mysql-master就、则配置完成

mysql-slave1

与mysql-master差异

mysql-slave的安装方法同mysql-master,但是sh脚本及docker-compose.yml存在较大差异

配置slave同步脚本

#将master初始化脚本写入到init/master目录下
cat > docker/mysql/init/slave/slave.sh <<EOF
  #!/bin/bash
  #定义连接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"
EOF

配置docker-compose.yml

# 创建并编辑docker-compose.yml
vi /docker/mysql/docker-compose.yml


# 填写如下内容
version: '3'
services:
  mysql-slave:
    image: mysql:latest
    container_name: mysql-slave
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      SLAVE_SYNC_USER: "sync_admin"
      SLAVE_SYNC_PASSWORD: "123456"
      ADMIN_USER: "root"
      ADMIN_PASSWORD: "123456"
      # 填写mysql-master ip
      MASTER_HOST: "192.168.136.131"
      TZ: "Asia/Shanghai"
    ports:
      - 3306:3306
    volumes:
      - ./init/slave:/docker-entrypoint-initdb.d
    command:
      - "--server-id=2"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"

启动mysql-slave

# 进入mysql文件夹
cd /docker/mysql
# docker-compose命令启动
docer-compose up -d
# 使用docker ps查看正在运行的container
docker ps

在这里插入图片描述

# 使用docker logs命令查看容器的运行情况
docker logs mysql-slave

新手搭建项目系列——mysql集群搭建_第1张图片

上翻查阅log,可以发现Slave_IO_Running、Slave_SQL_Running两个属性已经是Yes状态,标识主从复制已经完成,验证数据同步我就不演示了。

从库集群

我采用一个主一从在一个服务器上,另一个从库在另外一台服务器上,通过nginx实现正常情况下两个服务器中的一主一从备份,单独的从库服务器挂掉时,主库上的从库会作为备用顶替上。

通过nginx实现集群

  • 创建nginx.conf,开启stream支持
cat > nginx.conf <<EOF
  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 {
      include /opt/nginx/stream/conf.d/*.conf; #加载 /opt/nginx/stream/conf.d目录下面的所有配置文件
  }
EOF
  • 编写mysql.conf
mkdir -p conf.d/stream
cat > conf.d/stream/mysql.conf <<EOF
  proxy_timeout 30m;
  upstream mysql-slave-cluster{
    #docker-compose.yml里面会配置固定mysql-slave的ip地址,这里就填写固定的ip地址
    server 192.168.136.132:3306 weight=1;
    server 192.168.136.131:3307 weight=1 backup; #备用数据库,当上面的数据库挂掉之后,才会使用此数据库,也就是如果上面的数据库没有挂,则所有的流量都很转发到上面的主库
  }
  server {
    listen  0.0.0.0:3308;
    proxy_pass mysql-slave-cluster;
  }
EOF

修改mysql-master服务器上docker-compose.yml

version: '3'
services:
  mysql-master:
    image: mysql:latest
    container_name: mysql-master
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MASTER_SYNC_USER: "sync_admin"
      MASTER_SYNC_PASSWORD: "123456"
      ADMIN_USER: "root"
      ADMIN_PASSWORD: "123456"
      # local是给另外一台服务器上从数据库使用
      ALLOW_HOST_LOCAL: "192.168.136.%"
      # nonlocal是给本机的第二个从数据库使用
      ALLOW_HOST_NONLOCAL: "10.10.%.%"
      TZ: "Asia/Shanghai"
    ports:
      - 3306:3306
    restart: always
    hostname: mysql-master
    volumes:
      - ./init/master:/docker-entrypoint-initdb.d
    command:
      - "--server-id=1"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"
      - "--log-bin=mysql-bin"
      - "--sync_binlog=1"
    networks:
      mysql:
        ipv4_address: "10.10.10.10"
  mysql-slave2:
    image: mysql:latest
    container_name: mysql-slave2
    restart: always
    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"
    ports:
      - 3307:3307
    volumes:
      - ./init/slave:/docker-entrypoint-initdb.d
    command:
      - "--server-id=3"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_unicode_ci"
    networks:
      - mysql
networks:
  mysql:
      driver: bridge
      ipam:
        driver: default
        config:
          - subnet: "10.10.0.0/16"

修改mysql-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_LOCAL=${ALLOW_HOST_LOCAL:-%}
ALLOW_HOST_NONLOCAL=${ALLOW_HOST_NONLOCAL:-%}
#定义创建账号的sql语句
CREATE_LOCAL_USER_SQL="CREATE USER '$MASTER_SYNC_USER'@'$ALLOW_HOST_LOCAL' IDENTIFIED WITH mysql_native_password BY '$MASTER_SYNC_PASSWORD';"
CREATE_NONLOCAL_USER_SQL="CREATE USER '$MASTER_SYNC_USER'@'$ALLOW_HOST_NONLOCAL' IDENTIFIED WITH mysql_native_password BY '$MASTER_SYNC_PASSWORD';"
#定义赋予同步账号权限的sql,这里设置两个权限,REPLICATION SLAVE,属于从节点副本的权限,REPLICATION CLIENT是副本客户端的权限,可以执行show master status语句
GRANT_PRIVILEGES_LOCAL_SQL="GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '$MASTER_SYNC_USER'@'$ALLOW_HOST_LOCAL';"
GRANT_PRIVILEGES_NONLOCAL_SQL="GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '$MASTER_SYNC_USER'@'$ALLOW_HOST_NONLOCAL';"
#定义刷新权限的sql
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"
#执行sql
mysql -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_LOCAL_USER_SQL $CREATE_NONLOCAL_USER_SQL $GRANT_PRIVILEGES_LOCAL_SQL $GRANT_PRIVILEGES_NONLOCAL_SQL $FLUSH_PRIVILEGES_SQL"

问题排查

如果集群建立有问题,首先排查每个节点是否正在运行,如果节点未运行,可以看下节点启动时的logs,来排查问题

# 通过容器的名称或id查看容器的运行logs
docker logs 【container name/id】

可根据logs中的errors等逐个排查

需要注意

我采用一主一从+一从的方式,所以需要注意两台服务器中ip的关系,同服务器内通过docker-compose.yml定义了内部地址,使用内部地址进行通信,不同服务器使用局域网地址进行通讯,ip混乱会导致从库复制同步失败

总结

本章主要介绍通过docker、docker-compose配置mysql主从复制以及从库集群级:

你可能感兴趣的:(新手搭建项目系列,mysql,nginx)