使用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:将容器里的文件夹挂载到主机当前目录;
修改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
修改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
配置设置好后,重启mysql容器服务
docker restart mysql-master mysql-slaver-01
在master主库服务器上添加同步用户
首先我们为了方便调试,需进入容器数据库内部去设置远程访问权限(生产环境可以忽略此部分)
#进入容器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;
此时我们就可以远程连接容器内到数据库并进行同步账号添加
#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;
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为例介绍;
使用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
配置shareding-proxy
在 /${your_work_dir}/conf/
创建 server.yaml
和 config-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
引入数据库驱动程序
如果后端连接 PostgreSQL 数据库,不需要引入额外依赖。
如果后端连接 MySQL 数据库,需要下载 MySQL Connector/J, 解压缩后,将 mysql-connector-java-5.1.47.jar
拷贝到 ~/mydata/shardingsphere/sharding-proxy/ext-lib
目录。
重启sharding-proxy服务
docker restart sharding-proxy
至此mysql 主从架构+数据分片配置就介绍到这里,最后如果不想折腾这些,其实目前很多云服务商也提供了很多云上解决方案;
如阿里云的云数据库RDS MySQL 版和 腾讯云的云数据库 TencentDB for MySQL也是不错的选择;