Mysql中的分库分表

mysql中的分库分表
分库:减少并发问题
分表:降低了分布式事务
分表
1、垂直分表
把其中的不常用的基础信息提取出来,放到一个表中通过id进行关联。
降低表的大小来控制性能,但是这种方式没有解决高数据量带来的性能损耗。
优点
1、拆分后业务清楚,达到专库专用。
2、可以实现热数据和冷数据的分离,将不经常变化的数据和变动较大的数据分散到不同的
库/表里面。
3、便于维护。
缺点
1、不能解决数据量大带来的性能损耗,读写的压力依旧很大。
2、不同的业务不能夸库关联,只能通过业务关联。
2、水平分表
以某个字段按照一定的规则将一个表数据分到多个表中
优点
1、单表的数据量减少了,提高性能。
2、提高了系统的稳定性和负载能力。
3、切分出来的表结构相同,程序改动的少。
缺点
1、拆分规则较难抽象。
2、数据分片在扩容是需要迁移
3、维护量增大
4、依然存在跨库无法join等问题,同时涉及分布式事物,数据一致性问题。
分库策略
hash取模 通过一个表中的字段进行散列
range 范围区分 (比如:时间,地区....)
list 预定义 (步长区分
分库分表需要解决的问题
1、事物问题
解决事物问题有两种可行的规方案分布式事物和通过应用程序与数据库共同控制实现
1、使用分布式事物
优点:交给数据库管理,简单有效
缺点:性能代价高,特别是shard越来越多时
2、应用程序和数据库共同控制
原理:将一个跨多个数据库的分布式事物分拆成多个仅处于单个数据上面的小事物,并通过
应用程序来总控各个小事物。
优点:性能上有优势。
缺点:需要应用程序在事物控制上做灵活的设计。
2、跨节点JOIN问题
只要进行切分,跨节点JOIN是不可避免的。解决这一问题的普遍做法两次查询实现。在第
一次查询的结果集中找出关联数据的ID,根据这些ID发起第二次请求得到关联的数据。
3、跨界店的count.order by,group by聚合函数的问题
这是一类问题,因为他们都需要基于全部数据集进行计算。解决方案:与跨界店IOIN问题
类似,分别在各个节点得到结果后再用用程序端进行合并。和JOIN不同的是每个节点的查
询可以并行执行,因此很多时候它的速度比单一大表快很多。结果集很大,对应用程序的内
存消耗是一个问题。
4、数据迁移,容量规划,扩容等问题
来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的
数对2取余也是1)来分配数据,避免了行级别数据的迁移,但是依然需要进行表级别的迁
移,同时对于扩容规模和分别数量都有限制。总体上,这些方案都不是十分的理想,多多少
少存在一些缺点,同时反映了Sharding扩容的难度。
5、事物
优点
1、基于两阶段提交,最大限度保证跨库数据库操作的“原子性”,是分布式系统下最严谨
的事物实现方式。
2、实现简单,工作量小。由于多数应用服务器以及一些独立的分布式事物协调器做出了大
量的封装工作,使得项目引入分布式事物的难度和工作量基本上可以忽略不计。
缺点
系统伸缩的死敌。基于两阶段提交的分布式事物在提交事物时需要进行多个节点之间的协
调,最大限度的退后了事物的时间点,客观上延迟了事物的执行时间,会导致事物访问共享
资源时发生冲突和死锁的概率增高,随着数据库节点的增加,这种趋势会越来越严重,从而
成为系统在数据层面上水平伸缩的“枷锁”。
事物补偿(幂等值)
对那些对性能要求很高,但对一致性要求并不高的系统。往往并不苟求系统的实时一致性,
只要在一个允许的时间周期内达到最终一致性即可,这使得事物补偿机制成为一种方案。事
物补偿机制最初被提出是在“长事物”的处理中,单对于分布式系统确保一致性很有很好的
参考意义。笼统的讲,与事物在执行过程中发生错误立即回滚的方式不同,事物补偿性是一
种事后检查并补救的措施,它只期望在一个容许的时间周期内得到最终一致的结果就可以
了。事物补偿是实现与系统业务紧密相关,并没有一种标准的处理方案。一些常见的实现方
式:对数据进行对账检查,基于日志进行对比,定期同标准数据来源进行同步。。。
6、ID问题
一旦数据被切分到多个物理节点上,我么将不再依赖数据库自身的主键生成机制。一方面,
每个分区数据库生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前
需要获取ID,以便SQL路由。
UUID
使用UUID作为主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除
占用大量的存储空间,最主要的问题在索引上,在建立索引和基于索引进行查询时存在性能
问题。
结合数据库维护一个Sequence表
此方案简单,在数据库中建立一个Sequence表
CREATE TABLE `SEQUENCE` (
`table_name` varchar(18) NOT NULL,
`nextid` bigint(20) NOT NULL,
PRIMARY KEY (`table_name`)
) ENGINE=InnoDB
每当需要为某个表新纪录生成ID是就从Sequence表中取出对应表的nextid,并将nextid的值
加1更新到数据库中一以备下次使用。此方法简单,但是缺点明显,由于所有插入任何都需
要访问该表,该表很容易成为系统的性能瓶颈,同时也存在单点的问题,一旦还数据库失
效,整个应用程序将无法工作。有人提出用Master-Slave进行主从同步,但是也只能解决
单点问题,并不能解决读写1:1的访问压力问题。
Twitter的分布式自增ID算法Snowflake
在分布式系统中吗,需要生成全局的UID的场合还是蛮多的,twitter的snowfake解决了这
种需要,实现也是很简单的,除去配置信息,核心代码就是毫秒级时间41位 机器ID 10位
毫秒内序列12位。
* 10---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 --
-000000000000
在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为
毫秒级时间,然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标
识),然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由
datacenter和机器ID作区分),并且效率较高,经测试,snowflake每秒能够产生26万ID
左右,完全满足需要。
7、跨分片的排序分页
一般来说,分页的时候需要按照指定的字段进行排序。当排序字段就是分片字段的时候,我
们通过分片规则可以较为容易的定位到指定的分片,而当排序字段非分片字段的时候,情况
就复杂了。为了结果的准确性,我们需要在不通的分片节点将数据进行排序并返回,将不通
分片返回的结果集进行汇总和再次排序。最后返回给用户。
上面描述的是最简单的一种情况(去第一页的数据),看起来对性能的影响不大。但是,如
果取出第10也数据,情况就复杂很多了。
为什么不取10条,而是把前10页的数据全部取出来了呢?其实也不难理解,因为个节点的
数据可能是随机的,为了排序的准确性,必须把所有分片节点前的前N也数据都拍好序后做
合并,最终进行整体的排序。很显然这样的操作是很消耗性能的,用户越往后翻,性能就会
越差。
那么如何解决呢?
1、如果是前台提供分页。则限定用户只能看前面n页,这个限定在业务上也是合情合理
的,一般看后面的分页的意义不大(如果一定要看,可以要求用户缩小范围重新查询)
2、如果是后台批处理任务要求分批获取数据,则可以加大page size,比如每次获取5000
条记录,有效减少分页(当然离线访问一般走备库,避免冲击主库)
3、可以借助大数据平台
8、分库策略
分库维度确定后,如何把记录分到各个库中呢
1、根据数值范围,比如ID为1-9999到第一个库,10000-20000的到第二个库
2、根据数值取模,比如ID mod n,余数为0的记录到第一个库中,为1的记录到第二个库
中。
9、分库数量
分库数量首先和单库处理的记录数有关,一般来说MySQL单库超过5000万条记录,Oracle
超过1亿条记录,DB压力就很大(当然还跟数据表中记录有关系)
在满足上述前提下,如果分库的数量少了,达不到分散存储和减轻DB性能压力的目的;如
果分库的数量多,好处是每个库的记录少,单库访问性能好,但对于跨多个库的访问,应用
程序需要访问多个库,如果并发模式,要消耗宝贵的线程资源;如果串行模式,执行时间会
急剧增加。
分库的数量影响硬件的投入,一般每个分库泡在单独的物理机上面,多一个意味着多一台设
备。一般建议分4-8个库。
10、路由透明
分库从某种意义上,意味着DB schema改变了,必然影响应用,但这种改变和业务无关,
所以要尽量保证分库对应用代码透明,分库逻辑尽量在数据访问层处理。当然完全做到这一
点很困难,具体哪些应该由DAL负责,哪些由应用负责,这里有一些建议:
对于单库访问,比如查询条件指定用户Id,则该SQL只需访问特定库。此时应该由DAL层自
动路由到特定库,当库二次分裂时,也只要修改mod 因子,应用代码不受影响。
对于简单的多库查询,DAL负责汇总各个数据库返回的记录,此时仍对上层应用透明。

原文地址:https://www.cnblogs.com/ricklz/p/10982292.html

时间: 2024-10-13 11:28:19

Mysql中的分库分表的相关文章

MySQL纯透明的分库分表技术还没有

MySQL纯透明的分库分表技术还没有 种树人./oneproxy --proxy-address=:3307 --admin-username=admin --admin-password=D033E22AE348AEB5660FC2140AEC35850C4DA997 --proxy-master-addresses=172.16.132.87:[email protected] --proxy-master-addresses=172.16.3.92:[email protected] --

mysql主从同步分库分表同步

一.mysql数据库的安装 分别在master 和slave上源码安装mysql数据库 1.1 安装相关包1.1.1 cmake软件cd /home/oldboy/tools/tar xf cmake-2.8.8.tar.gzcd cmake-2.8.8./configure#CMake has bootstrapped.  Now run gmake.gmakegmake installcd ../ 1.1.2 依赖包yum install ncurses-devel -y 1.2 开始安装m

MYSQL数据切分(分库分表),读写分离和主从复制

参考1 参考2 对于一个大型的互联网应用,每天几十亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的问题.通过数据切分来提高网站性能,横向扩展数据层已经成为架构研发人员首选的方式. 数据切分:可以降低单台机器的负载,同时最大限度的降低了宕机造成的损失: 负载均衡策略:可以降低单台机器的访问负载,降低宕机的可能性: 集群方案:解决了数据库宕机带来的单点数据库不能访问的问题: 读写分离策略:最大限度了提高了应用中读取数据的速度和并发量: 这里主要谈及数据切分和其相关数据库优

MySQL如何实现分库分表,如何提高查询效率

本人没有做过电商平台,但了解其中的道道,今天闲来无事,说说其中的道道.下边我要开始表演了. 在大型电商网站中,随着业务的增多,数据库中的数据量也是与日俱增,这时候就要将数据库进行分库分表了. 1.如何分库分表? 两种解决方案:垂直拆分.水平拆分 垂直拆分:根据业务进行拆分,比如可以将一张表中的多个字段拆成两张表,一张是不经常更改的,一张是经常改的. 水平拆分:即根据表来进行分割:比如user表可以拆分为user0,.user1.user2.user3.user4等 2.分库分表之后如何实现联合查

分布式中的分库分表之后,ID 主键如何处理?

面试题 分库分表之后,id 主键如何处理?(唯一性,排序等) 面试官心理分析 其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定不对啊,需要一个全局唯一的 id 来支持,排序问题等.所以这都是你实际生产环境中必须考虑的问题. 面试题剖析 基于数据库的实现方案 数据库自增 id 这个就是说你的系统里每次得到一个 id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个 id.拿到这个 id 之后再

MyCat:对MySQL数据库进行分库分表

本篇前提: mycat配置正确,且能正常启动. 1.schema.xml <table>标签: dataNode -- 分片节点指定(取值:dataNode中的name属性值)rule ------ 分片规则选择(取值:rule标签中的name属性值) 1 2 3 [[email protected] conf]# vim schema.xml 1 <?xml version="1.0"?> 2 <!DOCTYPE mycat:schema SYSTEM

mysql分库分表总结

单库单表 单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到. 单库多表 随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能.如果使用mysql, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有的读写操作只能等待. 可以通过某种方式将user进行水平的切分,产生两个表结构完全一样的user_0000,user_0001等

【分库、分表】MySQL分库分表方案

一.Mysql分库分表方案 1.为什么要分表: 当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间. mysql中有一种机制是表锁定和行锁定,是为了保证数据的完整性.表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行.行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作. 2. mysql proxy:amoeba 做mysql集群,利用amoeba. 从上层的ja

Shell脚步之MySql分库分表备份

前言 数据备份的重要性已经不用过多强调了.这篇文章我们就以MySQL数据进行演示如何通过Shell脚步进行MySQL数据库的分库分表备份. 要求 Linux命令要求比较熟悉,Shell脚步语法规则也要熟悉,MySQL的数据库备份命令要比较熟悉.下面也会提到,如果有不懂得希望可以自行查阅资料学习. 命令窗口查询MySQL数据库列表 上面我们就通过Linux命令窗口查询到了MySQL的数据库列表 去除MySQL自带数据库获取目标业务数据库列表,查看表列表 备注:通过过滤掉MySQL自带数据库,那么就