Mycat实现读写分离

Docker下使用MyCat实现MySQL读写分离

Mycat的架构其实很好理解,Mycat是代理,Mycat后面就是物理数据库。和Web服务器的Nginx类似。对于使用者来说,访问的都是Mycat,不会接触到后端的数据库。

环境

MySQL : 5.7.22

MyCat : 1.6.5

首先需要实现一个MySQL的主从结构

主从搭建具体可以参考上一篇文章。

准备

准备好jdk和mycat安装包

  • JDK:jdk-8u181-linux-x64.tar.gz
  • MyCat:Mycat-server-1.6.5-release-20180122220033-linux.tar

上传到服务器。

我建立了一个mycat_conf文件夹

把JDK和mycat的包放到里头。

使用

1
touch Dockerfile

建立Dockerfile

拉取基础镜像

mycat的镜像打算使用官方的centOS 7镜像作为基础镜像

1
docker pull centos:7

编写Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# CentOS 7 作为基础镜像
FROM centos:7
# 复制并解压缩jdk文件(tar)
ADD jdk-8u181-linux-x64.tar.gz /opt
# 复制并解压缩myCat文件(tar)
VOLUME /opt/mycat/conf
ADD Mycat-server-1.6.5-release-20180122220033-linux.tar /opt
# 设置环境变量
ENV JAVA_HOME /opt/jdk1.8.0_181
ENV PATH $PATH:$JAVA_HOME/bin:
# ENV JAVA_OPTS="-Xms512m -Xmx768m -Xss1024K -XX:PermSize=328m -XX:MaxPermSize=656m"
EXPOSE 8066 9066
# 启动MyCat
CMD ["/opt/mycat/bin/mycat", "console"]

其中ADD命令会在构建镜像过程中进行解压缩的操作

对比COPY命令,COPY命令只会进行单纯的复制。

创建镜像

1
docker build -t mycat_server:1.6.5 .

创建容器

1
docker run -it --name mycat_server -p 8066:8066 -p 9066:9066 mycat_server:1.6.5

mycat需要暴露两个端口,8066端口作为连接端口,9066端口作为控制端口

加上-it参数,可以查看中途的输出进行debug。

若是调试中创建了很多无用的但是缓存下来的镜像,可以使用:

1
docker image prune

来清除所有Tag 为 none 的镜像。

prune命令还能干很多事情。

配置MyCat

容器创建成功之后,会处于运行状态,但是如果进入/opt/mycat/log/目录中查看mycat.log日志文件的话,会报错。原因就是没有正确配置。

*注意:上面的/opt/mycat/这个目录是Dockerfile解压得到的,具体需要看Dockerfile的配置。

MyCat的配置文件目录是/opt/mycat/conf/

其中的 server.xml 中包含连接MyCat的用户配置和连接的逻辑库:

1
2
3
4
5
6
7
8
9
10
<user name="root">
<property name="password">root</property>
<property name="schemas">TESTDB</property>
</user>
<user name="user">
<property name="user">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>

接下来就是 schema.xml

这部分是重点,如果只是简单实现读写分离的话只需要配置很少一部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="2"
writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="mysql-master" url="10.0.0.5:3306" user="root"
password="root">
<!-- can have multi read hosts -->
<readHost host="mysql-slave" url="10.0.0.6:3306" user="root" password="root" />
</writeHost>
<writeHost host="mysql-slave" url="10.0.0.6:3306" user="root" password="root">
</writeHost>
</dataHost>

database对应的是物理数据库名

url 是物理数据库的IP和端口

userroot则是连接所用的用户名和对应的密码

其中blance参数对应的就是负载平衡设置

说明 备注
0 不开启读写分离 默认值
1 全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡
2 所有读操作都随机的在 writeHost、 readhost 上分发
3 所有读请求随机分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读 Mycat ≥ 1.4

writeType属性:

说明 备注
0 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties . 默认值
1 所有写操作都随机的发送到配置的 writeHost 1.5 以后废弃不推荐

switchType属性:

说明 备注
-1 不自动切换
1 自动切换 默认值
2 基于MySQL主从同步状态决定是否切换

完成配置后可以连接MyCat中间件对数据库进行读写了。

参考文章

Mycat 权威指南