Linux MySQL分库分表之Mycat

介绍

背景

  • 表的个数达到了几百千万张表时,众多的业务模块都访问这个数据库,压力会比较大,考虑对其进行分库
  • 表的数据达到几千万级别,在做很多操作都比较吃力,考虑对其进行分库或分表

数据切分(sharding)方案

  数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式:

  • 垂直切分:按照业务模块进行切分,将不同模块的表切分到不同的数据库中
  • 水平切分,将一张大表按照一定的切分规则,按照行切分成不同的表或者切分到不同的库中

如何理解垂直切分?

  垂直分库:主要解决的问题是单个数据库中[数据表]过多问题

  垂直分表:主要解决的问题是单个中[过多问题(将一张大表,拆分不同的关联表)。

如何理解水平切分?

  水平切分主要解决的问题就是对于[单表数据量过大]的问题(1000W以上数据性能会有所下降)

切分原则

  1. 能不切尽量不要切分
  2. 如果要切分一定要选择合适的切分规则,提前规划好
  3. 数据切分尽量通过冗余或表分组(Table Group)来降低跨库Join的可能
  4. 由于数据库中间件对数据Join实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表Join

分库分表之后带来问题?

  1. 跨库Join:订单表需要关联会员信息(订单表和会员表拆分为两个库的表)
    1. 应用层由一个查询拆分为多个
    2. 全局表,每个库都存储相同的数据,比如字典表、地址表
    3. 字段冗余
    4. Mycat技术可以实现跨库Join,只能实现2张表跨库Join
  2. 分布式事务(Mycat没有很好实现分布式事务)
    1. 强一致性(互联网项目不推荐,性能不好)
    2. 最终一致性(异步方式去实现,需要通过日志信息)
  3. 主键问题(保证ID的连续性和唯一性)
    1. UUID(性能不好)
    2. redis incr命令
    3. zookeeper
    4. 雪花算法
  4. 跨库进行排序问题
    1. 在应用层进行排序

Mycat应用

官网链接

点我直达

Mycat核心概念

  • Schema:由它制定逻辑数据库(相当于MySQL的database数据库)
  • Table:逻辑表(相当于MySQL的table表)
  • DataNode:真正存储数据的物理节点
  • DataHost:存储节点所在的数据库主机(指定MySQL数据库的连接信息)
  • User:MyCat的用户(类似于MySQL的用户,支持多用户)

MyCat主要解决的问题

  • 海量数据存储
  • 查询优化

Mycat对数据库的支持

Linux MySQL分库分表之Mycat_第1张图片

Mycat安装

安装要求

  • jdk:要求jdk必须是1.7及以上版本 (我使用的是jdk 1.8

  • Mysql:推荐mysql是5.5以上版本(我使用的是mysql 5.7

安装jdk

具体教程:点我直达

Linux MySQL分库分表之Mycat_第2张图片

Mcat下载

下载链接:点我直达

百度云盘地址:https://pan.baidu.com/s/14A3BAwnBRGZppc3AicF5Hw  密码: gkrp

Linux MySQL分库分表之Mycat_第3张图片

解压

Linux MySQL分库分表之Mycat_第4张图片

Linux MySQL分库分表之Mycat_第5张图片

修改配置文件

路径:/cyb/soft/mycat/conf

server.xml

用途:用于配置用户信息

Linux MySQL分库分表之Mycat_第6张图片

xml version="1.0" encoding="UTF-8"?>

DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <system>
    <property name="useSqlStat">0property>  
    <property name="useGlobleTableCheck">0property>  

        <property name="sequnceHandlerType">2property>
       
         
    
    
        
        <property name="processorBufferPoolType">0property>
        
        
        
        
        
        
        
        
        <property name="handleDistributedTransactions">0property>
        
            
        <property name="useOffHeapForMerge">1property>

        
        <property name="memoryPageSize">1mproperty>

        
        <property name="spillsFileBufferSize">1kproperty>

        <property name="useStreamOutput">0property>

        
        <property name="systemReserveMemorySize">384mproperty>


        
        <property name="useZKSwitch">trueproperty>


    system>
    
    
    
    
    <user name="root">
        <property name="password">rootproperty>
        <property name="schemas">TESTDBproperty>
        
        
        
    user>

    <user name="user">
        <property name="password">userproperty>
        <property name="schemas">TESTDBproperty>
        <property name="readOnly">trueproperty>
    user>

mycat:server>

schema.xml

用途:管理逻辑表

为了演示方便,删掉一些不必要的标签,标签详细用法:点我直达

Linux MySQL分库分表之Mycat_第7张图片

xml version="1.0"?>
DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
        
        <table name="cyb_test" dataNode="dn1,dn2,dn3" rule="mod-long" />
    schema>
    <dataNode name="dn1" dataHost="localhost1" database="db1" />
    <dataNode name="dn2" dataHost="localhost1" database="db2" />
    <dataNode name="dn3" dataHost="localhost1" database="db3" />
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()heartbeat>
        
        <writeHost host="hostM1" url="192.168.31.200:3306" user="root"
                   password="root">
            
            <readHost host="hostS2" url="192.168.31.201:3306" user="root" password="root" />
        writeHost>
    dataHost>
mycat:schema>

rule.xml

用途:定义了我们对表进行拆分所涉及到的规则定义,视情况修改参数

xml version="1.0" encoding="UTF-8"?>

DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="rule1">
        <rule>
            <columns>idcolumns>
            <algorithm>func1algorithm>
        rule>
    tableRule>

    <tableRule name="rule2">
        <rule>
            <columns>user_idcolumns>
            <algorithm>func1algorithm>
        rule>
    tableRule>

    <tableRule name="sharding-by-intfile">
        <rule>
            <columns>sharding_idcolumns>
            <algorithm>hash-intalgorithm>
        rule>
    tableRule>
    <tableRule name="auto-sharding-long">
        <rule>
            <columns>idcolumns>
            <algorithm>rang-longalgorithm>
        rule>
    tableRule>
    <tableRule name="mod-long">
        <rule>
            <columns>idcolumns>
            <algorithm>mod-longalgorithm>
        rule>
    tableRule>
    <tableRule name="sharding-by-murmur">
        <rule>
            <columns>idcolumns>
            <algorithm>murmuralgorithm>
        rule>
    tableRule>
    <tableRule name="crc32slot">
        <rule>
            <columns>idcolumns>
            <algorithm>crc32slotalgorithm>
        rule>
    tableRule>
    <tableRule name="sharding-by-month">
        <rule>
            <columns>create_timecolumns>
            <algorithm>partbymonthalgorithm>
        rule>
    tableRule>
    <tableRule name="latest-month-calldate">
        <rule>
            <columns>calldatecolumns>
            <algorithm>latestMonthalgorithm>
        rule>
    tableRule>
    
    <tableRule name="auto-sharding-rang-mod">
        <rule>
            <columns>idcolumns>
            <algorithm>rang-modalgorithm>
        rule>
    tableRule>
    
    <tableRule name="jch">
        <rule>
            <columns>idcolumns>
            <algorithm>jump-consistent-hashalgorithm>
        rule>
    tableRule>

    <function name="murmur"
        class="io.mycat.route.function.PartitionByMurmurHash">
        <property name="seed">0property>
        <property name="count">2property>
        <property name="virtualBucketTimes">160property>
        
        
    function>

    <function name="crc32slot"
              class="io.mycat.route.function.PartitionByCRC32PreSlot">
        <property name="count">2property>
    function>
    <function name="hash-int"
        class="io.mycat.route.function.PartitionByFileMap">
        <property name="mapFile">partition-hash-int.txtproperty>
    function>
    <function name="rang-long"
        class="io.mycat.route.function.AutoPartitionByLong">
        <property name="mapFile">autopartition-long.txtproperty>
    function>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        
        <property name="count">3property>
    function>

    <function name="func1" class="io.mycat.route.function.PartitionByLong">
        <property name="partitionCount">8property>
        <property name="partitionLength">128property>
    function>
    <function name="latestMonth"
        class="io.mycat.route.function.LatestMonthPartion">
        <property name="splitOneDay">24property>
    function>
    <function name="partbymonth"
        class="io.mycat.route.function.PartitionByMonth">
        <property name="dateFormat">yyyy-MM-ddproperty>
        <property name="sBeginDate">2015-01-01property>
    function>
    
    <function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
            <property name="mapFile">partition-range-mod.txtproperty>
    function>
    
    <function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
        <property name="totalBuckets">3property>
    function>
mycat:rule>

启动mycat

进入mycat/bin,启动mycat

启动命令:./mycat start
停止命令:./mycat stop
重启命令:./mycat restart
查看状态命令:./mycat status

注意,可以使用mysql的客户端直接连接mycat服务,默认端口为8066

错误日志(重要)

  部署过程中,我碰到点小问题,找不到主机名,具体解决方案,请看我另一篇:点我直达 ,如果Mycat服务起不来,记得看错误日志哟!

测试

ip:192.168.31.200(mysql主服务器)

ip:192.168.31.201(mysql从服务器)

ip:192.168.31.209(mycat服务器)

  注:演示过程中,因为mysql搭建了集群,主从复制,可能网络原因,有些延迟,或者mysql主从复制同步机制问题,导致刷新好几次,才显示出来,因为图片较大,被分割几张gif,内容都是连续的,验证结果,达到预期,演示成功!

  MySQL集群搭建主从复制:点我直达

你可能感兴趣的:(Linux MySQL分库分表之Mycat)