分库分表之Mycat应用学习四

4 分片策略详解

分片的目标是将大量数据和访问请求均匀分布在多个节点上,通过这种方式提升数
据服务的存储和负载能力。

4.1 Mycat 分片策略详解

总体上分为连续分片和离散分片,还有一种是连续分片和离散分片的结合,例如先
范围后取模。
在这里插入图片描述
比如范围分片(id 或者时间)就是典型的连续分片,单个分区的数量和边界是确定
的。离散分片的分区总数量和边界是确定的,例如对 key 进行哈希运算,或者再取模。
关键词:范围查询、热点数据、扩容
连续分片优点:
1)范围条件查询消耗资源少(不需要汇总数据)
2)扩容无需迁移数据(分片固定)
连续分片缺点:
1)存在数据热点的可能性
2)并发访问能力受限于单一或少量 DataNode(访问集中)
离散分片优点:
1)并发访问能力增强(负载到不同的节点)
2)范围条件查询性能提升(并行计算)
离散分片缺点:
1)数据扩容比较困难,涉及到数据迁移问题
2)数据库连接消耗比较多

4.1.1 连续分片

范围分片(已演示)

<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>
</function>
# range start-end ,data node index
# K=1000,M=10000. 0-500M=0
500M-1000M=1
1000M-1500M=2

特点:容易出现冷热数据
按自然月分片
建表语句

CREATE TABLE `sharding_by_month` (
`create_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTA
`db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT

逻辑表

<schema name="catmall" checkSQLschema="false" sqlMaxLimit="100"><table name="sharding_by_month" dataNode="dn1,dn2,dn3" rule="qs-sharding-by-month" />
</schema>

分片规则

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

分片算法

<function name="qs-partbymonth" class="io.mycat.route.function.PartitionByMonth"><property name="dateFormat">yyyy-MM-dd</property><property name="sBeginDate">2019-10-01</property><property name="sEndDate">2019-12-31</property>
</function>

columns 标识将要分片的表字段,字符串类型,与 dateFormat 格式一致。
algorithm 为分片函数。
dateFormat 为日期字符串格式。
sBeginDate 为开始日期。
sEndDate 为结束日期
注意:节点个数要大于月份的个数
测试语句

INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-10-16', database());
INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-10-27', database());
INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-11-04', database());
INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-11-11', database());
INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-12-25', database());
INSERT INTO sharding_by_month (create_time,db_nm) VALUES ('2019-12-31', database());

另外还有按天分片(可以指定多少天一个分片)、按小时分片

4.1.2 离散分片

枚举分片
将所有可能出现的值列举出来,指定分片。例如:全国 34 个省,要将不同的省的数据存放在不同的节点,可用枚举的方式。
建表语句:

CREATE TABLE `sharding_by_intfile` (
`age` int(11) NOT NULL, `db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

逻辑表:

<table name="sharding_by_intfile" dataNode="dn$1-3" rule="qs-sharding-by-intfile" />

分片规则:

<tableRule name="sharding-by-intfile"><rule><columns>sharding_id</columns><algorithm>hash-int</algorithm></rule>
</tableRule>

分片算法:

<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"><property name="mapFile">partition-hash-int.txt</property><property name="type">0</property><property name="defaultNode">0</property>
</function>

type:默认值为 0,0 表示 Integer,非零表示 String。
PartitionByFileMap.java,通过 map 来实现。
策略文件:partition-hash-int.txt

16=0
17=1
18=2

插入数据测试:

INSERT INTO `sharding_by_intfile` (age,db_nm) VALUES (16, database());
INSERT INTO `sharding_by_intfile` (age,db_nm) VALUES (17, database());
INSERT INTO `sharding_by_intfile` (age,db_nm) VALUES (18, database())

特点:适用于枚举值固定的场景。

一致性哈希
一致性 hash 有效解决了分布式数据的扩容问题。
建表语句:

CREATE TABLE `sharding_by_murmur` (
`id` int(10) DEFAULT NULL, `db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB 

逻辑表

<schema name="test" checkSQLschema="false" sqlMaxLimit="100"><table name="sharding_by_murmurhash" primaryKey="id" dataNode="dn$1-3" rule="sharding-by-murmur" />
</schema>

分片规则

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

分片算法

<function name="qs-murmur" class="io.mycat.route.function.PartitionByMurmurHash"><property name="seed">0</property><property name="count">3</property><property name="virtualBucketTimes">160</property>
</function>

测试语句

INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (1, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (2, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (3, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (4, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (5, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (6, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (7, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (8, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (9, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (10, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (11, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (12, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (13, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (14, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (15, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (16, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (17,database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (18, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (19, database());
INSERT INTO `sharding_by_murmur` (id,db_nm) VALUES (20, database())

特点:可以一定程度减少数据的迁移。
十进制取模分片(已演示)
根据分片键进行十进制求模运算。

<tableRule name="mod-long"><rule><columns>sid</columns><algorithm>mod-long</algorithm></rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"><!-- how many data nodes --><property name="count">3</property>
</function>

特点:分布均匀,但是迁移工作量比较大
固定分片哈希
这是先求模得到逻辑分片号,再根据逻辑分片号直接映射到物理分片的一种散列算法。
建表语句:

CREATE TABLE `sharding_by_long` (
`id` int(10) DEFAULT NULL,
`db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

逻辑表

<schema name="test" checkSQLschema="false" sqlMaxLimit="100"><table name="sharding_by_long" dataNode="dn$1-3" rule="qs-sharding-by-long" />
</schema>

分片规则

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

平均分成 8 片(%1024 的余数,1024=128*8):

<function name="qs-sharding-by-long" class="io.mycat.route.function.PartitionByLong"><property name="partitionCount">8</property><property name="partitionLength">128</property>
</function>
  • partitionCount 为指定分片个数列表。
  • partitionLength 为分片范围列
    在这里插入图片描述
    第二个例子:
    两个数组,分成不均匀的 3 个节点(%1024 的余数,1024=2256+1512):
<function name="qs-sharding-by-long" class="io.mycat.route.function.PartitionByLong"><property name="partitionCount">2,1</property><property name="partitionLength">256,512</property>
</function>

3 个节点,对 1024 取模余数的分布
在这里插入图片描述
测试语句

INSERT INTO `sharding_by_long` (id,db_nm) VALUES (222, database());
INSERT INTO `sharding_by_long` (id,db_nm) VALUES (333, database());
INSERT INTO `sharding_by_long` (id,db_nm) VALUES (666, database());

特点:在一定范围内 id 是连续分布的
取模范围分片
逻辑表

<schema name="test" checkSQLschema="false" sqlMaxLimit="100"><table name="sharding_by_pattern" primaryKey="id" dataNode="dn$0-10" rule="qs-sharding-by-pattern" />
</schema>

建表语句

CREATE TABLE `sharding_by_pattern` (
`id` varchar(20) DEFAULT NULL, `db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=ut

分片规则

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

分片算法

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

patternValue 取模基数,这里设置成 100
partition-pattern.txt,一共 3 个节点
id=19%100=19,在 dn1;
id=222%100=22,dn2;
id=371%100=71,dn3

# id partition range start-end ,data node index
###### first host configuration
1-20=0
21-70=1
71-100=2
0-0=0

测试语句

INSERT INTO `sharding_by_pattern` (id,db_nm) VALUES (19, database());
INSERT INTO `sharding_by_pattern` (id,db_nm) VALUES (222, database());
INSERT INTO `sharding_by_pattern` (id,db_nm) VALUES (371, database())

特点:可以调整节点的数据分布
范围取模分片
建表语句

CREATE TABLE `sharding_by_rang_mod` (
`id` bigint(20) DEFAULT NULL, `db_nm` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

逻辑表

<schema name="test" checkSQLschema="false" sqlMaxLimit="100"><table name="sharding_by_rang_mod" dataNode="dn$1-3" rule="qs-sharding-by-rang-mod" />
</schema>

分片规则

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

分片算法

<function name="qs-rang-mod" class="io.mycat.route.function.PartitionByRangeMod"><property name="mapFile">partition-range-mod.txt</property>
</function>

partition-range-mod.txt

# range start-end ,data node group size
0-20000=1
20001-40000=2

解读:先范围后取模。Id 在 20000 以内的,全部分布到 dn1。Id 在 20001-40000
的,%2 分布到 dn2,dn3。
插入数据:

INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (666, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (6667, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (16666, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (21111, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (22222, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (23333, database());
INSERT INTO `sharding_by_rang_mod` (id,db_nm) VALUES (24444, database());

特点:扩容的时候旧数据无需迁移
其他分片规则
应用指定分片 PartitionDirectBySubString
日期范围哈希 PartitionByRangeDateHash
冷热数据分片 PartitionByHotDate
也 可 以 自 定 义 分 片 规 则 : extends AbstractPartitionAlgorithm implements
RuleAlgorithm。

4.1.3 切分规则的选择

步骤:
1、找到需要切分的大表,和关联的表
2、确定分片字段(尽量使用主键),一般用最频繁使用的查询条件
3、考虑单个分片的存储容量和请求、数据增长(业务特性)、扩容和数据迁移问题
例如:按照什么递增?序号还是日期?主键是否有业务意义?
一般来说,分片数要比当前规划的节点数要大。
总结:根据业务场景,合理地选择分片规则
举例:
老师:3.7 亿的数据怎么分表?我是不是分成 3 台服务器?
1、一年内到达多少?两年内到达多少?(数据的增长速度)?
答:一台设备每秒钟往 3 张表各写入一条数据,一共 4 台设备。每张表一天86400*4=345600 条。每张表一个月 10368000 条。
分析:增长速度均匀,可以用日期切分,每个月分一张表。
2、什么业务?所有的数据都会访问,还是访问新数据为主?
答:访问新数据为主,但是所有的数据都可能会访问到。
3、表结构和表数据是什么样的?一个月消耗多少空间?
答:字段不多,算过了,三年数据量有 3.7 亿,30G。
分析:30G 没必要分库,浪费机器。
4、访问量怎么样?并发压力大么?
答:并发有一点吧
分析:如果并发量不大,不用分库,只需要在单库分表。不用引入 Mycat 中间件了。如果要自动路由的话可以用 Sharding-JDBC,否则就是自己拼装表名。
5、3 张表有没有关联查询之类的操作?
答:没有。
分析:还是拼装表名简单一点。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于AT89C51单片机可做实物的温度烟雾火灾报警设计

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/88658141?spm1001.2014.3001.5503 C 源码仿真图毕业设计实物制作步骤02 摘要 随着现代家庭用火、用电量的增加&#xff0c;家庭火灾发生的频率越来越高。火灾报警…

浅学lombok

Lombok&#xff08;Project Lombok&#xff09;是一个用于 Java 编程语言的开源库&#xff0c;旨在减少 Java 代码中的冗余和样板代码&#xff0c;提高开发人员的生产力。它通过使用注解来自动生成 Java 类的常见方法和代码&#xff0c;从而使开发人员能够编写更简洁、更具可读…

ColibriSM v1.4.2 已注册– 仿脸书类社交网络PHP源码

ColibriSM&#xff1a;当代社交网络平台的崛起 一、开篇与概述 在信息时代的浪潮中&#xff0c;社交媒体成为了人们日常生活中不可或缺的一部分。ColibriSM&#xff0c;作为一个仿照脸书&#xff08;Facebook&#xff09;、推特&#xff08;Twitter&#xff09;和照片墙&#…

WPF 新手指引弹窗

新手指引弹窗介绍 我们在第一次使用某个软件时&#xff0c;通常会有一个“新手指引”教学引导。WPF实现“新手指引”非常方便&#xff0c;且非常有趣。接下来我们就开始制作一个简单的”新手指引”(代码简单易懂&#xff0c;便于移植)&#xff0c;引用到我们的项目中又可添加一…

Windows电脑引导损坏?按照这个教程能修复

前言 Windows系统的引导一般情况下是不会坏的&#xff0c;小伙伴们可以不用担心。发布这个帖子是因为要给接下来的文章做点铺垫。 关注小白很久的小伙伴应该都知道&#xff0c;小白的文章都讲得比较细。而且文章与文章之间的关联度其实还是蛮高的。在文章中&#xff0c;你会遇…

使用uni-app editor富文本组件设置富文本内容及解决@Ready先于onload执行,无法获取后端接口数据的问题

开始使用富文本组件editor时&#xff0c;不知如何调用相关API设置富文本内容和获取内容&#xff0c;本文将举例详解 目录 一.了解editor组件的常用属性及相关API 1.属性常用说明 2.富文本相关API说明 1&#xff09;editorContext 2&#xff09; editorContext.setContents…

【Leetcode】第 378 场周赛

文章目录 100166. 检查按位或是否存在尾随零题目题意代码 100185. 找出出现至少三次的最长特殊子字符串 I题目思路代码 100184. 找出出现至少三次的最长特殊子字符串 II 100166. 检查按位或是否存在尾随零 题目 题意 这里题目要求的是或运算&#xff0c;所以原数组中只需要有…

LeetCode每日一题.04(不同路径)

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 示例 1…

Spring Cloud + Vue前后端分离-第10章 基于阿里云OSS的文件上传

源代码在GitHub - 629y/course: Spring Cloud Vue前后端分离-在线课程 Spring Cloud Vue前后端分离-第10章 基于阿里云OSS的文件上传 前面介绍的文件上传是基于本地文件服务器的文件上传&#xff0c;但是自己搭文件服务器会有很多运维的问题&#xff0c;比如磁盘满了要扩容…

Spark SQL简介与基本用法

Apache Spark是一个强大的分布式计算框架&#xff0c;Spark SQL是其组件之一&#xff0c;用于处理结构化数据。Spark SQL可以使用SQL查询语言来查询和分析数据&#xff0c;同时还提供了与Spark核心API的无缝集成。本文将深入探讨Spark SQL的基本概念和用法&#xff0c;包括数据…

Flink Job 执行流程

Flink On Yarn 模式 ​ 基于Yarn层面的架构类似 Spark on Yarn模式&#xff0c;都是由Client提交App到RM上面去运行&#xff0c;然后 RM分配第一个container去运行AM&#xff0c;然后由AM去负责资源的监督和管理。需要说明的是&#xff0c;Flink的Yarn模式更加类似Spark on Ya…

mysql间隙锁demo分析

概述 通常用的mysql都是innodb引擎&#xff1b; 一般在update的时候用id都会认为是给行记录加锁&#xff1b; 在使用非唯一索引更新时&#xff0c;会遇到临键锁&#xff08;范围锁&#xff09;&#xff1b; 临键锁和表中的数据有关&#xff1b; mysq版本:8 隔离级别&#xf…

jmeter的常用功能及在测试中的基本使用和压测实战

Jmeter基础功能 了解Jmeter的常用组件 元件&#xff1a;多个类似功能组件的容器&#xff08;类似于类&#xff09; 一&#xff1a;Test Plan&#xff08;测试计划&#xff09; 测试计划通常用来给测试的项目重命名&#xff0c;使用多线程脚本运行时还可以配置线程组运行方式…

【C++】STL 容器 - map 关联容器 ① ( std::map 容器简介 | std::map 容器排序规则 | std::map 容器底层实现 )

文章目录 一、std::map 容器1、std::map 容器简介2、std::map 容器排序规则3、std::map 容器底层实现 二、代码示例 - std::map 容器1、代码示例2、执行结果 一、std::map 容器 1、std::map 容器简介 std::map 容器 是 C 语言 标准模板库 ( STL , Standard Template Library ) …

分布式技术之数据复制技术

文章目录 什么是数据复制技术&#xff1f;数据复制技术原理及应用同步复制技术原理及应用异步复制技术原理及应用半同步复制技术原理及应用三种数据复制技术对比 什么是数据复制技术&#xff1f; 数据复制是一种实现数据备份的技术。数据复制技术&#xff0c;可以保证存储在不…

Plantuml之甘特图语法介绍(二十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

磁盘和文件系统管理

一&#xff1a;磁盘结构&#xff1a; 1.磁盘基础&#xff1a; 扇区固定大小&#xff0c;每个扇区4k。磁盘会进行磨损&#xff0c;损失生命周期。 设备文件&#xff1a; 一切皆文件 设备文件&#xff1a;关联至一个设备驱动程序&#xff0c;进而能够跟与之对应硬件设备进行通…

Rust学习笔记000 安装

安装命令 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh $ curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh info: downloading installerWelcome to Rust!This will download and install the official compiler for the Rust programming la…

【基础】【Python网络爬虫】【3.chrome 开发者工具】(详细笔记)

Python网络爬虫基础 chrome 开发者工具元素面板&#xff08;Elements)控制台面板&#xff08;Console&#xff09;资源面板&#xff08;Source&#xff09;网络面板&#xff08;Network&#xff09;工具栏Requests Table详情 chrome 开发者工具 ​ 当我们爬取不同的网站是&…

javaWeb学生信息管理系统2

一、学生信息管理系统SIMS 一款基于纯Servlet技术开发的学生信息管理系统&#xff08;SIMS&#xff09;&#xff0c;在设计中没有采用SpringMVC和Spring Boot等框架。系统完全依赖于Servlet来处理HTTP请求和管理学生信息&#xff0c;实现了信息的有效存储、检索和更新&#xf…