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


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



    1、 数据切分

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

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

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


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

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

    1.1 配置server.xml

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

    
    DOCTYPE mycat:server SYSTEM "server.dtd">
    <mycat:server xmlns:mycat="http://io.mycat/">
    	<system>
    		<property name="nonePasswordLogin">0property> 
    		<property name="useHandshakeV10">1property>
    		<property name="useSqlStat">0property>  
    		<property name="useGlobleTableCheck">0property>  
    		<property name="sqlExecuteTimeout">300property>  
    		<property name="sequnceHandlerType">2property>
    		<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+property>
    		<property name="processorBufferPoolType">0property>
    		
    		<property name="handleDistributedTransactions">0property>
    		<property name="useOffHeapForMerge">0property>
            <property name="memoryPageSize">64kproperty>
    		<property name="spillsFileBufferSize">1kproperty>
    		<property name="useStreamOutput">0property>
    		<property name="systemReserveMemorySize">384mproperty>
    		
    		<property name="useZKSwitch">falseproperty>
    		
    		
    		
    		
    		
    		<property name="strictTxIsolation">falseproperty>
    		<property name="useZKSwitch">trueproperty>
    	system>
    
    	<user name="yxc" defaultAccount="true">
    		<property name="password">yxc123456property>
    		<property name="schemas">mycatsproperty>
    	user>
    
    	<user name="user">
    		<property name="password">userproperty>
    		<property name="schemas">mycatsproperty>
    		<property name="readOnly">trueproperty>
    	user>
    
    mycat:server>
    
    • 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
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    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 dualheartbeat>
           <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 dualheartbeat>
           <writeHost host="hostM2" url="jdbc:oracle:thin:@192.168.157.128:1521:oracle11" user="yxc" password="yxc" />
        dataHost>
    mycat:schema>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1.3 配置分片规则

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

    
    DOCTYPE mycat:rule SYSTEM "rule.dtd">
    <mycat:rule xmlns:mycat="http://io.mycat/">
    	<tableRule name="mod-long">
    		<rule>
    			<columns>idcolumns>
    			<algorithm>mod-longalgorithm>
    		rule>
    	tableRule>
    
    	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    		
    		<property name="count">2property>
    	function>
    
    mycat:rule>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    在这里插入图片描述

    在这里插入图片描述

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


    2、读写分离

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

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

    
    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">  
                    
                    <heartbeat>select 1 from dualheartbeat>  
                    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

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

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

    在这里插入图片描述


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


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

  • 相关阅读:
    最全面的创建线程的几种方式总结,让你的需求轻松选择最合适你的线程创建方式
    HTML+CSS+JS静态网页设计【二十四节气】期末课程大作业
    OpenSceneGraph3.5.1编译
    基于SpringBoot蜗牛兼职网的设计与实现【附PPT|万字文档(LW)和搭建文档】
    java日志框架之JCL和SLF4J
    RabbitMQ 简介
    Kafka原理剖析之「位点提交」
    医药行业投资公司都有哪些?医药企业项目投资分析实用工具
    WPS(WSC)中M1 到M8 图解
    OrbbecSDK_ros关于imu数据的发布
  • 原文地址:https://blog.csdn.net/xch_yang/article/details/126610044