基于Mycat的分库分表

6次阅读

共计 2873 个字符,预计需要花费 8 分钟才能阅读完成。

数据库分库分表有两个种方式

  • 垂直切分
    一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面。
    优点:

    - 拆分后业务清晰,拆分规则明确;- 系统之间整合或扩展容易;- 数据维护简单。
** 缺点:**
 - 部分业务表无法 join,只能通过接口方式解决,提高了系统复杂度;- 受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高;- 事务处理复杂。

由于垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈,所以就需要水平拆分来做解决。

  • 水平切分

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,如图:

    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190804210504414.png)
** 优点:**
 - 拆分规则抽象好,join 操作基本可以数据库做;- 不存在单库大数据,高并发的性能瓶颈;- 应用端改造较少;- 提高了系统的稳定性跟负载能力。** 缺点:**
 - 拆分规则难以抽象;- 分片事务一致性难以解决;- 数据多次扩展难度跟维护量极大;- 拆分规则难以抽象;- 分片事务一致性难以解决;

等等还有很多。具体的就参照 Mycat 的问题说明。还有 Mycat 支持的分片策略:
http://www.mycat.io/document/…

基于 Mycat 用枚举分片算法实现分库

创建三个数据库

修改配置文件,如果觉得手动输入比较慢,可以直接复制然后修改库名和连接信息就可以

schema.xml 配置

<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- testdb 是 mycat 的逻辑库名称,链接需要用的 -->
    <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
       <!--rule 对应 rule.xml name 的名称 -->
      <table name="t_user"  dataNode="dn1,dn2,dn3" rule="role2" /> 
    
    </schema>
        <!-- database 是 MySQL 数据库的库名 -->
    <dataNode name="dn1" dataHost="localhost1" database="t_user1" />
    <dataNode name="dn2" dataHost="localhost1" database="t_user2" />
    <dataNode name="dn3" dataHost="localhost1" database="t_user3" />

     <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- 可以配置多个主从 -->
        <writeHost host="hostM1" url="192.168.100.131:3306" user="root" password="root">
            <!-- 可以配置多个从库 -->
            <readHost host="hostS2" url="192.168.100.132:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>

rule.xml 配置

<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="role2">
             <rule>
             <!-- 根据传入的 name 字段来判断存入那个库 -->
                  <columns>name</columns>
                  <!-- 指定的规则 -->
                <algorithm>hash-int</algorithm>
                </rule>
    </tableRule> 
    <function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
    <!-- 指定的规则枚举文件 -->
        <property name="mapFile">partition-hash-int.txt</property>
        <!-- key 如果是数值就写 0,不是就写 1 -->
        <property name="type">1</property>
        <!-- 如果都不符合,默认存入 1 节点库中 -->
        <property name="defaultNode">1</property>
    </function>
</mycat:rule>

partition-hash-int.txt 配置   key 是 name 对应的值,value 指的是存在哪个库中
hefei=0
nanjing=1
bengbu=2

server.xml 配置
<mycat:server xmlns:mycat="http://io.mycat/">
   <!-- 读写都可用的用户 -->
    <user name="root" defaultAccount="true">
        <property name="password">root</property>
        <property name="schemas">testdb</property>
    </user>
    <!-- 只读用户 -->
    <user name="user">
        <property name="password">user</property>
        <property name="schemas">testdb</property>
        <property name="readOnly">true</property>
    </user>
</mycat:server>

这样配置完成,然后启动 Mycat。使用 Navicat 连接的时候还是会出现表找不到的原因

通过日志可以看到,每次查询表的时候都会携带逻辑库的名字。所以导致没有查询到。这个问题我还没有解决。只能通过写 sql 来查询和新增了。


新增四个地区名称

INSERT INTO t_user (name) VALUES ('shanghai');
INSERT INTO t_user (name) VALUES ('nanjing');
INSERT INTO t_user (name) VALUES ('hefei');
INSERT INTO t_user (name) VALUES ('bengbu');


这样就可以看出来效果了

还有很多分片策略都可以在 Mycat 官方指南上面看到。
http://www.mycat.io/document/…

正文完
 0