- 浏览: 1146621 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (138)
- JAVA基础 (22)
- Spring (6)
- 设计模式 (2)
- JDK源码 (3)
- java-功能组件 (4)
- 游戏项目 (2)
- linux (13)
- Oracle (2)
- struts (1)
- 字符集 (8)
- HTTP协议 (2)
- java-网络通信 (1)
- 工具软件推荐 (2)
- tomcat (1)
- java-容器框架 (2)
- java-IO框架 (2)
- java-多线程框架 (4)
- java-NIO框架 (0)
- jquery (2)
- 工具使用 (12)
- 加密解密 (1)
- redis (2)
- maven (2)
- svn (1)
- eclipse (1)
- mysql (11)
- 我的收藏 (1)
- JAVA进阶 (26)
- 运维 (3)
- protocol buffer (1)
- 优秀博主 (1)
- nginx (1)
- 算法 (2)
- 故障排查 (4)
- 粤语歌曲 (6)
- 生活总结 (6)
- 高并发 (4)
- 语言训练 (1)
- 读书笔记 (5)
- 诗歌 (1)
- tomcat源码学习 (1)
- 软件词汇 (1)
- git (1)
最新评论
-
ryuhi:
一个是来源source,一个是来源方序列号seq这两个数据要怎 ...
高并发的核心技术-幂等的实现方案 -
xuezhongyu01:
无量 写道Master-Gao 写道理论感觉还行,可以代码我还 ...
高并发的核心技术-幂等的实现方案 -
无量:
Master-Gao 写道理论感觉还行,可以代码我还是不会写。 ...
高并发的核心技术-幂等的实现方案 -
phil_jing:
@RequestParam 默认 true
SpringMVC注解@RequestParam全面解析 -
aguai0:
aguai0 写道第五条里的如果要获取任务执行结果,用Comp ...
JAVA进阶----ThreadPoolExecutor机制
海量数据存储--分库分表策略详解
一、背景:
系统刚开始的时候,数据库都是单库单表结构。随着业务量的增加进行第一次数据库升级,根据业务垂直拆分数据库,这样多变成多个业务数据库,每个数据库里面还是单表结构。接下来,继续随着业务量的继续增加,单表已经很难承受数据量,就要进行分表,这个时候就是,多个业务库,每个业务库下对需要分表的表进行分表。再接下来,随着应用的增加,数据库IO,磁盘等等都抗不住了,就要把分表的表分到多个库,这样就形成了如下的结构。
重点:本文主要讨论的是分库分表的策略,也就是分库分表的规则或者说是算法。
二、分库分表的依据--分库分表字段的选择
分库分表首先要确定根据哪个字段、或者哪几个字段进行路由,一般的原则是按使用频率最高维度的字段去分库分表,尽量保证高使用维度下只查询单表。
常用的字段有主键ID,用户ID,时间,商户ID,产品ID,业务类型等等
三、分库分表策略
主要原理:分区、取模、数据路由表
1. 按照时间区间
1)基本原理:
一定区间内时间产生的数据放到一张表里面,多个时间区间的表放到一个库里面
2)简单例子:
单库多表结构,按月分表可以这样,user_201601,user_201602,...,user_201612这种结构。按年分表可以这样,user_2016,user_2017,...这种。
3)多库多表算法:
比如按天分表,每天一张表,当单库超过100张表的时候,进行分库到下一张表。那么假如第一张报表在库BD0,表名是user_20160201。从DB0.user_20160201,..到DB0.user_20160511就100张表了,接下来就要进行分库了,进入20160512,就是DB1.user_20160512,这个算法就是上线的时候定一个上线日期,具体算法如下
库ID = (当前日期 - 上线日期)/ 100
表ID = user_yyyyMMdd
注:好处是可以直接根据时间经过简单计算定位到哪个库和哪个表
还有一种算法:
库ID = (当前日期 - 上线日期)/ 100
表ID = (当前日期 - 上线日期) % 100
表名如下: DB0.user_0001, user_0002,....,user_01000。
注:表名和库名都要经过计算,比较麻烦
4)按月分表,每个月一张表;这种情况,一般就不用分库了,一年12张表说明量也不会特别大,如果量特别大,或者是热点数据,可以一年分一个库,具体算法和上面差不多。
5)按季度分表,基本不用分库。
6)按年分表,肯定不用分库了,没有必要了。
2. 按照主键ID区间
对于自增的主键ID,可以按照ID区间进行分表,以1000万数据量为分界线,对线性的ID进行切割分表,每涨到1000万数据,分到下一张表,超过一定数目的表,进行分库。
库ID = 主键ID / 1000万 / 100
表ID = 主键ID / 1000万 % 100
如:DB0.user_0000,...,DB0.user_0099, DB1.user_0000,...,DB1.user_0099
3. 按照指定字段hash后再取模
如果要取模的字段不是整数型,要先hash后,再通过取模算法,算出在哪个库和那个表。具体算法,参照下面的按用户ID取模。
4. 按照用户ID取模
这里把按照用户ID取模单独拎出来,因为就使用而言,是使用场景最多的情况,很多时候都是用户相关数据量最大,需要分库分表,查询维度更多也是按照用户来查询,所以对用户取模,让同一个用户的数据落到一张表里面,再好不过了。
案例:假设用户ID是整数型的。库数量要分4库,每个库表数量8表,一共32张表。
原理讲解:
一共要分4库,8表,共32张表,也就是1到32的用户ID要平均分配到每张表应该有一条数据,这样就有两种分法。
1) 1到8是第一个库,9到16第二个库,17到24第三个库,25到32是第四个库,每个库里面表的编号都是0到3,这个原则是一个库里面一个一个分,分完再下一个库一个一个分,保证不重复,不漏掉。
2)1,5,9这样每隔4个一个库,2开头隔4个一个库,这个原则是一个库分一个,在分下一个库,一圈走完,再在第一库没分到的表继续分,也保证了不重复,不漏掉原则。
库ID = userId % 库数量4
表ID = userId / 库数量4 % 表数量8
或者
库ID = userId / 表数量4 % 库数量4
表ID = userId % 表数量8
算法图示如下:
5. 数据路由表
如果分库分表的算法很复杂,可以通过路由表+程序算法,来存储和计算分库分表规则,不过一般不建议,分库分表搞得太复杂,不便于维护和查询问题
四、各个方案对比
分区算法
优点:线性扩容,平滑扩容,不需要数据迁移
缺点:存在热点数据,非时间维度查询多的情况,聚合复杂
建议:冷数据,用户维度查询少,且数据量大的情况用分区算法
取模算法
优点:同一个热点的数据可以做到一个表里面,查询方便
缺点:扩容不是很方便,需要数据迁移
建议:用户维度查询多,热点维度查询多的情况,建议使用
注:
分库分表的核心是未来数据量的预估,根据预估和实际使用情况来确定分库分表方案,一般像订单类数据以用户维度取模分表最好,商品数据以商户取模最好,签到等活动流水数据时间分区最好。
取模方案扩容的解决:一、可以提前按照预估方案创建库和表,前期放到一个DB,后期迁移,或者一次性弄好 二、可以按照预估的方案去确定分库和分表的后缀ID,但是前期只创建一部分库和表。例如:最终4库,每个库16个表。后缀应该是0000----0315共64个表的后缀,前期可以一个库,4个表,也就是所有数据都在这个四张表里面。
0000--0003-----》0000表
0100--0103-----》0000表
0200--0203-----》0000表
0300--0303-----》0000表
0004--0007-----》0004表
0104--0107-----》0004表
0204--0207-----》0004表
0304--0307-----》0004表
0008--0011-----》0008表
0108--0111-----》0008表
0208--0211-----》0008表
0308--0311-----》0008表
0012--0015-----》0012表
0112--0115-----》0012表
0212--0215-----》0012表
0312--0315-----》0012表
后续可以二分法,迁移数据,扩容。
欢迎大家关注我的公众号:
一、背景:
系统刚开始的时候,数据库都是单库单表结构。随着业务量的增加进行第一次数据库升级,根据业务垂直拆分数据库,这样多变成多个业务数据库,每个数据库里面还是单表结构。接下来,继续随着业务量的继续增加,单表已经很难承受数据量,就要进行分表,这个时候就是,多个业务库,每个业务库下对需要分表的表进行分表。再接下来,随着应用的增加,数据库IO,磁盘等等都抗不住了,就要把分表的表分到多个库,这样就形成了如下的结构。
重点:本文主要讨论的是分库分表的策略,也就是分库分表的规则或者说是算法。
二、分库分表的依据--分库分表字段的选择
分库分表首先要确定根据哪个字段、或者哪几个字段进行路由,一般的原则是按使用频率最高维度的字段去分库分表,尽量保证高使用维度下只查询单表。
常用的字段有主键ID,用户ID,时间,商户ID,产品ID,业务类型等等
三、分库分表策略
主要原理:分区、取模、数据路由表
1. 按照时间区间
1)基本原理:
一定区间内时间产生的数据放到一张表里面,多个时间区间的表放到一个库里面
2)简单例子:
单库多表结构,按月分表可以这样,user_201601,user_201602,...,user_201612这种结构。按年分表可以这样,user_2016,user_2017,...这种。
3)多库多表算法:
比如按天分表,每天一张表,当单库超过100张表的时候,进行分库到下一张表。那么假如第一张报表在库BD0,表名是user_20160201。从DB0.user_20160201,..到DB0.user_20160511就100张表了,接下来就要进行分库了,进入20160512,就是DB1.user_20160512,这个算法就是上线的时候定一个上线日期,具体算法如下
库ID = (当前日期 - 上线日期)/ 100
表ID = user_yyyyMMdd
注:好处是可以直接根据时间经过简单计算定位到哪个库和哪个表
还有一种算法:
库ID = (当前日期 - 上线日期)/ 100
表ID = (当前日期 - 上线日期) % 100
表名如下: DB0.user_0001, user_0002,....,user_01000。
注:表名和库名都要经过计算,比较麻烦
4)按月分表,每个月一张表;这种情况,一般就不用分库了,一年12张表说明量也不会特别大,如果量特别大,或者是热点数据,可以一年分一个库,具体算法和上面差不多。
5)按季度分表,基本不用分库。
6)按年分表,肯定不用分库了,没有必要了。
2. 按照主键ID区间
对于自增的主键ID,可以按照ID区间进行分表,以1000万数据量为分界线,对线性的ID进行切割分表,每涨到1000万数据,分到下一张表,超过一定数目的表,进行分库。
库ID = 主键ID / 1000万 / 100
表ID = 主键ID / 1000万 % 100
如:DB0.user_0000,...,DB0.user_0099, DB1.user_0000,...,DB1.user_0099
3. 按照指定字段hash后再取模
如果要取模的字段不是整数型,要先hash后,再通过取模算法,算出在哪个库和那个表。具体算法,参照下面的按用户ID取模。
4. 按照用户ID取模
这里把按照用户ID取模单独拎出来,因为就使用而言,是使用场景最多的情况,很多时候都是用户相关数据量最大,需要分库分表,查询维度更多也是按照用户来查询,所以对用户取模,让同一个用户的数据落到一张表里面,再好不过了。
案例:假设用户ID是整数型的。库数量要分4库,每个库表数量8表,一共32张表。
原理讲解:
一共要分4库,8表,共32张表,也就是1到32的用户ID要平均分配到每张表应该有一条数据,这样就有两种分法。
1) 1到8是第一个库,9到16第二个库,17到24第三个库,25到32是第四个库,每个库里面表的编号都是0到3,这个原则是一个库里面一个一个分,分完再下一个库一个一个分,保证不重复,不漏掉。
2)1,5,9这样每隔4个一个库,2开头隔4个一个库,这个原则是一个库分一个,在分下一个库,一圈走完,再在第一库没分到的表继续分,也保证了不重复,不漏掉原则。
库ID = userId % 库数量4
表ID = userId / 库数量4 % 表数量8
或者
库ID = userId / 表数量4 % 库数量4
表ID = userId % 表数量8
算法图示如下:
5. 数据路由表
如果分库分表的算法很复杂,可以通过路由表+程序算法,来存储和计算分库分表规则,不过一般不建议,分库分表搞得太复杂,不便于维护和查询问题
四、各个方案对比
分区算法
优点:线性扩容,平滑扩容,不需要数据迁移
缺点:存在热点数据,非时间维度查询多的情况,聚合复杂
建议:冷数据,用户维度查询少,且数据量大的情况用分区算法
取模算法
优点:同一个热点的数据可以做到一个表里面,查询方便
缺点:扩容不是很方便,需要数据迁移
建议:用户维度查询多,热点维度查询多的情况,建议使用
注:
分库分表的核心是未来数据量的预估,根据预估和实际使用情况来确定分库分表方案,一般像订单类数据以用户维度取模分表最好,商品数据以商户取模最好,签到等活动流水数据时间分区最好。
取模方案扩容的解决:一、可以提前按照预估方案创建库和表,前期放到一个DB,后期迁移,或者一次性弄好 二、可以按照预估的方案去确定分库和分表的后缀ID,但是前期只创建一部分库和表。例如:最终4库,每个库16个表。后缀应该是0000----0315共64个表的后缀,前期可以一个库,4个表,也就是所有数据都在这个四张表里面。
0000--0003-----》0000表
0100--0103-----》0000表
0200--0203-----》0000表
0300--0303-----》0000表
0004--0007-----》0004表
0104--0107-----》0004表
0204--0207-----》0004表
0304--0307-----》0004表
0008--0011-----》0008表
0108--0111-----》0008表
0208--0211-----》0008表
0308--0311-----》0008表
0012--0015-----》0012表
0112--0115-----》0012表
0212--0215-----》0012表
0312--0315-----》0012表
后续可以二分法,迁移数据,扩容。
欢迎大家关注我的公众号:
发表评论
-
区块链!每个人都要了解下--十分钟洞见区块链的前世今生
2018-04-27 12:32 799区块链!每个人都要了解下--十分钟洞见区块链的前世今生 ... -
区块链!每个人都要了解下--十分钟洞见区块链的前世今生
2018-04-27 12:09 0为啥要讲区块链呢,因为它太火了,火到什么程度呢 ... -
项目打包,报软件包、类不存在问题排查过程
2017-05-16 17:13 5978项目打包报,软件包、类不存在问题排查过程 一、背景 ... -
jstack详解
2017-02-17 11:15 1915jstack http://www.open-open.co ... -
jdk-源码中的一些坑
2017-02-13 15:17 1233jdk-源码中的一些坑 1. Runnable接口的命名简直 ... -
一次mysql死锁的排查过程
2016-11-21 10:04 11324一次mysql死锁的排查过程 一、背景 17号晚上要吃饭 ... -
JVM调优:选择合适的GC collector (三)
2016-11-15 20:51 1271CMS Collector 在很多地方,CMS Collec ... -
JVM调优:选择合适的GC collector (二)
2016-11-15 20:47 995http://blog.csdn.net/historya ... -
JVM调优:选择合适的GC collector (一)
2016-11-15 20:45 1273http://blog.csdn.net/historyas ... -
jstat查看gc情况
2016-11-10 10:11 2494jps(Java Virtual Machine Proces ... -
tomcat源码学习(一) eclipse导入tomcat源码
2016-10-31 20:05 14051. 到官网下载Tomcat源代码,这里用到的是apache- ... -
深入分析ClassLoader
2016-10-27 23:27 782转(原文http://blog.csdn.net/xya ... -
业务架构模板
2016-10-20 19:56 1885业务架构模板 默认一个高大上的业务系统需要具备的技术点和对应 ... -
如何写一个强壮的JOB任务
2016-10-18 15:00 3014如何写一个强壮的JOB任务 1. JOB跑一半断电了,不能产 ... -
mybatis.xml中sql编写规范
2016-10-18 14:54 6259一、越少的代码,越强悍的功能,xml里面应该6个sql语句就够 ... -
数据库设计规范
2016-10-17 23:29 65801. 数据库设计基本规范 领域驱动表内容 ... -
全局主键生成器-支持单JVM1秒近1000万订单生成
2016-05-03 20:46 5676全局主键生成器 介绍: 相对于DB自增序列的全局主键生成器, ... -
解决并发下累计的问题
2016-04-25 11:58 2126package com.tongbanjie.trade.te ... -
系统开发中的坑
2016-03-15 15:39 2800系统开发中的坑 这个是在公司分享的一个ppt,整理下发到博客里 ... -
系统开发中的坑
2016-03-14 15:55 193系统开发的坑 一.幂等性 二.数据库 三.代码 ...
相关推荐
CDR分库分表主要针对大型通信运营商在处理海量话单数据时所面临的问题。由于传统的单库单表结构无法有效支撑如此庞大的数据量,因此引入了分库分表机制来优化话单数据的存储与查询性能。 #### 三、关键技术点解析 ...
### 读写分离和分库分表详解 随着互联网应用的发展,海量数据处理与高并发访问成为了许多系统面临的主要挑战之一。为了应对这些挑战,多种技术手段被提出并广泛应用于实践中,其中“读写分离”与“分库分表”是两种...
阿里巴巴在面对海量数据时采用分库分表策略,以应对高QPS、带宽压力和数据库连接数限制。例如,通过时间算法分库分表,可以按天/月/年划分数据,简化查询定位。在扩展时,可以通过调整计算规则来平滑地增加新的库表...
随着业务量的增长,单一数据库往往难以承受高并发访问和海量数据的压力,这时就需要采用分库分表策略来分散负载。Mybatis-Mate 支持这一策略,通过将大型数据库拆分成多个小型数据库和表格,实现了数据的水平扩展,...
**分库分表解决方案——ShardingSphere-JDBC详解** 在当今大数据时代,单个数据库往往无法满足高并发、海量数据的存储与处理需求。为了解决这个问题,分库分表成为了一个常用的技术策略。ShardingSphere-JDBC作为一...
Mycat作为一款开源的分布式数据库中间件,被广泛应用于大型网站和企业的数据分库分表解决方案中,以解决单个数据库无法承载高并发和海量数据的问题。本文将详细讲解Mycat 2如何进行分库分表,并结合提供的SQL测试...
使用MySQL作为读库,支持数据切分、分库分表等策略,以减轻单个数据库的压力。读库通过内存缓存机制显著提升查询性能。 - **水平拆分**:适用于核心业务数据量过大、无法短时间内完成迁移的情况。采用异构数据库读写...
2. 社交网络:处理海量的用户消息、好友关系等数据,利用Mycat进行分库分表,提高查询效率。 3. 金融系统:保障交易数据的高可用性和一致性,通过Mycat实现故障快速切换。 总结,Mycat-Server1.5是应对大数据挑战...
Mycat的核心功能在于实现数据库的水平扩展,通过分库分表策略,将大量数据分散到多个数据库实例上,以降低单个数据库的压力,提升整体系统的处理能力。同时,Mycat还支持数据库的读写分离,提高系统的并发性能,满足...
总结,Mycat作为一款优秀的分布式数据库中间件,凭借其强大的分库分表、读写分离、数据一致性保证等功能,成为了大数据时代企业应对高并发、海量数据挑战的重要工具。深入理解和掌握Mycat的使用,对于提升系统性能、...
- **分库分表与水平拆分**:随着数据量进一步增长,单一数据库的处理能力达到极限,因此采取了分库分表和水平拆分等策略来分散负载。 - **NoSQL数据库的出现**:进入21世纪,特别是2010年以后,Web 2.0的兴起使得...
Mycat 是一款基于 MySQL 协议的开源分布式数据库中间件,它实现了数据库的分库分表功能,有效地解决了大数据量下的高性能读写问题。在这个最新版的 Linux Mycat-server-1.6.7.5-release-20200410174409-linux.tar.gz...
- 面对100亿级别的数据量和1万属性的复杂性,58同城通过数据分库分表、字段合并等手段,有效地解决了存储和查询性能问题。同时,通过合理的索引策略和数据分区,提高了查询效率,确保了系统的稳定运行。 总结来说...
在大数据时代,单个数据库往往无法满足海量数据的存储和处理需求,因此需要将数据分散到多个数据库或表中,这就是分库分表的基本思想。Mycat通过路由规则,将用户的SQL请求智能地分发到不同的数据库和表上,实现数据...
TDDL(Table Data Layer)是淘宝开源的数据库中间件,主要用于解决数据库的分库分表问题。TDDL提供了动态数据路由、读写分离、故障切换等功能,它通过配置定义数据的分布策略,使得应用程序无需关心数据的具体存储...
总结起来,Zebra作为团点评集团的MySQL数据库访问层中间件,通过提供透明化的接口、智能的读写分离策略、灵活的分库分表以及完善的监控体系,有效地解决了大规模数据处理的问题,提高了系统的稳定性和效率。...
- **分表分库**:将数据分布在不同的表或不同的数据库中,降低单表的访问压力。 - **水平拆分**:按业务逻辑或数据范围将数据分割到不同数据库。 - **MySQL集群**:利用MySQL Cluster实现数据的分布式存储和计算...
- **分库分表**:这是DRDS中的一个重要概念,指的是将原有的大型数据库分解成多个较小的数据库或表,以减轻单个数据库的压力。DRDS提供了多种拆分策略,包括哈希(Hash)、范围(Range)、列表(List)等,以适应...