跨库 join 全局表 系统中基本都会存在数据字典信息,如数据分类信息、项目的配置信息等。这些字典数据最大的特点就是数据量不大并且很少会被改变。同时绝大多数的业务场景都会涉及到字典表的操作。 因此为了避免频繁的跨库 join 操作,结合冗余数据思想,可以考虑把这些字典信息在每一个分库中都存在一份。
mycat 在进行 join 操作时,当业务表与全局表进行聚合会优先选择相同分片的全局表,从而避免跨库 join 操作。在进行数据插入时,会把数据同时插入到所有分片的全局表中。
修改schema.xml
1 <table name ="tb_global" dataNode ="dn142,dn145" primaryKey ="global_id" type ="global" />
ER 表 ER 表也是一种为了避免跨库 join 的手段,在业务开发时,经常会使用到主从表关系的查询,如商品表与商品详情表。
ER 表的出现就是为了让有关系的表数据存储于同一个分片中,从而避免跨库 join 的出现。
修改 schema.xml 1 2 3 <table name ="tb_goods" dataNode ="dn129,dn130" primaryKey ="goods_id" rule ="sharding-by-murmur-goods" > <childTable name ="tb_goods_detail" primaryKey ="goods_detail_id" joinKey ="goods_id" parentKey ="goods_id" > </childTable > </table >
再次添加 goods 数据的时候,有关系的表数据存储于同一个分片中 读写分离 一个数据库的容量毕竟是有限制的,如果数据量非常大,分表已经满足不了的话,就会进行分库操作。分库架构如下:
现在存在两个主库,并且各自都有从节点。 当插入数据时,根据 id 取模放入不同的库中。同时主从间在进行写时复制的同时,还要完成主从读写分离的配置。
修改 schema.xml。配置多 datenode 与 datahost。同时配置主从读写分离。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0"?> <!DOCTYPE mycat :schema SYSTEM "schema.dtd" > <mycat:schema xmlns:mycat ="http://io.mycat/" > <schema name ="userDB" checkSQLschema ="true" dataNode ="dn129" sqlMaxLimit ="500" > <table name ="t_user" dataNode ="dn129,dn130" primaryKey ="id" rule ="mod-long" /> </schema > <dataNode name ="dn129" dataHost ="dh129" database ="user" /> <dataNode name ="dn130" dataHost ="dh130" database ="user" /> <dataHost name ="dh129" balance ="1" maxCon ="100" minCon ="10" dbType ="mysql" dbDriver ="jdbc" writeType ="0" switchType ="1" slaveThreshold ="1000" > <heartbeat > select user()</heartbeat > <writeHost url ="jdbc:mysql://192.168.200.129:3306" host ="host1" user ="root" password ="123456" > <readHost host ="host2" url ="jdbc:mysql://192.168.200.130:3306" user ="root" password ="123456" > </readHost > </writeHost > </dataHost > <dataHost name ="dh130" balance ="1" maxCon ="100" minCon ="10" dbType ="mysql" dbDriver ="jdbc" writeType ="0" switchType ="1" slaveThreshold ="1000" > <heartbeat > select user()</heartbeat > <writeHost url ="jdbc:mysql://192.168.200.129:3306" host ="host1" user ="root" password ="123456" > <readHost host ="host2" url ="jdbc:mysql://192.168.200.130:3306" user ="root" password ="123456" > </readHost > </writeHost > </dataHost > </mycat:schema >
修改 rule.xml。配置取模时的模数 1 2 3 4 5 <function name ="mod-long" class ="io.mycat.route.function.PartitionByMod" > <property name ="count" > 2</property > </function >
读写分离验证 设置 log4j2.xml 的日志级别为 DEBUG
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <Configuration status ="DEBUG" > ........ <asyncRoot level ="DEBUG" includeLocation ="true" > ........ </asyncRoot > </Loggers > </Configuration >
基于 mysql 服务进行数据查看,观察控制台信息,可以看到对于 read 请求的数据源,分别使用的是配置文件的配置
主从切换 基于 Mycat 主从复制方案,当前存在一个主节点和一个从节点,主节点负责写操作,从节点负责读操作。当在一个 dataHost 中配置了两个或多个 writeHost,如果第一个 writeHost 宕机,则 Mycat 会在默认 3 次心跳检查失败后,自动切换到下一个可用的 writeHost 执行 DML 语句,并在conf/dnindex.properties 文件里记录当前所用的 writeHost 的 index。
在 Mycat 主从切换中,可以将从节点也配置为是一个写节点(相当于从节点同时负责读写)。当原有的 master 写节点宕机后,从节点会被提升为主节点,同时负责读写操作。当写节点恢复后,会被作为从节点使用,保持现有状态不变,跟随新的主节点。
简单点说就是:原来的主变成从,原来的从一直为主。
schema.xml 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?xml version="1.0"?> <!DOCTYPE mycat :schema SYSTEM "schema.dtd" > <mycat:schema xmlns:mycat ="http://io.mycat/" > <schema name ="userDB" checkSQLschema ="true" dataNode ="dn142" sqlMaxLimit ="500" > <table name ="tb_user" dataNode ="dn142" primaryKey ="user_id" /> </schema > <dataNode name ="dn142" dataHost ="dh142" database ="user" /> <dataHost name ="dh142" writeType ="0" balance ="1" switchType ="2" maxCon ="100" minCon ="10" dbType ="mysql" dbDriver ="jdbc" slaveThreshold ="1000" > <heartbeat > show slave status</heartbeat > <writeHost url ="jdbc:mysql://192.168.200.142:3309" host ="host1" user ="root" password ="123456" > <readHost host ="host2" url ="jdbc:mysql://192.168.200.145:3309" user ="root" password ="123456" > </readHost > </writeHost > <writeHost url ="jdbc:mysql://192.168.200.145:3309" host ="host2" user ="root" password ="123456" > </writeHost > </dataHost > </mycat:schema >
测试:
开启 host1 和 host2
结论: 新增数据,全部新增到了 host1 中
关闭 host1
结论: 新增数据,全部新增到了 host2 中
再次开启 host1
结论: 新增数据,依然新增到 host2 中