【集群运维篇】使用docker简单快速搭建mysql集群

【集群运维篇】使用docker 搭建mysql集群

一、mysql 主从master-slaver搭建

  1. 使用docker容器搭建master和slave 实例

    #mysql master实例并启动
    docker run -p 3307:3306 --name mysql-master \
    -v ~/mydata/mysql/master/log:/var/log/mysql \
    -v ~/mydata/mysql/master/conf:/etc/mysql \
    -v ~/mydata/mysql/master/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 \
    -d mysql:5.7
    
    #mysql slave实例并启动
    docker run -p 3308:3306 --name mysql-slaver-01 \
    -v ~/mydata/mysql/slaver/log:/var/log/mysql \
    -v ~/mydata/mysql/slaver/conf:/etc/mysql \
    -v ~/mydata/mysql/slaver/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 \
    -d mysql:5.7
    

    参数说明:

    -p 3306:3306:将容器的3306端口映射到主机的3307端口;

    -v ~/mydata/mysql/master/log:/var/log/mysql:将容器里的日志文件夹挂载到主机当前目录;
    -v ~/mydata/mysql/master/conf:/etc/mysql:将容器里的配置文件夹挂载到主机当前目录;
    -v ~/mydata/mysql/master/data:/var/lib/mysq:将容器里的文件夹挂载到主机当前目录;

修改mysql(master/slaver)配置文件

  1. 修改master配置文件,执行命令 vim ~/mydata/mysql/master/conf/my.cnf

    #基本配置如下
    [client]
    default-character-set=utf8
    [mysql]
    default-character-set=utf8
    [mysqld]
    init_connect='SET collation_connection = utf8_unicode_ci'
    init_connect='SET NAMES utf8'
    character_set_server=utf8
    collation-server=utf8_unicode_ci
    skip-character-set-client-handshake
    #选项可以禁用dns解析,加快连接速度。但是这样不能在mysql的授权表中使用主机名了,只能使用IP。
    skip-name-resolve 
    #sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 这个有问题,在创建完新用户登录时报错
    sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    
    
    #master主服务器的配置
    #为服务器添加唯一的编号
    server-id=1
    #开启二进制日志
    log-bin=mysql-bin
    #是不是只读模式,0则不是;
    read-only=0
    #指定哪些库需要同步,如果是多个指定多行即可
    binlog-do-db=test1
    #binlog-do-db=test2
    #binlog-do-db=test3
    
    #在主从同步的环境中,replicate-ignore-db用来设置不需要同步的库。
    replicate-ignore-db=mysql
    replicate-ignore-db=sys
    replicate-ignore-db=information_schema
    replicate-ignore-db=performance_schema
    
  2. 修改slaver配置文件,执行命令 vim ~/mydata/mysql/slaver/conf/my.cnf

    #基本配置如下
    [client]
    default-character-set=utf8
    [mysql]
    default-character-set=utf8
    [mysqld]
    init_connect='SET collation_connection = utf8_unicode_ci'
    init_connect='SET NAMES utf8'
    character_set_server=utf8
    collation-server=utf8_unicode_ci
    skip-character-set-client-handshake
    #选项可以禁用dns解析,加快连接速度。但是这样不能在mysql的授权表中使用主机名了,只能使用IP。
    skip-name-resolve 
    #sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 这个有问题,在创建完新用户登录时报错
    sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    
    
    #slaver从服务器的配置
    #为服务器添加唯一的编号,在一个集群中不能有相同ID
    server-id=2
    #开启二进制日志
    log-bin=mysql-bin
    #是不是只读模式;
    read-only=1
    #指定哪些库需要同步,如果是多个指定多行即可
    binlog-do-db=test1
    #binlog-do-db=test2
    #binlog-do-db=test3
    
    #在主从同步的环境中,replicate-ignore-db用来设置不需要同步的库。
    replicate-ignore-db=mysql
    replicate-ignore-db=sys
    replicate-ignore-db=information_schema
    replicate-ignore-db=performance_schema
    
  3. 配置设置好后,重启mysql容器服务

    docker restart mysql-master mysql-slaver-01
    
  4. 在master主库服务器上添加同步用户

    1. 首先我们为了方便调试,需进入容器数据库内部去设置远程访问权限(生产环境可以忽略此部分

      #进入容器mysql-master/mysql-slaver-01数据库分别设置远程权限
      docker exec -it mysql-master /bin/bash
      #输入mysql客户端命令连接数据库
      mysql -uroot -p
      #设置root可以远程访问权限
      grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
      #刷新权限生效
      flush privileges;
      
    2. 此时我们就可以远程连接容器内到数据库并进行同步账号添加

      #192.168.0.100是我的容器宿主机IP地址
      mysql -h192.168.0.100 -uroot -P3307 -p 
      #添加用于同步的账号backup
      GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
      #刷新权限生效
      flush privileges;
      #查看用户是否创建成功
      select user,host from mysql.user;
      #查看master状态
      show master status\G;
      
  5. slave数据库连接master数据库配置并启动同步

    #输入mysql客户端命令连接数据库
    mysql -uroot -p
    #告诉从mysql,需要同步那个主节点
    change master to
    master_host='192.168.0.100',
    master_user='backup',
    master_password='123456',
    master_log_file='mysql-bin.000001',
    master_log_pos=0,
    master_port=3307;
    #开始同步
    start slave; #停止同步 stop slave
    #查看从服务状态
    show slave status\G
    

    以上解决了主从备份问题,但是没有解决单库单表数据量较大带来的性能问题,要解决这个问题我们需要引入数据分片概念,即见同一库和同一表的数据分拆到若干子库子表中存储。目前市面上有很多数据分片中间件工具,如mycat、shardingsphere等,下面我们以shardingsphere为例介绍;

二、使用sharding-proxy中间件实现分库分表&读写分离提升数据库存储能力

  1. 使用docker安装 sharding-proxy

    # 官方docker镜像地址
    docker pull apache/sharding-proxy
    或
    docker pull shardingsphere/sharding-proxy
    
    
    #手动构建docker(镜像可选)
    git clone https://github.com/apache/shardingsphere
    mvn clean install
    cd shardingsphere-distribution/shardingsphere-proxy-distribution
    mvn clean package -Prelease,docker
    
    
    ##
    #执行docker参数说明
    #端口默认为3307,但我们可以自定义端口 3308 和 13308。3308 表示 docker 容器端口, 13308表示宿主机端口。
    #将容器里的配置文件夹挂载到主机当前目录,必须挂载配置路径到 /opt/sharding-proxy/conf。此路径可以在 https://hub.docker.com/r/shardingsphere/sharding-proxy 查看
    #如需使用外部 jar 包,可将其所在目录挂载到 /opt/sharding-proxy/ext-lib。
    #可以自定义JVM相关参数到环境变量 JVM_OPTS 中(可选)
    ##
    docker run -p 13308:3308 --name sharding-proxy \
    -v ~/mydata/shardingsphere/sharding-proxy/conf:/opt/sharding-proxy/conf \
    -v ~/mydata/shardingsphere/sharding-proxy/ext-lib:/opt/sharding-proxy/ext-lib \
    -e PORT=3308 \
    -e JVM_OPTS="-Djava.awt.headless=true" \
    -d apache/sharding-proxy:latest
    
  2. 配置shareding-proxy

    /${your_work_dir}/conf/ 创建 server.yamlconfig-xxx.yaml 文件,进行服务器和分片规则配置。 配置规则,请参考配置手册。 配置模板,请参考配置模板

    vim ~/mydata/shardingsphere/sharding-proxy/conf/server.yaml

    #
    #开启注册中心
    #orchestration:
    #  name: orchestration_ds
    #  registryCenter:
    #    type: ZooKeeper
    #    serverLists: localhost:2181
    #    props:
    #      retryIntervalMilliseconds: 500
    #      timeToLiveSeconds: 60
    #      maxRetries: 3
    #      operationTimeoutMilliseconds: 500
    #  overwrite: false
    #
    
    ##数据源公共配置
    schemaName: sharding_db # 逻辑数据源名称
    dataSourceCommon:
      username: root # 数据库用户名
      password: 123456 # 数据库密码
      connectionTimeoutMilliseconds: 30000 # 连接超时毫秒数
      idleTimeoutMilliseconds: 60000 # 空闲连接回收超时毫秒数
      maxLifetimeMilliseconds: 1800000 # 连接最大存活时间毫秒数
      maxPoolSize: 50 # 最大连接数
      minPoolSize: 1  # 最小连接数
    
    #用于执行登录 Sharding Proxy 的权限验证。 配置用户名、密码、可访问的数据库后,必须使用正确的用户名、密码才可登录
    authentication:
      users:
        root: # 自定义用户名
          password: root # 自定义用户名
        sharding: # 自定义用户名
          password: sharding # 自定义用户名
          authorizedSchemas: sharding_db, masterslave_db # 该用户授权可访问的数据库,多个用逗号分隔。缺省将拥有 root 权限,可访问全部数据库。
    
    #一些属性配置
    props:
    #  max.connections.size.per.query: 1
    #  acceptor.size: 16  # The default value is available processors count * 2.
      executor.size: 16  # 线程数大小Infinite by default.
    #  proxy.frontend.flush.threshold: 128  # The default value is 128.
    #    # LOCAL: Proxy will run with LOCAL transaction.
    #    # XA: Proxy will run with XA transaction.
    #    # BASE: Proxy will run with B.A.S.E transaction.
    #  proxy.transaction.type: LOCAL
    #  proxy.opentracing.enabled: false
    #  proxy.hint.enabled: false
    #  query.with.cipher.column: true
    #是否在日志中打印 SQL。
    	sql.show: true
    #  allow.range.query.with.inline.sharding: false
    #  check.table.metadata.enabled: false
    

    vim ~/mydata/shardingsphere/sharding-proxy/conf/config-sharding.yaml 上面配置了每个库的公共数据源配置,如果你想覆盖 dataSourceCommon 属性,请在每个数据源单独配置。

    #具体数据源配置
    dataSources:
    	ds_0:
    	 	url: jdbc:mysql://192.168.0.100:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    #    username: # 数据库用户名,覆盖 dataSourceCommon 配置
    #    password: # 数据库密码,覆盖 dataSourceCommon 配置
    #    connectionTimeoutMilliseconds: # 连接超时毫秒数,覆盖 dataSourceCommon 配置
    #    idleTimeoutMilliseconds: # 空闲连接回收超时毫秒数,覆盖 dataSourceCommon 配置
    #    maxLifetimeMilliseconds: # 连接最大存活时间毫秒数,覆盖 dataSourceCommon 配置
    #    maxPoolSize: # 最大连接数,覆盖 dataSourceCommon 配置
      ds_1:
        url: jdbc:mysql://192.168.0.100:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
    
    #定义分片规则
    rules:
    - !SHARDING
      tables:
        t_order:
          actualDataNodes: ds_${0..1}.t_order_${0..1}
          tableStrategy:
            standard:
              shardingColumn: order_id
              shardingAlgorithmName: t_order_inline
          keyGenerateStrategy:
            column: order_id
            keyGeneratorName: snowflake
        t_order_item:
          actualDataNodes: ds_${0..1}.t_order_item_${0..1}
          tableStrategy:
            standard:
              shardingColumn: order_id
              shardingAlgorithmName: t_order_item_inline
          keyGenerateStrategy:
            column: order_item_id
            keyGeneratorName: snowflake
      bindingTables:
        - t_order,t_order_item
    	defaultDatabaseStrategy:
        standard:
          shardingColumn: user_id
          shardingAlgorithmName: database_inline
      defaultTableStrategy:
        none:
      
      shardingAlgorithms:
        database_inline:
          type: INLINE
          props:
            algorithm.expression: ds_${user_id % 2}
        t_order_inline:
          type: INLINE
          props:
            algorithm.expression: t_order_${order_id % 2}
        t_order_item_inline:
          type: INLINE
          props:
            algorithm.expression: t_order_item_${order_id % 2}
      
      keyGenerators:
          snowflake:
            type: SNOWFLAKE
            props:
                worker.id: 123
    

    vim ~/mydata/shardingsphere/sharding-proxy/conf/config-master_slave.yaml 配置master_slave(主从架构)

    schemaName: master_slave_db
    #
    #dataSourceCommon:
    #  username: root
    #  password:
    #  connectionTimeoutMilliseconds: 30000
    #  idleTimeoutMilliseconds: 60000
    #  maxLifetimeMilliseconds: 1800000
    #  maxPoolSize: 50
    #  minPoolSize: 1
    #  maintenanceIntervalMilliseconds: 30000
    #
    
    dataSources:
      master_ds:
        url: jdbc:mysql://127.0.0.1:3307/demo_ds_master?serverTimezone=UTC&useSSL=false
      slave_ds_0:
        url: jdbc:mysql://127.0.0.1:3308/demo_ds_slave_0?serverTimezone=UTC&useSSL=false
      slave_ds_1:
        url: jdbc:mysql://127.0.0.1:3308/demo_ds_slave_1?serverTimezone=UTC&useSSL=false
    
    rules:
    - !MASTER_SLAVE
      dataSources:
        ms_ds:
          name: ms_ds
          masterDataSourceName: master_ds
          slaveDataSourceNames:
            - slave_ds_0
            - slave_ds_1
    
  3. 引入数据库驱动程序

    • 如果后端连接 PostgreSQL 数据库,不需要引入额外依赖。

    • 如果后端连接 MySQL 数据库,需要下载 MySQL Connector/J, 解压缩后,将 mysql-connector-java-5.1.47.jar 拷贝到 ~/mydata/shardingsphere/sharding-proxy/ext-lib 目录。

  4. 重启sharding-proxy服务

    docker restart sharding-proxy
    

至此mysql 主从架构+数据分片配置就介绍到这里,最后如果不想折腾这些,其实目前很多云服务商也提供了很多云上解决方案;

如阿里云的云数据库RDS MySQL 版和 腾讯云的云数据库 TencentDB for MySQL也是不错的选择;

你可能感兴趣的:(运维工具,数据结构,Docker深入浅出,mysql,中间件,数据库,linux,docker)