《Mycat分布式数据库架构》之数据切分和读写分离

前文回顾:
《Mycat分布式数据库架构》之原理及架构
《Mycat分布式数据库架构》之搭建详解
《Mycat分布式数据库架构》之配置详解



1、 数据切分

这里的数据切分也是分布式数据库架构的核心,将数据分开存到多个节点中,简单来说,就是将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。

数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式:垂直切分和水平切分。
垂直切分: 按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切分可以称之为数据的垂直(纵向)切分;
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。

水平切分: 根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
水平切分是将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则复杂,后期的数据维护也会更为复杂一些。


由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,本文将使用水平拆分来做演示,两台服务器相关信息如下:

IP地址数据库端口号
192.168.157.128Oracle1521
192.168.157.129Oracle1521

1.1 配置server.xml

server.xml文件中定义登录Mycat的用户和权限,配置如下所示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
	<system>
		<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
		<property name="useHandshakeV10">1</property>
		<property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
		<property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
		<property name="sqlExecuteTimeout">300</property>  <!-- SQL 执行超时 单位:秒-->
		<property name="sequnceHandlerType">2</property>
		<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
		<property name="processorBufferPoolType">0</property>
		<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
		<property name="handleDistributedTransactions">0</property>
		<property name="useOffHeapForMerge">0</property>
        <property name="memoryPageSize">64k</property>
		<property name="spillsFileBufferSize">1k</property>
		<property name="useStreamOutput">0</property>
		<property name="systemReserveMemorySize">384m</property>
		<!--是否采用zookeeper协调切换  -->
		<property name="useZKSwitch">false</property>
		<!-- XA Recovery Log日志路径 -->
		<!--<property name="XARecoveryLogBaseDir">./</property>-->
		<!-- XA Recovery Log日志名称 -->
		<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
		<!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
		<property name="strictTxIsolation">false</property>
		<property name="useZKSwitch">true</property>
	</system>

	<user name="yxc" defaultAccount="true">
		<property name="password">yxc123456</property>
		<property name="schemas">mycats</property>
	</user>

	<user name="user">
		<property name="password">user</property>
		<property name="schemas">mycats</property>
		<property name="readOnly">true</property>
	</user>

</mycat:server>

1.2 配置schema.xml

配置schema.xml文件,指明逻辑库、表、分片规则、分片节点和数据源,具体配置如下:

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="mycats" checkSQLschema="false" sqlMaxLimit="100">
        <table name="tb_user" dataNode="dn1,dn2" rule="mod-long"/>
    </schema>
    <dataNode name="dn1" dataHost="host1" database="oracle11" />
    <dataNode name="dn2" dataHost="host2" database="orcl" />
    <dataHost name="host1" maxCon="100" minCon="10" balance="0" writeType="0" dbType="oracle" dbDriver="jdbc">
       <heartbeat>select 1 from dual</heartbeat><!--心跳检测命令-->
       <writeHost host="hostM1" url="jdbc:oracle:thin:@192.168.157.129:1521:oracle11" user="scott" password="chaoDev.2019" /><!--实际物理库的配置信息-->
    </dataHost>
    <dataHost name="host2" maxCon="100" minCon="10" balance="0" writeType="0" dbType="oracle" dbDriver="jdbc">
       <heartbeat>select 1 from dual</heartbeat><!--心跳检测命令-->
       <writeHost host="hostM2" url="jdbc:oracle:thin:@192.168.157.128:1521:oracle11" user="yxc" password="yxc" /><!--实际物理库的配置信息-->
    </dataHost>
</mycat:schema>

1.3 配置分片规则

rule.xml定义了表拆分所涉及到的规则定义,根据业务可以灵活的对表使用不同的分片算法(目前已实现十余种不同的分片规则,对应所在源码包为:io.mycat.route.function),或者对表使用相同的算法但具体的参数不同。这里添加如下配置,进行水平切分,数据按id取模均匀划分到两个数据库中。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="mod-long">
		<rule>
			<columns>id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>

	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">2</property>
	</function>

</mycat:rule>

下面我们从程序中调用mycat,并且插入一些数据,两台数据库中的数据如下:

在这里插入图片描述

在这里插入图片描述

可以看到数据已经按id取模的方式切分到了两个数据库中。


2、读写分离

这里首先需要强调的是,Mycat的读写分离依赖于数据库产品的主从数据同步。也就是说数据同步要从数据库角度入手,mycat只负责读写分离,不负责数据同步。数据的同步不同的数据库有不同的解决方案,比如MySQL的主从复制(我前面的文章有写)、Oracle的data guard、SQL Server的复制订阅等。

读写分离,简单来说就是把数据库的读和写操作分开,以对应不同的数据库服务器。Mycat控制后台数据库的读写分离和负载均衡由schema.xml文件datahost标签的balance属性控制,具体配置如下:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="mycats" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        </schema>  
 
        <dataNode name="dn1" dataHost="host1" database="oracle11" />  
        <dataHost name="host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="oracle" dbDriver="jdbc" switchType="1"  slaveThreshold="100">  
                <!--心跳sql-->
                <heartbeat>select 1 from dual</heartbeat>  
                <writeHost host="hostM1" url="jdbc:oracle:thin:@192.168.157.129:1521:oracle11" user="scott" password="chaoDev.2019">  
                        <readHost host="slave1" url="jdbc:oracle:thin:@192.168.157.128:1521:oracle11" user="yxc" password="yxc" />  
                </writeHost>  
        </dataHost>  
 
</mycat:schema>

这里我们指定了writeHost和readHost,并且指定balance为1,具体说明如下。

  • balance=“0”, 不开启读写分离机制,所有读操作都发送到当前的writeHost上执行。
  • balance=“1”,所有读操作都发送到当前的writeHost对应的readHost和备用的writeHost,这样就可以减轻主库的压力,高效的提供写操作,而由其他服务器承担比较耗费资源的读操作。
  • balance=“2”,所有读操作都发送到所有的writeHost、readHost上,即当前dataHost内的服务器都参与分担读操作。这个场景比较适合主库压力不是很大时,也可以分担读操作,更合理的利用资源。
  • balance=“3”,所有读操作只发送到当前writeHost对应的readHost上。

运行程序后,读和写操作将分离,如下所示,读取时只能读取到readHost对应的数据库信息。

在这里插入图片描述


后续继续更新Mycat数据切分实战以及应用层连接Mycat等,敬请关注。


更多技术干货,请持续关注程序员大佬超。
原创不易,转载请注明出处。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员大佬超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值