第111讲:Mycat实践指南:固定Hash算法分片下的水平分表详解

文章目录

    • 1.固定Hash算法分片的概念
      • 1.1.固定Hash算法的概念
      • 1.2.固定Hash算法是如何将数据路由到分片节点的
    • 2.使用固定Hash算法分片对某张表进行水平拆分
      • 2.1.在所有的分片节点中创建表结构
      • 2.2.配置Mycat实现固定Hash算法分片的水平分表
        • 2.2.1.配置Schema配置文件
        • 2.2.2.配置Rule分片规则配置文件
        • 2.2.3.配置Server配置文件
        • 2.2.4.重启Mycat
      • 2.3.写入数据观察分片效果

1.固定Hash算法分片的概念

1.1.固定Hash算法的概念

固定Hash算法类似于十进制的求模运算,但是固定Hash算法是为二进制进行运算的,固定Hash运算会将依据的字段转换成耳机10位的二进制数字,然后与二进制1111111111进行位&运算。

位于运算时这个样子的:例如8的二进制是1000,7的二进制是0111,求1000和0111的位&运算,计算方式就是按照第一个二进制的每一位与第二个二进制的每一位进行相乘,如1*0=0 0*1=0 0*1=0 0*1=0 ,最后得出1000和0111的位&运算是0000。

固定Hash算法会将依据的字段内容转换成二进制数,然后与1111111111进行位运算,任何二进制数与1111111111进行位运算最终的结果都会在0000000000和1111111111之间,转换成十进制数也就是0-1023。

我们可以将分片策略设置0-255之间划分到分片1,256-512之间划分到分片2,512-1023划分到分片3,当依据字段被固定Hash转换成2进制数并且位运算完后,得到一个十进制数时,根据十进制数所在的分片,将数据写入到对应的分片节点中。

如下图所示,当字段值为1时,转换成二进制数与10个1进行位运算,最后在转换成十进制数,刚好也是1,0~255之间划分到分片1上,此时这条数据就会被划分到分片1节点上。

image-20220715205222179

固定Hash算法的特点:

  • 如果是取模分片,连续的值可能会分配到不同的分片中,而固定Hash算法会将连续的值可能分配到同一个分片中,降低事务处理的难度。
  • 可以均匀的分配,也可以非均匀分配。
  • 分片字段必须是数字类型。

1.2.固定Hash算法是如何将数据路由到分片节点的

我们会在定义分片策略时,一共有3个分片节点,例如定义第一个节点存储位运算结果0-255之间的数据,第二个节点处理256-511之间的数据,第三个节点处理512到1023之间的数据,此时前两个节点分别处理256个数组。,第三个节点则处理512个数组。

在0-255之间数组的结构中,会记录上第一个分片节点的ID0,255-511之间的数组的结构中,记录第二个分片节点的ID1,512-1023之间的数组结构中,记录第三个分片节点的ID2。

例如当字段值为515,经过固定Hash算法运算,将515转换成二进制数,与1023的二进制数进行位运算,最后的出来位运算的结果是十进制数515,515位于512-1023数组之间,此时就会拿导512-1023数组对应的分片ID号,然后将这条数据写入到对应的分片节点中。

image-20220715205802785

2.使用固定Hash算法分片对某张表进行水平拆分

需求:目前有一张tb_longhash 表,表中的id一列的值是数字类型,我们按照这个字段进行固定Hash算法分片。

2.1.在所有的分片节点中创建表结构

分片依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。

#在分片1节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11
mysql> use db_2;
mysql> create table tb_longhash (id int,name varchar(200),firstchar char(1));


#在分片2节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11
mysql> use db_2;
mysql> create table tb_longhash (id int,name varchar(200),firstchar char(1));

2.2.配置Mycat实现固定Hash算法分片的水平分表

2.2.1.配置Schema配置文件
[root@mysql-1 ~]# vim /data/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
         <!--定义逻辑库 库名叫做db_shopping 该逻辑库关联dn1这个数据节点-->
        <schema name="db_2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            <!--固定Hash算法分片-->
            <table name="tb_longhash" dataNode="dn1,dn2" rule="sharding-by-long-hash"/>
        </schema>  

        <!--定义数据节点 也就是分片 一个分片会关联一个数据主机组 然后对应真实的数据库名称-->
        <dataNode name="dn1" dataHost="mysqlcluster-1" database= "db_2" />          
        <dataNode name="dn2" dataHost="mysqlcluster-2" database= "db_2" />          

        <!--定义数据主机 在这个标签下定义具体的读写操作路由的数据库实例地址 schema、table划分如何指定的是该数据主机关联的数据节点 那么对应的库、表都会被存储在数据主机定义的数据库实例中-->
        <dataHost name="mysqlcluster-1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <!--定义写操作路由的数据库实例-->
                <writeHost host="c1-1-master3306" url="192.168.20.11:3306" user="root" password="123456">
                        <!--定义读操作路由的数据库实例-->
                        <readHost host="c1-1-slave3308" url="192.168.20.11:3308" user="root" password="123456" />
                </writeHost> 
                <!--备用的主库 也是提供写操作的数据库,当主库c1-1-master3306故障后 备用库开始提供写操作-->
                <writeHost host="c1-2-master3306" url="192.168.20.12:3306" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c1-2-slave3308" url="192.168.20.12:3308" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

        <dataHost name="mysqlcluster-2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <writeHost host="c2-1-master3307" url="192.168.20.11:3307" user="root" password="123456">
                        <readHost host="c2-1-slave3309" url="192.168.20.11:3309" user="root" password="123456" />
                </writeHost> 
                <!--备用主库db3 主库db1故障后 开始提供写操作-->
                <writeHost host="c2-2-master3307" url="192.168.20.12:3307" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c2-2-slave3309" url="192.168.20.12:3309" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

</mycat:schema>
2.2.2.配置Rule分片规则配置文件
[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml
    <tableRule name="sharding-by-long-hash">
        <rule>
            <columns>id</columns>
            <!--关联固定hash的函数-->
            <algorithm>sharding-by-long-hash</algorithm>
        </rule> 
    </tableRule> 

   
    <function name="sharding-by-long-hash" class="io.mycat.route.function.PartitionByLong">
        <!--定义分片节点个数 书写方式和下面的partitionLength有对应关系 例如partitionCount为1,1 partitionLength为512,512 就表示前1个分片节点承载512个数组 后1个分片节点承载512个数组-->
        <property name="partitionCount">2,1</property>         <!--常见的有分片数量为,书写是这么写的:2,1 表示前两个节点分别承载多少个数组,具体承载多少个数组由partitionLength定义:256,512 连起来的意思就是说前两个分片分别承载256个数组,后一个分片承载512个数组-->
         <!-- 数组的总长度为1024 指定每个节点的数组数之后 多个数组相加起来必须等于1024--> 
        <property name="partitionLength">256,512</property>
    </function>	
2.2.3.配置Server配置文件
[root@mysql-1 ~]# vim /data/mycat/conf/server.xml
    <user name="root" defaultAccount="true">
        <!--登录用户的密码-->
        <property name="password">123456</property>
        <!--该用户登录后可以显示那些Schema-->
        <property name="schemas">db_2</property>
    </user>
2.2.4.重启Mycat
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...

2.3.写入数据观察分片效果

先插入5条连续的数据。

[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into tb_longhash (id,name,firstChar) values(1,'aa','Q');
mysql> insert into tb_longhash (id,name,firstChar) values(2,'nn','B'); 
mysql> insert into tb_longhash (id,name,firstChar) values(3,'ss','J'); 
mysql> insert into tb_longhash (id,name,firstChar) values(4,'ee','S'); 
mysql> insert into tb_longhash (id,name,firstChar) values(5,'hh','L'); 

可以看到数据全写入到了分片1中,这是因为1-5这个数字位运算后,还是1-5,当然会落在第一个分片中,0-511会写入到第一个分片,511-1023会写入到第二个分片。

image-20220715212012071

下面我们写入的数据id值给大一些,511-1023之间,观察效果。

[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into tb_longhash (id,name,firstChar) values(777,'uuu','L');
mysql> insert into tb_longhash (id,name,firstChar) values(1000,'uuu','L');

777和1000位运算后,属于512-1023之间的数据,此时会被路由到分片2中,水平分表成功。

image-20220715212324090

我们再观察一种现象,如果数大于1023呢,会写入到哪里?答案是写入到第一个分片,相当于第二轮了。

[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into tb_longhash (id,name,firstChar) values(1118,'uuu','L');
mysql> insert into tb_longhash (id,name,firstChar) values(1999,'uuu','L');

我们又分表插入了1118和1999这两台数据,1118属于第二轮的0-511之间的数据,路由到分片1,1999属于第二轮的512-1023的数据,路由到分片2。

image-20220715212443024

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/465834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信开发者工具如何使用?使用注意事项

&#xff08;1&#xff09;单位如何进行换算&#xff1f; 1 px 750/屏幕宽度 rpx 1 rpx 屏幕宽度/750 px &#xff08;2&#xff09;如何新建文件&#xff1f; 1> 点开app.json 2> 在“pages/index/index”后面接“&#xff0c;pages/自定义文件夹名/自定义文件名”…

FPGA 学习需要哪些东西?

FPGA 学习需要哪些东西&#xff1f; 三样东西&#xff1a;第一就是完整的理论&#xff0c;第二一套开发板&#xff0c;第三可练手的项目 第一&#xff0c;一套完整的课程&#xff0c; 这个课程必须是紧跟技术发展的&#xff0c;适应市场的&#xff0c;这样不至于学完后发现太…

开源Ai对话系统(MNAi)系统

支持对接gpt&#xff0c;阿里云&#xff0c;腾讯云/chatGPT源码/AI绘画系统/AI创作系统/AI写作系统 具体看截图 后端环境&#xff1a;PHP7.4MySQL5.6 软件&#xff1a;uniapp 部署教程请看源码内的【使用教程】文档 源码免费下载地址抄笔记 chaobiji.cn

【计算机网络篇】物理层(3)编码与调制

文章目录 &#x1f354;编码与调试⭐基本概念 &#x1f354;基本的带通调制方法和混合调制方法⭐基本的带通调制方法⭐混合调制方法 &#x1f354;编码与调试 物理层是OSI模型中的第一层&#xff0c;它负责在物理媒体上传输原始比特流。在物理层的编码和调试中&#xff0c;我们…

leetcode106从中序与后序遍历序列构造二叉树

目录 1.解题关键2.思路3.变量名缩写与英文单词对应关系4.算法思路图解5.代码 本文针对原链接题解的比较晦涩的地方重新进行说明解释 原题解链接&#xff1a;https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/solutions/50561/tu-jie-…

3D Tiles语义分割流水线

Dylan Chua 和 Anne Lee 开发了一个处理管线&#xff0c;用于对 3D Tiles 中包含的 GL 传输格式 (glTF) 模型进行语义分割。 该管道读取并遍历 3D Tileset&#xff0c;以输出包含元数据的经过转换的划分对象集。 该项目为 3D 语义分割器提供了最小可行产品&#xff0c;作为各种…

STM32CubeIDE基础学习-BEEP蜂鸣器实验

STM32CubeIDE基础学习-BEEP蜂鸣器实验 文章目录 STM32CubeIDE基础学习-BEEP蜂鸣器实验前言第1章 硬件介绍第2章 工程配置2.1 工程外设配置部分2.2 生成工程代码部分 第3章 代码编写第4章 实验现象总结 前言 前面学习了LED闪烁实验&#xff0c;现在来学习一下蜂鸣器发声实验&am…

JVM工作原理与实战(四十四):JVM常见面试题目

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、JVM常见面试题目 1.有哪些常用的垃圾回收器&#xff1f; 2.什么是内存泄漏&#xff0c;如何解决内存泄漏问题&#xff1f; 3.请列举并简要描述一些常用的JVM工具及其主要功能。 …

用python写网络爬虫:3.urllib库进一步的使用方法

文章目录 异常处理URLErrorHTTPError设置超时时间 链接的解析、构造、合并urlparse方法urlsplit方法urljoin方法urlencode方法parse_qs方法quote方法 Robots 协议Robots 协议的结构解析协议 参考书籍 在上一篇文章&#xff1a;用python写网络爬虫&#xff1a;2.urllib库的基本用…

Nginx底层基础数据结构

基础数据结构 ngx_int_t 32位操作系统4字节,64位操作系统8字节 解决跨平台以及,普通int类型在x86和x64操作系统上面是4字节,在类型转换时造成内存浪费(如在x64下面转换long类型) typedef intptr_t ngx_int_t;#ifdef _WIN64 typedef __int64 intptr_t; #else typedef _…

Canal实现mysql与缓存同步

什么是Canal Canal是阿里巴巴旗下的一款开源项目, 基于java开发. Canal是基于mysql的主从同步来实现的. github地址: https://github.com/alibaba/canal Canal把自己伪装成MySQL的一个slave节点, 从而监听master的binary log变化. 再把得到的变化信息通知给Canal的客户端, 进而…

vue3 element plus 上传下载

文章目录 上传下载 上传 /* html */ <el-upload v-model"fileId" class"avatar-uploader" ref"exampleUploadRef" :file-list"fileList" :show-file-list"false" action"/ys-three-year/ThreeReport/uploadFile&q…

Python从0到100(五):Python分支结构和循环结构

一、分支结构&#xff1a; Python中的分支结构和循环结构是编写程序时常用的控制结构。在Python中&#xff0c;分支结构通过if、elif和else关键字来实现条件判断。在使用if语句时&#xff0c;程序会根据条件表达式的真假执行相应的代码块。 if condition1:# 如果条件1为真&am…

YOLOv5改进 | 图像去雾 | 利用图像去雾网络UnfogNet辅助YOLOv5进行图像去雾检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用UnfogNet超轻量化图像去雾网络,我将该网络结合YOLOv5针对图像进行去雾检测(也适用于一些模糊场景),我将该网络结构和YOLOv5的网络进行结合同时该网络的结构的参数量非常的小,我们将其添加到模型里增加的计算量和参数量基本可…

每天一点正压采样器小知识

只要你奔跑&#xff0c;这个世界就会跟着你奔跑&#xff0c; 只要你停驻&#xff0c;这个世界就会舍弃你独自奔跑&#xff0c; 唯有你确定一个方向&#xff0c;使劲的跑起来&#xff0c; 这个世界会为你而让路。 每天一点正压采样器小知识 该采样器活赛与气筒采用全金属密封&am…

操作系统知识-存储管理+文件管理管理-嵌入式系统设计师备考笔记

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记&#xff0c;未经本人许可&#xff0c;请勿转载&#xff0c;如发现本笔记内容的错误还望各位不吝赐教&#xff08;笔记内容可能有误怕产生错误引导&#xff09;。 本章的主要内容见下图&#xff1a; 1、存储管理&#…

[c++]内存管理

1. C/C内存分布 我们先来看下面的一段代码和相关问题 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1; int num1[10] { 1, 2, 3, 4 }; char char2[] "abcd"; const char* pChar3 "abcd"; …

Redis 八种常用数据类型详解

夯实基础&#xff0c;这篇文章带着大家回顾一下 Redis 中的 8 种常用数据类型&#xff1a; 5 种基础数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zse…

想进阿里?先搞懂Spring Bean的循环依赖!

如有疑问或者更多的技术分享,欢迎关注我的微信公众号“知其然亦知其所以然”! 嗨,小伙伴们!我是小米,你们的技术分享小助手!今天我们要聊的话题可是技术圈内颇为热门的“阿里巴巴面试题:Spring的循环依赖”哦!相信很多小伙伴都会在技术面试中遇到类似的问题,没错,循…

QT网络编程之获取本机网络信息

一.概述 查询一个主机的MAC地址或者IP地址是网络应用中常用到的功能&#xff0c;Qt提供了QHostInfo和QNetworkInterface 类可以用于此类信息的查询 1.QHostInfo 类&#xff08;显示和查找本地的信息&#xff09; 2.QNetworkInterface 类&#xff08;获得应用程序上所在主机的…