mycat
1、没有数据库中间件采用规则表存放规则,现根据规则切分数据,然后插入数据。
2、数据库中间件可以保存水平切分规则,可以直接切分和整合数据。
下载mycat
docker pull adoptopenjdk/openjdk8
docker tag adoptopenjdk/openjdk8 jdk8
docker rmi adoptopenjdk/openjdk8
创建容器
docker run -d -it --name mycat1 -v mycat:/root/server --privileged --net=host openjdk8
开放防火墙
firewall-cmd --zone=public --add-port=8066/tcp --permanent
firewall-cmd --zone=public --add-port=9066/tcp --permanent
firewall-cmd --reload
查看数据卷并且上传mycat压缩包
docker volume inspect mycat
上传mycat压缩包
tar -xvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
docker exec -it mycat1 bash
cd /root/server
部署两个mycat实现mycat负载均衡
主要配置文件如下,server.xml,schema.xml,rule.xml,mycat 虚拟的数据库,有逻辑表和数据库表
server.xml
配置端口号,账号信息,全局主键方式,主要修改user标签里面内容
<user name="root" defaultAccount="true"> <property name="password">123</property> <property name="schemas">neti</property> <property name="defaultSchema">neti</property> <!--No MyCAT Database selected 閿欒鍓嶄細灏濊瘯浣跨敤璇chema浣滀负schema锛屼笉璁剧疆鍒欎负null,鎶ラ敊 --> <!-- 琛ㄧ骇 DML 鏉冮檺璁剧疆 --> <!-- <privileges check="false"> <schema name="TESTDB" dml="0110" > <table name="tb01" dml="0000"></table> <table name="tb02" dml="1111"></table> </schema> </privileges> --> </user>
schema
设置读写分离,pxc不需要做读写分离只需要做负载均衡
主要配置datahost,balance=0代表不使用读写分离,writeType=1 读写节点自动发送写节点,slaveThreshold=100表示从节点落后主库100秒就会剔除这个从节点,不会再从从节点读取数据。
虚拟逻辑库要和server里面一致。一个datahost表示一个集群。balance=0不开启读写分离,balance=1除了m1以外m2,s1,s2参与select语句负载均衡。balance=2随机分发到各个节点,balance=3
只分配到对应的读节点
配置pxc集群
<schema name="neti" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<dataHost name="pxc1" maxCon="1000" minCon="10" balance="0" writeType="1" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="p1w1" url="localhost:3306" user="root" password="123"> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost> <dataHost name="pxc1" maxCon="1000" minCon="10" balance="0" writeType="1" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="p1w1" url="localhost:3306" user="root" password="123"> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost>
配置replication集群
<dataHost name="rep1" maxCon="1000" minCon="10" balance="3" writeType="1" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="r1w1" url="localhost:3306" user="root" password="123"> <readHost host="r1r1" url="localhost:3306" user="root" password="123"></readHost> </writeHost> <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </dataHost>
mycat配置虚拟库和虚拟表
配置真实逻辑库
<dataNode name="dn1" dataHost="pxc1" database="neti" /> <dataNode name="dn2" dataHost="pxc2" database="neti" /> <dataNode name="dn3" dataHost="rep1" database="neti" /> <dataNode name="dn4" dataHost="rep2" database="neti" />
配置虚拟逻辑库和虚拟表,sqlmaxlimit最多返回记录,table使用虚拟表,type是表类型,global表示全局表,不进行水平切分
<schema name="neti" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="teacher" dataNode="dn1,dn2,dn3" rule="mod-long"/>
<table name="student" dataNode="dn1,dn2,dn3" type="global"/>
</schema>
修改mod-long算法,修改为与分片数一致
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">3</property> </function>
启动mycat并且使用mycat
首先需要创建log目录
为mycat bin目录下的所有sh设置最高权限
chmod -R 777 ./*.sh
./startup_nowrap.sh
mycat水平切分算法
分片算法 | 适用场合 | 案例 |
主键求模 | 初始数据很多,增长慢 | 地图数据 |
枚举值 | 大多数场合 | 58同城,饿了么 |
日期分片 | 按日期查找的数据 | 日志数据 |
自然月分片 | 按日期查找数据 | 财务数据 |
冷数据分片 | 冷热数据分离 | 订单数据 |
全局表就是业务数据不多
就是每个分片上表数据都一样,select随机分发,insert,update,delete会分发给所有节点去执行
<table name="student" dataNode="dn1,dn2,dn3" type="global"/>
主键求模可以均匀切分数据,不能适合数据增长太快,数据增长太快容易导致需要做数据迁移,一旦增加分片代价惨重。
枚举值预先定义,主流切分规则,必须是整数类型。定义文件
10=0 22=0 24=1 441=1
<function name="partition_by_city" class="io.mycat.route.function.PartitionByFileMap"> <property name="mapFile">city.txt</property> </function>
<tableRule name="share_by_city"> <rule> <columns>id</columns> <algorithm>partion_by_city</algorithm> </rule> </tableRule>
mycat 热加载,连接mycat地址和9066mycat管理端口,选择命令界面。
reload @@config_all
跨表连接,如分片中表进行连接需要在局域网传输大量数据,所以mycat不支持跨表连接。只能采用父子表,字表数据会跟随父表数据存储在同一个分片上。父表可以有切分规则,子表无法有切分规则,
配置primarykey会缓存,不配不缓存
<table name="student" dataNode="dn1,dn2,dn3" primaryKey="ID" rule="partition_by_city"> <childTable name="payment" primaryKey="ID" joinKey="customer_id" parentKey="ID"> </table>
全局主键
mycat按计数器方式自增长生成主键,计数器保存数据库中,如果是pxc集群,频繁同步回压力大。如果是replication集群,同步不及时,不推荐。
mycat采用时间搓和机器id,生成一个主键,都是偶数,不能采用主键求模算法。
利用zookeeper时间搓生成主键,主键必须是bigint类型
docker pull zookeeper
docker run -d --name z1 -p 2181:2181 -p 3888:3888 -p 2888:2888 --net=swarm_mysql zookeeper
配置server.xml
<property name="sequnceHandlerType">3</property>
编辑myid.properties
loadZk=false zkURL=127.0.0.1:2181 clusterId=mycat-cluster-1 myid=mycat_fz_01 clusterSize=3 clusterNodes=mycat_fz_01,mycat_fz_02,mycat_fz_04
select next value for MYCATSEQ_GLOBAL;
INSERT INTO terminal_customer (id) values (next value for MYCATSEQ_GOLBAL )