
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
在对着本文进行实践操着之前,建议阅读蒋老湿之前的2篇文章
Docker的网络(三)
开源数据库中间件-MyCa初探与分片实践
mycat-dockerfile
############################################
# version : debugman007/c7-mycat:v1
# desc : centos7 上安装的mycat
############################################
# 设置继承自 centos7 官方镜像
FROM centos:7
RUN echo "root:root" | chpasswd
RUN yum -y install net-tools
# install java
ADD http://mirrors.linuxeye.com/jdk/jdk-7u80-linux-x64.tar.gz /usr/local/
RUN cd /usr/local && tar -zxvf jdk-7u80-linux-x64.tar.gz && rm -f jdk-7u80-linux-x64.tar.gz
ENV JAVA_HOME /usr/local/jdk1.7.0_80
ENV CLASSPATH ${JAVA_HOME}/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:${JAVA_HOME}/bin
#install mycat
ADD http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz /usr/local
RUN cd /usr/local && tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz && rm -f Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
VOLUME d://docker/mycat:/usr/local/mycat/conf
EXPOSE 8066 9066
CMD ["/usr/local/mycat/bin/mycat", "console"]
mysql 的docker 请点击此处查看:mysql5.7-dockerfile
- 首先把mysql的dockerfile文件打包镜像
docker build -t mycat -f mycat-dockerfile .,或者直接docker pull从dockerhub中拉取mysql 的镜像。通过如下命令启动2个mysql实例,分别叫one-mysql,two-mysqldocker run --name one-mysql -e MYSQL_ROOT_PASSWORD=123456 -d -p 3307:3306 mysql:5.7 docker run --name two-mysql -e MYSQL_ROOT_PASSWORD=123456 -d -p 3307:3306 mysql:5.7 docker run -d --name mycat mycat启动构建mycat容器,docker cp mycat:/usr/local/mycat/conf .使用命令复制 mycat容器中目录下/usr/local/mycat/的conf文件夹到当前宿主机,我的是E盘,其他的盘符也可以 ,.为当前路径,这么做的原因是待会要用这个文件做一个bind Mounting映射,因为如果我们直接修改mycat容器中的配置文件后重启,配置如果有错误的话,会导致容器一起启动不了,这个时候我们就很难再进入容器中修改mycat的配置文件了。 记得要开启如下的配置,否则做不了volume配置,具体参考Docker的持久化存储和数据共享(四)
- 接下来我们删除掉刚刚创建的mycat容器,重新再生成一个
docker rm -f mycat docker run -d -v e:/mycat/conf:/usr/local/mycat/conf -d 8066:8066 -d 9066:9066 --name mycat mycat docker ps 这个时候我们就不用每次使用
winpty docker exec -it mycat bash进入容器中去修改mycat 配置文件了,可以直接在e:/mycat/conf目录下修改保存,然后在命令行窗口执行docker restart mycat && docker attach mycat重启mycat,attach是为了在启动的时候打印日志到控制台,方便实时查看错误 - 使用navicat for mysql 连接我们刚刚创建的mycat,mysql




- mycat的schema.xml修改如下,其中writeHost的url该怎么写呢?因为我是在一台机器上部署了3个Docker实列,所以对应的连接应该是可以通过
docker network inspect bridge查看
具体配置说明可以参考Mycat之——配置文件schema.xml<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <!-- auto sharding by id (long) --> <table name="tb_test" dataNode="dn1,dn2,dn3,dn4,dn5,dn6" rule="auto-sharding-long-jp" /> <!-- 全局表自动克隆到所有已定义的数据节点,因此可以连接与分片节点位于同一数据节点中的任何表 --> <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3,dn4,dn5,dn6" rule="auto-sharding-long"/> <!-- 使用mod sharind规则的随机共享 --> </schema> <dataNode name="dn1" dataHost="localhost1" database="db1" /> <dataNode name="dn2" dataHost="localhost1" database="db2" /> <dataNode name="dn3" dataHost="localhost1" database="db3" /> <dataNode name="dn4" dataHost="localhost2" database="db1" /> <dataNode name="dn5" dataHost="localhost2" database="db2" /> <dataNode name="dn6" dataHost="localhost2" database="db3" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- 可以有多写主机 --> <writeHost host="hostM1" url="172.17.0.3:3306" user="root" password="123456"> <!-- 可以有多读主机 <readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" /> --> </writeHost> <!--<writeHost host="hostS1" url="localhost:3316" user="root" password="123456" /> --> </dataHost> <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="172.17.0.4:3306" user="root" password="123456"/> </dataHost> </mycat:schema> - 到这基本算完成了,现在我们来做一个示例吧!执行如下sql语句:
CREATE TABLE `company` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, `age` int(11) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into company (id,NAME,age) values (1,'jp',25); 可以看到one-mysql,two-mysql的所有db库里都有一个company表,而且每个库表里都有刚刚插入的内容, 但是这个效果看起来像是全量复制的感觉,没有很分片,这是因为schema.xml中
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3,dn4,dn5,dn6" rule="auto-sharding-long"/>设置了type="global",所以刚刚每个库表都有内容。取消global全局设置就可以了。下面再来一个演示示例。 - 自定义分片规则


执行如下sql:
发现结果不一样了,根据id的范围区间不同,数据所在的数据库实列也不同,所在的database也不同。CREATE TABLE tb_test ( id BIGINT(20) NOT NULL, title VARCHAR(100) NOT NULL , PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8 ; INSERT INTO tb_test(ID,TITLE) VALUES(1,'蒋老湿1'); INSERT INTO tb_test(ID,TITLE) VALUES(6000,'蒋老湿2'); INSERT INTO tb_test(ID,TITLE) VALUES(10001,'蒋老湿3'); INSERT INTO tb_test(ID,TITLE) VALUES(15001,'蒋老湿4'); INSERT INTO tb_test(ID,TITLE) VALUES(20001,'蒋老湿5'); INSERT INTO tb_test(ID,TITLE) VALUES(25001,'蒋老湿6'); INSERT INTO tb_test(ID,TITLE) VALUES(30001,'蒋老湿error'); 超出id最大值则会有如下错误!因为我们规则中定义的最大id范围为30K = 30000


好了~至于主从复制和读写分离,在了解本文之后,其实也不是什么很困难的事情了,在这里就不再演示说明了。
