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

智能推荐

51单片机的中断系统_51单片机中断篇-程序员宅基地

文章浏览阅读3.3k次,点赞7次,收藏39次。CPU 执行现行程序的过程中,出现某些急需处理的异常情况或特殊请求,CPU暂时中止现行程序,而转去对异常情况或特殊请求进行处理,处理完毕后再返回现行程序断点处,继续执行原程序。void 函数名(void) interrupt n using m {中断函数内容 //尽量精简 }编译器会把该函数转化为中断函数,表示中断源编号为n,中断源对应一个中断入口地址,而中断入口地址的内容为跳转指令,转入本函数。using m用于指定本函数内部使用的工作寄存器组,m取值为0~3。该修饰符可省略,由编译器自动分配。_51单片机中断篇

oracle项目经验求职,网络工程师简历中的项目经验怎么写-程序员宅基地

文章浏览阅读396次。项目经验(案例一)项目时间:2009-10 - 2009-12项目名称:中驰别克信息化管理整改完善项目描述:项目介绍一,建立中驰别克硬件档案(PC,服务器,网络设备,办公设备等)二,建立中驰别克软件档案(每台PC安装的软件,财务,HR,OA,专用系统等)三,能过建立的档案对中驰别克信息化办公环境优化(合理使用ADSL宽带资源,对域进行调整,对文件服务器进行优化,对共享打印机进行调整)四,优化完成后..._网络工程师项目经历

LVS四层负载均衡集群-程序员宅基地

文章浏览阅读1k次,点赞31次,收藏30次。LVS:Linux Virtual Server,负载调度器,内核集成, 阿里的四层SLB(Server Load Balance)是基于LVS+keepalived实现。NATTUNDR优点端口转换WAN性能最好缺点性能瓶颈服务器支持隧道模式不支持跨网段真实服务器要求anyTunneling支持网络private(私网)LAN/WAN(私网/公网)LAN(私网)真实服务器数量High (100)High (100)真实服务器网关lvs内网地址。

「技术综述」一文道尽传统图像降噪方法_噪声很大的图片可以降噪吗-程序员宅基地

文章浏览阅读899次。https://www.toutiao.com/a6713171323893318151/作者 | 黄小邪/言有三编辑 | 黄小邪/言有三图像预处理算法的好坏直接关系到后续图像处理的效果,如图像分割、目标识别、边缘提取等,为了获取高质量的数字图像,很多时候都需要对图像进行降噪处理,尽可能的保持原始信息完整性(即主要特征)的同时,又能够去除信号中无用的信息。并且,降噪还引出了一..._噪声很大的图片可以降噪吗

Effective Java 【对于所有对象都通用的方法】第13条 谨慎地覆盖clone_为继承设计类有两种选择,但无论选择其中的-程序员宅基地

文章浏览阅读152次。目录谨慎地覆盖cloneCloneable接口并没有包含任何方法,那么它到底有什么作用呢?Object类中的clone()方法如何重写好一个clone()方法1.对于数组类型我可以采用clone()方法的递归2.如果对象是非数组,建议提供拷贝构造器(copy constructor)或者拷贝工厂(copy factory)3.如果为线程安全的类重写clone()方法4.如果为需要被继承的类重写clone()方法总结谨慎地覆盖cloneCloneable接口地目的是作为对象的一个mixin接口(详见第20_为继承设计类有两种选择,但无论选择其中的

毕业设计 基于协同过滤的电影推荐系统-程序员宅基地

文章浏览阅读958次,点赞21次,收藏24次。今天学长向大家分享一个毕业设计项目基于协同过滤的电影推荐系统项目运行效果:项目获取:https://gitee.com/assistant-a/project-sharing21世纪是信息化时代,随着信息技术和网络技术的发展,信息化已经渗透到人们日常生活的各个方面,人们可以随时随地浏览到海量信息,但是这些大量信息千差万别,需要费事费力的筛选、甄别自己喜欢或者感兴趣的数据。对网络电影服务来说,需要用到优秀的协同过滤推荐功能去辅助整个系统。系统基于Python技术,使用UML建模,采用Django框架组合进行设

随便推点

你想要的10G SFP+光模块大全都在这里-程序员宅基地

文章浏览阅读614次。10G SFP+光模块被广泛应用于10G以太网中,在下一代移动网络、固定接入网、城域网、以及数据中心等领域非常常见。下面易天光通信(ETU-LINK)就为大家一一盘点下10G SFP+光模块都有哪些吧。一、10G SFP+双纤光模块10G SFP+双纤光模块是一种常规的光模块,有两个LC光纤接口,传输距离最远可达100公里,常用的10G SFP+双纤光模块有10G SFP+ SR、10G SFP+ LR,其中10G SFP+ SR的传输距离为300米,10G SFP+ LR的传输距离为10公里。_10g sfp+

计算机毕业设计Node.js+Vue基于Web美食网站设计(程序+源码+LW+部署)_基于vue美食网站源码-程序员宅基地

文章浏览阅读239次。该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流项目运行环境配置:项目技术:Express框架 + Node.js+ Vue 等等组成,B/S模式 +Vscode管理+前后端分离等等。环境需要1.运行环境:最好是Nodejs最新版,我们在这个版本上开发的。其他版本理论上也可以。2.开发环境:Vscode或HbuilderX都可以。推荐HbuilderX;3.mysql环境:建议是用5.7版本均可4.硬件环境:windows 7/8/10 1G内存以上;_基于vue美食网站源码

oldwain随便写@hexun-程序员宅基地

文章浏览阅读62次。oldwain随便写@hexun链接:http://oldwain.blog.hexun.com/ ...

渗透测试-SQL注入-SQLMap工具_sqlmap拖库-程序员宅基地

文章浏览阅读843次,点赞16次,收藏22次。用这个工具扫描其它网站时,要注意法律问题,同时也比较慢,所以我们以之前写的登录页面为例子扫描。_sqlmap拖库

origin三图合一_神教程:Origin也能玩转图片拼接组合排版-程序员宅基地

文章浏览阅读1.5w次,点赞5次,收藏38次。Origin也能玩转图片的拼接组合排版谭编(华南师范大学学报编辑部,广州 510631)通常,我们利用Origin软件能非常快捷地绘制出一张单独的绘图。但是,我们在论文的撰写过程中,经常需要将多种科学实验图片(电镜图、示意图、曲线图等)组合在一张图片中。大多数人都是采用PPT、Adobe Illustrator、CorelDraw等软件对多种不同类型的图进行拼接的。那么,利用Origin软件能否实..._origin怎么把三个图做到一张图上

51单片机智能电风扇控制系统proteus仿真设计( 仿真+程序+原理图+报告+讲解视频)_电风扇模拟控制系统设计-程序员宅基地

文章浏览阅读4.2k次,点赞4次,收藏51次。51单片机智能电风扇控制系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0042。_电风扇模拟控制系统设计