mycat_wrapper-linux-aarch64-64-程序员宅基地

技术标签: java  服务器  数据库  

1.分库分表

  • 垂直分库:以表为依据,根据业务将不同的表拆分至不同库中。

    • 特点:

      1.每个库的表结构不一样

      2.每个库的数据也不一样

      3.所有库的并集是全量数据

  • 垂直分表:以字段为依据,根据字段属于将不同字段拆分到不同表中

    • 特点:

      1.每个表的结构不一样

      2.每个表的数据也不一样,一般通过一列(主键/外键)关联

      3.所有表的并集是全量数据

  • 水平分库:以字段为依据,按照一定策略,将一个库的数据拆分到多个库中

    • 特点:

      1.每个库的表结构一样

      2.每个库的数据都不一样

      3.所有库的并集是全量数据

  • 水平分表:以字段为依据,按照一定策略,将一个表的数据拆分到多个表中

    • 特点:

      1.每个表的结构都一样

      2.每个表的数据都不一样

      3.所有表的并集是全量数据

2.核心概念

1.逻辑库、逻辑表

  • 逻辑库

    image-20220706232023378

  • 逻辑表:分布式数据库中,对于应用来说,读取数据的表就说逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

    • 分片表:指那些数据量很大的表,需要切分到多个数据库的表,这样每个分片都会有一部分数据,所以分片构成了完整的数据
    • 非分片表:数据库中不是很大的表可以不用切分,非分片表是相对分片表来说的,就是那些不需要进行数据切分的表
    • ER表:子表的记录与其关联的父表的记录存放在同一个数据分片中,通过表分组保证数据关联查询不会跨库操作
    • 全局表:存储一些基础的数据,数量不大但在各个业务表中可能都存在关联,当业务表数据量大而分片后,业务表与附属的数据字典表之间的关联查询就变成了比较棘手的问题,在mycat中可以通过数据冗余来解决这类表的关联问题,即所有分片都复制这一份数据,因此可以把这些冗余数据的表定义为全局表。

2.分片测试

  • 准备

    • 三台服务器并且安装mysql

      # 安装mysql
      docker run -p 3308:3306 \
      -e MYSQL_ROOT_PASSWORD=root \
      -v /mydata/mysql8/data:/var/lib/mysql-files:rw \
      -v /mydata/mysql8/log:/var/log/mysql:rw \
      -v /mydata/mysql8/config/my.cnf:/etc/my.cnf:rw \
      --name mysql8 --restart=always -d mysql:8.0
      
      # 安装mycat 解压jar包
      # 修改mycat/lib/下 mysql-connector-java-8.0.22.jar (1.6.7mycat默认5.7)
      
      # 启动mycat报错
      Unable to locate any of the following operational binaries:
        /etc/develop/mycat/bin/./wrapper-linux-aarch64-64
        /etc/develop/mycat/bin/./wrapper-linux-aarch64-32
        /etc/develop/mycat/bin/./wrapper
        
      # 解决
      wget https://download.tanukisoftware.com/wrapper/3.5.40/wrapper-linux-armhf-64-3.5.40.tar.gz
      tar zxvf wrapper-linux-armhf-64-3.5.40.tar.gz
       将 bin/wrapper 拷贝至 mycat/bin 目录下
       将 lib/libwrapper.so 拷贝至 mycat/lib 目录下
      
    • 配置mycat的schema.xml

      image-20220708165909354

      <?xml version="1.0"?>
      <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
      <mycat:schema xmlns:mycat="http://io.mycat/">
      
              <schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
                      <table name="test1" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
              </schema>
              <dataNode name="dn1" dataHost="localhost1" database="db1" />
              <dataNode name="dn2" dataHost="localhost2" database="db2" />
              <dataNode name="dn3" dataHost="localhost3" database="db3" />
              <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                                writeType="0" dbType="mysql" dbDriver="jdbc	" switchType="1"  slaveThreshold="100">
                      <heartbeat>select user()</heartbeat>
                      <writeHost host="hostM1" url="jdbc:mysql://10.211.55.3:3307?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                         password="root">
                      </writeHost>
              </dataHost>
      
      
              <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
                                writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                      <heartbeat>select user()</heartbeat>
                      <writeHost host="hostM1" url="jdbc:mysql://10.211.55.4:3308?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                         password="root">
                      </writeHost>
              </dataHost>
      
      
      
              <dataHost name="localhost3" maxCon="1000" minCon="10" balance="0"
                                writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                      <heartbeat>select user()</heartbeat>
                      <writeHost host="hostM1" url="jdbc:mysql://10.211.55.5:3309?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                         password="root">
                      </writeHost>
              </dataHost>
      
      
      </mycat:schema>
      
    • 配置mycat的server.xml

      <property name="charset">utf8</property>
      
              <user name="root" defaultAccount="true">
                      <property name="password">root</property> 
                      <property name="schemas">mycat</property> //设置为逻辑库名
      
                      <!-- 表级 DML 权限设置 -->
                      <!--
                      <privileges check="false">
                              <schema name="TESTDB" dml="0110" >
                                      <table name="tb01" dml="0000"></table>
                                      <table name="tb02" dml="1111"></table>
                              </schema>
                      </privileges>
                       -->
              </user>
      
              <user name="user">
                      <property name="password">user</property>
                      <property name="schemas">mycat</property>
                      <property name="readOnly">true</property>
              </user>
      
    • 启动mycat bin/mycat start

      查看logs下wrapper.log

      MyCAT Server startup successfully. see logs in logs/mycat.log  // 启动成功
      
    • 连接mycat root root 端口8066

    • 插入数据

      INSERT INTO test1(id,title) VALUES(1,'a');
      INSERT INTO test1(id,title) VALUES(2,'a');
      

      image-20220710125051162

3.分片

1.垂直拆分

  • 将一个库的表拆分到多个库中,每个库的表结构不同,数据不同
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
                <table name="tb_areas_city" dataNode="dn1" primaryKey="id" /> 
                <table name="tb_areas_provinces" dataNode="dn1" primaryKey="id" />
                <table name="tb_areas_region" dataNode="dn1" primaryKey="id" />
                <table name="tb_user" dataNode="dn1" primaryKey="id" />
                <table name="tb_user_address" dataNode="dn1" primaryKey="id" />

                <table name="tb_goods_base" dataNode="dn2" primaryKey="id" />
                <table name="tb_goods_desc" dataNode="dn2" primaryKey="goods_id" />
                <table name="tb_goods_item_cat" dataNode="dn2" primaryKey="id" />

                <table name="tb_order_item" dataNode="dn3" primaryKey="id" />
                <table name="tb_order_master" dataNode="dn3" primaryKey="order_id" />
                <table name="tb_order_pay_log" dataNode="dn3" primaryKey="out_trade_no" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="user_db" />
        <dataNode name="dn2" dataHost="localhost2" database="goods_db" />
        <dataNode name="dn3" dataHost="localhost3" database="order_db" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="jdbc:mysql://10.211.55.3:3307?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                   password="root">
                </writeHost>
        </dataHost>


        <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="jdbc:mysql://10.211.55.4:3308?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                   password="root">
                </writeHost>
        </dataHost>



        <dataHost name="localhost3" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM1" url="jdbc:mysql://10.211.55.5:3309?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                   password="root">
                </writeHost>
        </dataHost>


</mycat:schema>
SELECT order_id , payment ,receiver, province , city , area FROM tb_order_master o , tb_areas_provinces p , tb_areas_city c , tb_areas_region r
WHERE o.receiver_province = p.provinceid AND o.receiver_city = c.cityid AND o.receiver_region = r.areaid ;

# MyCat会报错, 原因是因为当前SQL语句涉及到跨域的join操作
  • 全局表

    <table name="tb_areas_city" dataNode="dn1,dn2,dn3" primaryKey="id" type="global"/>
    <table name="tb_areas_provinces" dataNode="dn1,dn2,dn3" primaryKey="id"  type="global"/>
    <table name="tb_areas_region" dataNode="dn1,dn2,dn3" primaryKey="id"  type="global"/>
    

2.水平拆分

  • 将库的表拆分到不同的库中,每个数据库的表结构不一样,数据不一样

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
              #  rule="mod-long":取余
              <table name="tb_log" dataNode="dn1,dn2,dn3" primaryKey="id"  rule="mod-long" />  
            </schema>
            <dataNode name="dn1" dataHost="localhost1" database="log_db" />
            <dataNode name="dn2" dataHost="localhost2" database="log_db" />
            <dataNode name="dn3" dataHost="localhost3" database="log_db" />
            <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <writeHost host="hostM1" url="jdbc:mysql://10.211.55.3:3307?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                       password="root">
                    </writeHost>
            </dataHost>
    
    
            <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <writeHost host="hostM1" url="jdbc:mysql://10.211.55.4:3308?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                       password="root">
                    </writeHost>
            </dataHost>
    
    
    
            <dataHost name="localhost3" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <writeHost host="hostM1" url="jdbc:mysql://10.211.55.5:3309?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root"
                                       password="root">
                    </writeHost>
            </dataHost>
    
    
    </mycat:schema>
    

3.分片规则

1.取模分片

<tableRule name="mod-long">
    <rule>
        <columns>id</columns>
        <algorithm>mod-long</algorithm>
    </rule>
</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <property name="count">3</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
count 数据节点的数量

2.范围分片

<tableRule name="auto-sharding-long">
	<rule>
		<columns>id</columns>
		<algorithm>rang-long</algorithm>
	</rule>
</tableRule>

<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong">
	<property name="mapFile">autopartition-long.txt</property>
  <property name="defaultNode">0</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
mapFile 对应的外部配置文件
type 默认值为0 ; 0 表示Integer , 1 表示String
defaultNode 默认节点的所用:枚举分片时,如果碰到不识别的枚举值, 就让它路由到默认节点 ; 如果没有默认值,碰到不识别的则报错 。

3.枚举分片

<tableRule name="sharding-by-intfile">
    <rule>
        <columns>status</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>
    <property name="type">0</property>
    <property name="defaultNode">0</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
mapFile 对应的外部配置文件
type 默认值为0 ; 0 表示Integer , 1 表示String
defaultNode 默认节点 ; 小于0 标识不设置默认节点 , 大于等于0代表设置默认节点 ;
默认节点的所用:枚举分片时,如果碰到不识别的枚举值, 就让它路由到默认节点 ; 如果没有默认值,碰到不识别的则报错 。

修改partition-hash-int.txt

1=0
2=1
3=2

4.范围求模算法

该算法为先进行范围分片, 计算出分片组 , 再进行组内求模。

优点: 综合了范围分片和求模分片的优点。 分片组内使用求模可以保证组内的数据分布比较均匀, 分片组之间采用范围分片可以兼顾范围分片的特点。

缺点: 在数据范围时固定值(非递增值)时,存在不方便扩展的情况,例如将 dataNode Group size 从 2 扩展为 4 时,需要进行数据迁移才能完成 。

<tableRule name="auto-sharding-rang-mod">
	<rule>
		<columns>id</columns>
		<algorithm>rang-mod</algorithm>
	</rule>
</tableRule>

<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
	<property name="mapFile">autopartition-range-mod.txt</property>
    <property name="defaultNode">0</property>
</function>
#autopartition-range-mod.txt
#range  start-end , data node group size
0-500M=1
500M1-2000M=2  #2=分片数量
columns 标识将要分片的表字段名
属性 描述
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
mapFile 对应的外部配置文件
defaultNode 默认节点 ; 未包含以上规则的数据存储在defaultNode节点中, 节点从0开始

5.固定分片hash算法

该算法类似于十进制的求模运算,但是为二进制的操作,例如,取 id 的二进制低 10 位 与 1111111111 进行位 & 运算

image-20220711113805929

优点: 这种策略比较灵活,可以均匀分配也可以非均匀分配,各节点的分配比例和容量大小由partitionCount和partitionLength两个参数决定

缺点:和取模分片类似

<tableRule name="sharding-by-long-hash">
    <rule>
        <columns>id</columns>
        <algorithm>func1</algorithm>
    </rule>
</tableRule>

<function name="func1" class="org.opencloudb.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property>
    <property name="partitionLength">256,512</property>
</function>
属性 描述
columns 标识将要分片的表字段名
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
partitionCount 分片个数列表
partitionLength 分片范围列表

约束 :

1). 分片长度 : 默认最大2^10 , 为 1024 ;

2). count, length的数组长度必须是一致的 ;

3). 两组数据的对应情况: (partitionCount[0]partitionLength[0])=(partitionCount[1]partitionLength[1])

以上分为三个分区:0-255,256-511,512-1023

6.取模范围算法

该算法先进行取模,然后根据取模值所属范围进行分片。

优点:可以自主决定取模后数据的节点分布

缺点:dataNode 划分节点是事先建好的,需要扩展时比较麻烦。

<tableRule name="sharding-by-pattern">
	<rule>
		<columns>id</columns>
		<algorithm>sharding-by-pattern</algorithm>
	</rule>
</tableRule>

<function name="sharding-by-pattern" class="io.mycat.route.function.PartitionByPattern">
	<property name="mapFile">partition-pattern.txt</property>
    <property name="defaultNode">0</property>
    <property name="patternValue">96</property>
</function>

partition-pattern.txt 配置如下:

0-32=0
33-64=1
65-96=2

在mapFile配置文件中, 1-32即代表id%96后的分布情况。如果在1-32, 则在分片0上 ; 如果在33-64, 则在分片1上 ; 如果在65-96, 则在分片2上。

属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
mapFile 对应的外部配置文件
defaultNode 默认节点 ; 如果id不是数字, 无法求模, 将分配在defaultNode上
patternValue 求模基数

7.字符串hash求模范围算法

与取模范围算法类似, 该算法支持数值、符号、字母取模,首先截取长度为 prefixLength 的子串,在对子串中每一个字符的 ASCII 码求和,然后对求和值进行取模运算(sum%patternValue),就可以计算出子串的分片数。

优点:可以自主决定取模后数据的节点分布

缺点:dataNode 划分节点是事先建好的,需要扩展时比较麻烦。

<tableRule name="sharding-by-prefixpattern">
	<rule>
		<columns>id</columns>
		<algorithm>sharding-by-prefixpattern</algorithm>
	</rule>
</tableRule>

<function name="sharding-by-prefixpattern" class="io.mycat.route.function.PartitionByPrefixPattern">
	<property name="mapFile">partition-prefixpattern.txt</property>
    <property name="prefixLength">5</property>
    <property name="patternValue">96</property>
</function>

partition-prefixpattern.txt 配置如下:

# range start-end ,data node index
# ASCII
# 48-57=0-9
# 64、65-90=@、A-Z
# 97-122=a-z
###### first host configuration
0-32=0
33-64=1
65-96=2
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
mapFile 对应的外部配置文件
prefixLength 截取的位数; 将该字段获取前prefixLength位所有ASCII码的和, 进行求模sum%patternValue ,获取的值,在通配范围内的即分片数 ;
patternValue 求模基数

8.应用指定算法

由运行阶段由应用自主决定路由到那个分片 , 直接根据字符子串(必须是数字)计算分片号 , 配置如下 :

<tableRule name="sharding-by-substring">
	<rule>
		<columns>id</columns>
		<algorithm>sharding-by-substring</algorithm>
	</rule>
</tableRule>

<function name="sharding-by-substring" class="io.mycat.route.function.PartitionDirectBySubString">
	<property name="startIndex">0</property> <!-- zero-based -->
	<property name="size">2</property>
	<property name="partitionCount">3</property>
	<property name="defaultPartition">0</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
startIndex 字符子串起始索引
size 字符长度
partitionCount 分区(分片)数量
defaultPartition 默认分片(在分片数量定义时, 字符标示的分片编号不在分片数量内时,使用默认分片)

示例说明 :

id=05-100000002 , 在此配置中代表根据id中从 startIndex=0,开始,截取siz=2位数字即05,05就是获取的分区,如果没传默认分配到defaultPartition

9.字符串hash解析算法

截取字符串中的指定位置的子字符串, 进行hash算法, 算出分片 , 配置如下:

<tableRule name="sharding-by-stringhash">
	<rule>
		<columns>user_id</columns>
		<algorithm>sharding-by-stringhash</algorithm>
	</rule>
</tableRule>

<function name="sharding-by-stringhash" class="io.mycat.route.function.PartitionByString">
	<property name="partitionLength">512</property> <!-- zero-based -->
	<property name="partitionCount">2</property>
	<property name="hashSlice">0:2</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
partitionLength hash求模基数 ; length*count=1024 (出于性能考虑)
partitionCount 分区数
hashSlice hash运算位 , 根据子字符串的hash运算 ; 0 代表 str.length() , -1 代表 str.length()-1 , 大于0只代表数字自身 ; 可以理解为substring(start,end),start为0则只表示0

10.一致性hash算法

一致性Hash算法有效的解决了分布式数据的拓容问题 , 配置如下:

<tableRule name="sharding-by-murmur">
    <rule>
        <columns>id</columns>
        <algorithm>murmur</algorithm>
    </rule>
</tableRule>

<function name="murmur" class="io.mycat.route.function.PartitionByMurmurHash">
    <property name="seed">0</property>
    <property name="count">3</property><!--  -->
    <property name="virtualBucketTimes">160</property>
    <!-- <property name="weightMapFile">weightMapFile</property> -->
    <!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property> -->
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
seed 创建murmur_hash对象的种子,默认0
count 要分片的数据库节点数量,必须指定,否则没法分片
virtualBucketTimes 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍;virtualBucketTimes*count就是虚拟结点数量 ;
weightMapFile 节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替
bucketMapPath 用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmur hash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西

11.日期分片算法

按照日期来分片

<tableRule name="sharding-by-date">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-date</algorithm>
    </rule>
</tableRule>

<function name="sharding-by-date" class="io.mycat.route.function.PartitionByDate">
	<property name="dateFormat">yyyy-MM-dd</property>
	<property name="sBeginDate">2020-01-01</property>
	<property name="sEndDate">2020-12-31</property>
    <property name="sPartionDay">10</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
dateFormat 日期格式
sBeginDate 开始日期
sEndDate 结束日期,如果配置了结束日期,则代码数据到达了这个日期的分片后,会重复从开始分片插入
sPartionDay 分区天数,默认值 10 ,从开始日期算起,每个10天一个分区

注意:配置规则的表的 dataNode 的分片,必须和分片规则数量一致,例如 2020-01-01 到 2020-12-31 ,每10天一个分片,一共需要37个分片

12.单月小时算法

单月内按照小时拆分, 最小粒度是小时 , 一天最多可以有24个分片, 最小1个分片, 下个月从头开始循环, 每个月末需要手动清理数据。

<tableRule name="sharding-by-hour">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-hour</algorithm>
    </rule>
</tableRule>

<function name="sharding-by-hour" class="io.mycat.route.function.LatestMonthPartion">
	<property name="splitOneDay">24</property>
</function>
属性 描述
columns 标识将要分片的表字段 ; 字符串类型(yyyymmddHH), 需要符合JAVA标准
algorithm 指定分片函数与function的对应关系
splitOneDay 一天切分的分片数

13.自然月分片算法

使用场景为按照月份列分区, 每个自然月为一个分片, 配置如下:

<tableRule name="sharding-by-month">
    <rule>
        <columns>create_time</columns>
        <algorithm>sharding-by-month</algorithm>
    </rule>
</tableRule>

<function name="sharding-by-month" class="io.mycat.route.function.PartitionByMonth">
	<property name="dateFormat">yyyy-MM-dd</property>
	<property name="sBeginDate">2020-01-01</property>
	<property name="sEndDate">2020-12-31</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
dateFormat 日期格式
sBeginDate 开始日期
sEndDate 结束日期,如果配置了结束日期,则代码数据到达了这个日期的分片后,会重复从开始分片插入

14.日期范围hash算法

其思想和范围取模分片一样,先根据日期进行范围分片求出分片组,再根据时间hash使得短期内数据分布的更均匀 ;

优点 : 可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题

注意 : 要求日期格式尽量精确些,不然达不到局部均匀的目的

<tableRule name="range-date-hash">
    <rule>
        <columns>create_time</columns>
        <algorithm>range-date-hash</algorithm>
    </rule>
</tableRule>

<function name="range-date-hash" class="io.mycat.route.function.PartitionByRangeDateHash">
	<property name="dateFormat">yyyy-MM-dd HH:mm:ss</property>
	<property name="sBeginDate">2020-01-01 00:00:00</property>
	<property name="groupPartionSize">6</property>
    <property name="sPartionDay">10</property>
</function>
属性 描述
columns 标识将要分片的表字段
algorithm 指定分片函数与function的对应关系
class 指定该分片算法对应的类
dateFormat 日期格式 , 符合Java标准
sBeginDate 开始日期 , 与 dateFormat指定的格式一致
groupPartionSize 每组的分片数量
sPartionDay 代表多少天为一组

4.mycat性能监控

  • mycatweb简介

    Mycat-web 是 Mycat 可视化运维的管理和监控平台,弥补了 Mycat 在监控上的空白。帮 Mycat 分担统计任务和配置管理任务。Mycat-web 引入了 ZooKeeper 作为配置中心,可以管理多个节点。Mycat-web 主要管理和监控 Mycat 的流量、连接、活动线程和内存等,具备 IP 白名单、邮件告警等模块,还可以统计 SQL 并分析慢 SQL 和高频 SQL 等。为优化 SQL 提供依据

  • mycatweb安装

    • 安装zookeeper (安装jdk)

      A. 上传安装包 
      	alt + p -----> put D:\tmp\zookeeper-3.4.11.tar.gz
      	
      B. 解压
      	tar -zxvf zookeeper-3.4.11.tar.gz -C /usr/local/
      
      C. 创建数据存放目录
      	mkdir data
      
      D. 修改配置文件名称并配置
      	mv zoo_sample.cfg zoo.cfg
      
      E. 配置数据存放目录
      	dataDir=/usr/local/zookeeper-3.4.11/data
      	
      F. 启动Zookeeper
      	bin/zkServer.sh start
      
    • 安装mycatweb

      A. 上传安装包 
      	alt + p --------> put D:\tmp\Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz
      	
      B. 解压
      	tar -zxvf Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz -C /usr/local/
      
      C. 目录介绍
          drwxr-xr-x. 2 root root  4096 Oct 19  2015 etc         ----> jetty配置文件
          drwxr-xr-x. 3 root root  4096 Oct 19  2015 lib         ----> 依赖jar包
          drwxr-xr-x. 7 root root  4096 Jan  1  2017 mycat-web   ----> mycat-web项目
          -rwxr-xr-x. 1 root root   116 Oct 19  2015 readme.txt
          -rwxr-xr-x. 1 root root 17125 Oct 19  2015 start.jar   ----> 启动jar
          -rwxr-xr-x. 1 root root   381 Oct 19  2015 start.sh    ----> linux启动脚本
      
      D. 启动
      	sh start.sh
      	
      E. 访问
      	http://192.168.192.147:8082/mycat
      

      如果Zookeeper与Mycat-web不在同一台服务器上 , 需要设置Zookeeper的地址 ; 在/usr/local/mycat-web/mycat-web/WEB-INF/classes/mycat.properties文件中配置

5.mycat读写分离

1.搭建主从复制(一主一从)

  • master配置文件(/etc/my.cnf)中配置

    ## 同一局域网内注意要唯一
    server-id=100  
    ## 开启二进制日志功能,可以随便取(关键)
    log-bin=master-bin 
    binlog-format=ROW     // 二级制日志格式,有三种 row,statement,mixed
    binlog-do-db=数据库名  //同步的数据库名称,如果不配置,表示同步所有的库
    
  • slave配置文件 (/etc/my.cnf)

    [mysqld]
    ## 设置server_id,注意要唯一
    server-id=101  
    ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
    log-bin=mysql-slave-bin   
    ## relay_log配置中继日志
    relay_log=mysql-relay-bin  
    read_only=1  ## 设置为只读,该项如果不设置,表示slave可读可写
    
  • 开启主从复制

    # master
    # 创建用户并授权
    CREATE USER '用户名'@'%' IDENTIFIED WITH 'mysql_native_password' BY '密码';
      GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%';
    flush privileges;
    # show master status查看Master状态 记住file和position
    
    SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
    #slave
    change master to master_host='服务器地址', master_user='用户名', master_password='密码', master_port=3306, master_log_file='master-bin.000001', master_log_pos=2344, master_connect_retry=30;
    start slave;
    stop slave;
    show slave status \G; 
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nwFdRiPN-1658027949266)(images/image-20220712091151471.png)]

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOFrwNKg-1658027949266)(images/image-20220712091335699.png)]

2.一主一从读写分离

  • 修改schem.xml配置文件

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="test1" checkSQLschema="true" sqlMaxLimit="100">
              <table name="user" dataNode="dn1" primaryKey="id" />
            </schema>
            <dataNode name="dn1" dataHost="localhost1" database="db1" />
    
    
            <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql"
                                    dbDriver="jdbc" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
                    <writeHost host="hostM1" url="jdbc:mysql://10.211.55.3:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="root">
                            <readHost host="hostS1" url="jdbc:mysql://10.211.55.4:3306?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=utf8" user="root" password="root" />
                    </writeHost>
            </dataHost>
    
    </mycat:schema>
    
    checkSQLschema
    	当该值设置为true时, 如果我们执行语句"select * from test01.user ;" 语句时, MyCat则会把schema字符去掉 , 可以避免后端数据库执行时报错 ;
    	
    	
    balance
    	负载均衡类型, 目前取值有4种:
    	
    	balance="0" : 不开启读写分离机制 , 所有读操作都发送到当前可用的writeHost上.
    	
    	balance="1" : 全部的readHost 与 stand by writeHost (备用的writeHost) 都参与select 语句的负载均衡,简而言之,就是采用双主双从模式(M1 --> S1 , M2 --> S2, 正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。);
        
        balance="2" : 所有的读写操作都随机在writeHost , readHost上分发
        
        balance="3" : 所有的读请求随机分发到writeHost对应的readHost上执行, writeHost不负担读压力 ;balance=3 只在MyCat1.4 之后生效 .
    
  • 修改server.xml配置文件

       <user name="root" defaultAccount="true">
                    <property name="password">root</property>
                    <property name="schemas">test1</property>
    
            </user>
    
            <user name="user">
                    <property name="password">root</property>
                    <property name="schemas">test1</property>
                    <property name="readOnly">true</property>
            </user>
    
  • 修改log4j日志级别info–>debug

        <Loggers>
            <!--<AsyncLogger name="io.mycat" level="info" includeLocation="true" additivity="false">-->
                <!--<AppenderRef ref="Console"/>-->
                <!--<AppenderRef ref="RollingFile"/>-->
            <!--</AsyncLogger>-->
            <asyncRoot level="debug" includeLocation="true">
    
                <!--<AppenderRef ref="Console" />-->
                <AppenderRef ref="RollingFile"/>
    
            </asyncRoot>
        </Loggers>
    

3.主从复制(双主双从)

# 重新配置主从关系
stop slave;
reset master;
  • master1配置

    #主服务器唯一ID
    server-id=1
    
    #启用二进制日志
    log-bin=master-bin 
    binlog-format=ROW
    
    # 设置不要复制的数据库(可设置多个)
    # binlog-ignore-db=mysql
    # binlog-ignore-db=information_schema
    
    #设置需要复制的数据库
    binlog-do-db=db02
    binlog-do-db=db03
    binlog-do-db=db04
    
    # 在作为从数据库的时候,有写入操作也要更新二进制日志文件
    log-slave-updates
    
  • master2配置

    #主服务器唯一ID
    server-id=2
    
    #启用二进制日志
    log-bin=master-bin 
    binlog-format=ROW
    
    # 设置不要复制的数据库(可设置多个)
    # binlog-ignore-db=mysql
    # binlog-ignore-db=information_schema
    
    #设置需要复制的数据库
    binlog-do-db=db02
    binlog-do-db=db03
    binlog-do-db=db04
    
    # 在作为从数据库的时候,有写入操作也要更新二进制日志文件
    log-slave-updates
    
  • 双从机配置

    [mysqld]  # slave1
    ## 设置server_id,注意要唯一
    server-id=3 
    ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
    log-bin=mysql-slave-bin   
    ## relay_log配置中继日志
    relay_log=mysql-relay-bin  
    read_only=1  ## 设置为只读,该项如果不设置,表示slave可读可写
    
    #slave2
    ## 设置server_id,注意要唯一
    server-id=4 
    ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
    log-bin=mysql-slave-bin   
    ## relay_log配置中继日志
    relay_log=mysql-relay-bin  
    read_only=1  ## 设置为只读,该项如果不设置,表示slave可读可写
    
    # master上操作
    # 创建用户并授权
    CREATE USER '用户名'@'%' IDENTIFIED WITH 'mysql_native_password' BY '密码';
    GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%';
    flush privileges;
    # show master status查看Master状态 记住file和position
    
    #slave1->mast1 slave2 ->master2
    change master to master_host='服务器地址', master_user='用户名', master_password='密码', master_port=3306, master_log_file='master-bin.000001', master_log_pos=2344, master_connect_retry=30;
    start slave;
    stop slave;
    show slave status \G; 
    
  • 双主机配置

    # master1操作
    CHANGE MASTER TO MASTER_HOST='master2',
    MASTER_USER='用户',
    MASTER_PASSWORD='密码',
    MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=409;
    
    #master2操作
    CHANGE MASTER TO MASTER_HOST='master1',
    MASTER_USER='用户',
    MASTER_PASSWORD='密码',
    MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=409;
    

4.双主双从读写分离

  • schem.xml配置
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	
	<schema name="test" checkSQLschema="true" sqlMaxLimit="100">
		<table name="user" dataNode="dn1" primaryKey="id"/>
	</schema>
	
	<dataNode name="dn1" dataHost="localhost1" database="db03" />

	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" 	
				dbDriver="native" switchType="1"  slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<writeHost host="hostM1" url="192.168.192.147:3306" user="root" password="root">
			<readHost host="hostS1" url="192.168.192.149:3306" user="root" password="root" />
		</writeHost>
		
		<writeHost host="hostM2" url="192.168.192.150:3306" user="root" password="root">
			<readHost host="hostS2" url="192.168.192.151:3306" user="root" password="root" />
		</writeHost>
	</dataHost>
    
</mycat:schema>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_53060535/article/details/125829796

智能推荐

ubuntu 完全干净的卸载docker_ubuntu卸载docker-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏11次。ubuntu 完全干净的卸载docker_ubuntu卸载docker

java毕业设计疫苗及注射管理系统(springboot+mysql+jdk1.8+meven)-程序员宅基地

文章浏览阅读1.1k次,点赞18次,收藏10次。这样,前端Vue.js和后端Spring Boot框架的接口紧密协作,而MySQL数据库则作为数据存储和管理的核心,确保了整个系统的数据一致性和高效处理。通过本系统的设计与实施,旨在为政府和卫生部门提供一个高效、可靠、易用的疫苗及注射管理平台,满足现代疫苗管理的需求,同时为学生提供一个实践和提升技能的机会。以上选题背景和意义内容是根据本选题撰写,非本作品实际的选题背景、意义或功能。推动行业发展:随着信息技术的发展,疫苗及注射管理系统的建立将推动整个卫生防疫行业的信息化、数字化进程,促进行业的创新和发展。

JSON详解-程序员宅基地

文章浏览阅读66次。原文出处:http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.htmlJSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。XML也是一种数据交换格式,为什么没有选择XML呢?因为XML虽然可以作为跨平台的数据交换...

Python水平自测!100道经典练习题.pdf(附答案)_python题库 file:pdf-程序员宅基地

文章浏览阅读1.4w次,点赞80次,收藏579次。自学Python最令人头痛的地方,不是学不进去,而是不知道自己学完之后是什么样的水平!篇幅原因本文只分享了前10道练习题。公号文章处放了前36道题,大家可以自行查阅:https://mp.weixin.qq.com/s/qvcrduneuvmfLEyfoQkf9Q文末附完整版Python100经典练习题.pdf下载方式,大家自行获取即可~1:Python有哪些特点和优点?答:作为一门编程入门语言,Python主要有以下特点和优点:可解释具有动态特性面向对象简..._python题库 file:pdf

Java中Double类型出现科学计数法问题解决方法_java double科学计数-程序员宅基地

文章浏览阅读1.7k次。Double类型接收参数出现科学计数法_java double科学计数

51单片机寻迹小车_51单片机巡线小车说明书-程序员宅基地

文章浏览阅读3w次,点赞136次,收藏1.1k次。# 基于51单片机的循迹小车(详细讲解+源码)作为一名大学生,这里我就简单谈谈我们小组做这个循迹小车的一个过程。主要是实现小车寻黑线行驶的这样一个功能,速度可以调节(定时器中断模拟PWM波实现)一丶硬件部分小车的主体框架是一个三轮的外在形态电源:采用2S可充电锂电池作为主电源供给(主要是给驱动,单片机供电)传感器:采用灰度传感器(2个)灰度传感器工作原理很简单,下面有介绍,它和单片机之间的通信就是通过代码来体现的:两个灰度传感器的信号输出端(DO,这里可以定义两个变量分别保存他们的输出信号)_51单片机巡线小车说明书

随便推点

【youcans 的 OpenCV 例程200篇】128. 形态算法之骨架 (skimage)_c++opencv骨骼化-程序员宅基地

文章浏览阅读5k次,点赞3次,收藏28次。形态骨架(morphological skeleton)是一种细化的结构,指图像的骨骼部分,用于描述物体的几何形状和拓扑结构,是目标物体重要的拓扑描述。图像的细化是对二值图像进行骨架提取,删除不需要的轮廓点,只保留其骨架点。skimage 中提供了函数 **skimage.morphology.skeletonize** 可以获取图像的骨骼。_c++opencv骨骼化

SQL Server 2008 R2 Developer Edition图文安装教程_sql server 2008 developer-程序员宅基地

文章浏览阅读2.6k次。 转载自:https://blog.csdn.net/lucky51222/article/details/72953853本文主要以截图的方式,详细说明SQL Server 2008 R2 Developer Edition的安装过程。1.下载SqlServer的64位安装包如下: 2.双击安装首先将安装可执行程序拷贝到其他文件夹下然后默认解压路径为:C:\Users..._sql server 2008 developer

ACE的使用及其核心模块讲解等_ace使用-程序员宅基地

文章浏览阅读2.9k次。下面为本人在使用ACE中遇到的一些问题的汇总,只介绍了大体的思路,具体的细节还需进佐证。 1. ACE配置模块的使用 就一个正常项目而言,一个配置文件是必不可少的,那就先从这里入手了。linux/unix 程序可能经常用到命令行方式,不过我还是比较喜欢windows 的 ini 格式的,当然,有xml 的更好,不过 ACE 里暂时没有提供。配置文件的使用很简单,ACE 提供的类也很友好。代_ace使用

python飞机大战源代码(可直接运行)_飞机大战python源代码-程序员宅基地

文章浏览阅读5.6w次,点赞60次,收藏96次。喜欢的点个赞支持一下哦联系方式见评论区--------------欢迎大家一起探讨-----------------------------------------------------------------具体的代码:settings配置import pygameclass Settings(object): """设置常用的属性""" def __ini..._飞机大战python源代码

php加固_php文件上传加固-程序员宅基地

文章浏览阅读1.3k次。PHP应用部署后,开发者或者运维人员应该时刻关注PHP方面的漏洞消息,升级PHP版本,对PHP环境进行安全加固。本文将给大家介绍如何从WEB安全方面让你的网站更坚固更安全。1.启用 PHP 的安全模式PHP 环境提供的安全模式是一个非常重要的内嵌安全机制,PHP 安全模式能有效控制一些 PHP 环境中的函数(例如system()函数),对大部分的文件操作函数进行权限控制,同时不允许对某些关..._php文件上传加固

BM3406-VB一款N—Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明-程序员宅基地

文章浏览阅读210次。BM3406-VB是一款SOT23封装的N—Channel沟道场效应晶体管,具有低电阻、高电流特性,适用于高性能开关电子应用。4. **汽车电子:** 在汽车电子系统中,用于控制电动窗、座椅等模块。2. **驱动模块:** 在驱动电路中,实现快速、可靠的开关操作。1. **电源模块:** 用于电源开关和稳压模块,确保高效能耗。3. **电动工具:** 用于电动工具中的电源和驱动控制。- 产品型号:BM3406-VB。- 沟道类型:N—Channel。- 品牌:VBsemi。- 封装:SOT23。

推荐文章

热门文章

相关标签