使用Docker Compose搭建MySQL主从复制架构
环境准备
docker 安装MySQL数据库
docker pull mysql
运行MySQL容器
docker run –name mysql mysql -e MYSQL_ROOT_PASSWORD=123456
使用命令将MySQL配置文件my.cnf 复制出主机上
docker cp mysql:/var/lib/mysql/ D:/docker/mysql_cluster/my.cnf
拿到my.cnf
原配置文件,加以改造就可以实现数据库主从同步了
配置文件
创建文件夹
在主机创建mysql_cluster
文件夹
1 | mysql_cluster |
将从容器内复制出来my.cnf分别放入 master、slave 下
文件配置
设置 master my.cnf
1 | # 下面配置为主节点设置 |
配置 slave my.cnf
1 | server_id = 102 |
docker-compose.yml 配置
1 | version: '3.8' |
还用一点值得注意的,如果宿主机上的mysql 文件夹不是空的,配置中MySQL root 密码不生效的。有次我将一个正在运行中/var/lib/mysql copy到宿主机上,使用逻辑卷映射到容器中去,导致MySQL一直登录不上去。
设置主从同步
运行容器
docker-compose up -d
查看运行情况
docke ps -a
出现下面状态,表明两个节点都运行成功了
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
登录master节点
设置slave 连接master节点
mysql> grant replication client,replication slave on *.* to 'root'@'192.168.102.120'
保存设置
mysql> flush privileges
获取binlog 文件名和Position
mysql> show master status
1 | +------------------+----------+--------------+------------------+-------------------+ |
登录slave 节点
mysql> reset master;
mysql> CHANGE MASTER TO MASTER_HOST='mysql-master',MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=156
mysql> start slave
查看同步结果
1 | mysql> show slave status \G; |
看见 Slave_IO_Running: Yes Slave_SQL_Running: Yes这两个都是Yes 说明同步已经成功了。
验证同步
连接master 节点,创建一个数据库,在新数据库下再创建一个新表。再连接slave 节点可以看见再master 创建数据库下的新表,这样就表明数据已经实现同步了。
使用springboot 搭建读写分离
maven pox.xml
1 | <parent> |
主要原来就是利用org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
可以将不同连接设置到Map 根据key 获取获取dataSource
,重写determineCurrentLookupKey()
,实现对读取数据库时,切换到读库,写操作切换到写库。 下面会贴出全部代码
application.yml 配置
1 | server: |
多数据库druid 设置
1 | @Configuration |
创建枚举类用作数据库路由Key
1 | public enum ClusteEnum { |
重写路由数据库实现根据key 切换数据库
1 | public class DataSourceRouter extends AbstractRoutingDataSource { |
DataSourceContextHolder 提供线程安全方式返回不同连接切换key
1 | public class DataSourceContextHolder { |
设置了多数据源,需要手上生成SqlSessionFactory
,SqlSessionTemplate
bean,让Mybatis 生效。
1 | @Configuration |
自定义注解声明需要切换数据源
1 | @Retention(RetentionPolicy.RUNTIME) |
最后一步,设置AOP 环绕通知,动态修改数据库路由Key
1 | @Slf4j |
b编写一个简单service 验证成果
1 | @Component |
编写测试类
1 | @ExtendWith(SpringExtension.class) |
运行insert 插入 结果如下 成功切换到master 库
再运行 findOne 方法 使用默认连接slave ,能成功查询到结果
最后混合使用也是没问题的