001---mysql分库分表

mysql分库分表

一、整体的切分方式

1、分库分表即数据的切分就是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果

2、数据的切分根据其切分规则的类型,可以分为如下两种切分模式

【1】垂直(纵向)切分:把单一的表拆分成多个表 / 将不相关的表,分散到不同的数据库(主机)上。

如:用户表、商品SKU表、交易Pay表,根据业务不同进行切分,将表切分到不同数据库上。

优点:

(1)。拆分后业务清晰,拆分规则明确

(2)。系统之间进行整合或扩展很容易

(3)。按照成本、应用的等级、应用的类型等将表放到不同的机器上,便于管理

(4)。便于实现动静分离、冷热分离的数据库表的设计模式

冷热分离:冷数据(查询多,变化少),热数据/活跃数据(变化多)。将冷热数据分开存放即冷热分离。

(5)。数据维护简单

缺点:

(1)。部分业务表无法关联(Join),只能通过接口方式解决,提高了系统的复杂度

(2)。受每种业务的不同限制,存在单库性能瓶颈,不易进行数据扩展和提升性能

(3)。事务处理复杂

设计数据库表结构时考虑因素:

(1)。冷数据适合MyISAM存储引擎(查询快) ,热数据适合InnoDB存储引擎(更新快)。

(2)。主从分离:主库用于写入操作,从库(可配置更多从库)用于查询操作,分担请求压力。

(3)。针对活跃/热数据,可采用Memcache、Redis等缓存,待累计一定量时再更新DB。

【2】水平(横向)切分:根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上。

如:用户表可根据ID被水平切分为用户1表 & 用户2表 (表结构一致),即用户表数据=用户1表数据+用户2表数据

优点:

(1)。单库单表的数据保持在一定的量级,有助于性能的提高。

(2)。切分的表的结构相同,应用层改造较少,只需要增加路由规则即可。

(3)。提高了系统的稳定性和负载能力。

缺点:

(1)。切分后,数据是分散的,很难利用数据库的Join操作,跨库Join性能较差

(2)。拆分规则难以抽象。

(3)。分片事务的一致性难以解决。

(4)。数据扩容的难度和维护量极大。

以上,水平/垂直切分共同点:

  • 存在分布式事务的问题。
  • 存在跨节点Join的问题。
  • 存在跨节点合并排序、分页的问题。
  • 存在多数据源管理的问题。

二、水平切分方式的路由过程和分片维度

1. 水平切分的路由过程

我们在设计表时需要确定对表按照什么样的规则进行分库分表。

例如,当有新用户时,程序得确定

(1)。将此用户的信息添加到哪个表中;

(2)。在登录时我们需要通过用户的账号找到数据库中对应的记录。

所有这些都需要按照某一规则进行路由请求因为请求所需要的数据分布在不同的分片表中

以上:针对输入的请求,通过分库分表规则查找到对应的表和库的过程叫作路由

例如:

分库分表的规则是user_id % 4,当用户新注册了一个账号时,假设用户的ID是123,我们就可以通过123 % 4 = 3确定此账号应该被保存在User3表中。

当ID为123的用户登录时,我们可通过123 % 4 = 3计算后,确定其被记录在User3中。

2. 水平切分的分片维度(可参考Myca提供的切片方式)

【1】按照哈希切片

哈希分片:对数据的某个字段求哈希,再除以分片总数后取模,取模后相同的数据为一个分片。

按照哈希分片常常应用于数据没有时效性的情况,比如所有数据无论是在什么时间产生的,都需要进行处理或者查询。

优点:数据切片比较均匀,对数据压力分散的效果较好。

缺点:数据分散后,对于查询需求需要进行聚合处理。

【2】按照时间切片

时间分片:按照时间的范围将数据分布到不同的分片上。(这种切片方式适用于有明显时间特点的数据)

三、分片后的事务处理机制

(一)、分布式事务

由于我们将单表的数据切片后存储在多个数据库甚至多个数据库实例中,所以依靠数据库本身的事务机制不能满足所有场景的需要。

但是,我们推荐在一个数据库实例中的操作尽可能使用本地事务来保证一致性,跨数据库实例的一系列更新操作需要根据事务路由在不同的数据源中完成,各个数据源之间的更新操作需要通过分布式事务处理

主流的分布式事务解决方案有三种:两阶段提交协议、最大努力保证模式和事务补偿机制。

1、两阶段提交协议

两阶段提交协议将分布式事务分为两个阶段,一个是准备阶段,一个是提交阶段,两个阶段都由事务管理器发起。

基于两阶段提交协议,事务管理器能够最大限度地保证跨数据库操作的事务的原子性,是分布式系统环境下最严格的事务实现方法。

符合J2EE规范的AppServer(例如:Websphere、Weblogic、Jboss等)对关系型数据库数据源和消息队列都实现了两阶段提交协议,只需在使用时配置即可

如图所示:

但是,两阶段提交协议也带来了性能方面的问题,难于进行水平伸缩,因为在提交事务的过程中,事务管理器需要和每个参与者进行准备和提交的操作的协调,在准备阶段锁定资源,在提交阶段消费资源。

但是由于参与者较多,锁定资源和消费资源之间的时间差被拉长,导致响应速度较慢,在此期间产生死锁或者不确定结果的可能性较大。因此,在互联网行业里,为了追求性能的提升,很少使用两阶段提交协议。

另外,由于两阶段提交协议是阻塞协议,在极端情况下不能快速响应请求方,因此有人提出了三阶段提交协议,解决了两阶段提交协议的阻塞问题,但仍然需要事务管理器在参与者之间协调,才能完成一个分布式事务。

2、最大努力保证模式

这是一种非常通用的保证分布式一致性的模式,很多开发人员一直在使用,但是并未意识到这是一种模式。最大努力保证模式适用于对一致性要求并不十分严格但是对性能要求较高的场景。

具体的实现方法是,在更新多个资源时,将多个资源的提交尽量延后到最后一刻处理,这样的话,如果业务流程出现问题,则所有的资源更新都可以回滚,事务仍然保持一致。

唯一可能出现问题的情况是在提交多个资源时发生了系统问题,比如网络问题等,但是这种情况是非常罕见的,一旦出现这种情况,就需要进行实时补偿,将已提交的事务进行回滚,这和我们常说的TCC模式有些类似。

下面是使用最大努力保证模式的一个样例,在该样例中涉及两个操作,一个是从消息队列消费消息,一个是更新数据库,需要保证分布式的一致性。

(1)开始消息事务。

(2)开始数据库事务。

(3)接收消息。

(4)更新数据库。

(5)提交数据库事务。

(6)提交消息事务。

这时,从第1步到第4步并不是很关键,关键的是第5步和第6步,需要将其放在最后一起提交,尽最大努力保证前面的业务处理的一致性。

到了第5步和第6步,业务逻辑处理完成,这时只可能发生系统错误,如果第5步失败,则可以将消息队列和数据库事务全部回滚,保持一致。如果第5步成功,第6步遇到了网络超时等问题,则这是唯一可能产生问题的情况。

在这种情况下,消息的消费过程并没有被提交到消息队列,消息队列可能会重新发送消息给其他消息处理服务,这会导致消息被重复消费,但是可以通过幂等处理来保证消除重复消息带来的影响。

当然,在使用这种模式时,我们要充分考虑每个资源的提交顺序。我们在生产实践中遇到的一种反模式,就是在数据库事务中嵌套远程调用,而且远程调用是耗时任务,导致数据库事务被拉长,最后拖垮数据库。

因此,上面的案例涉及的是消息事务嵌套数据库事务,在这里必须进行充分评估和设计,才可以规避事务风险。

3、事务补偿机制

显然,在对性能要求很高的场景中,两阶段提交协议并不是一种好方案,最大努力保证模式也会使多个分布式操作互相嵌套,有可能互相影响。这里,我们给出事务补偿机制,其性能很高,并且能够尽最大可能地保证事务的最终一致性。

在数据库分库分表后,如果涉及的多个更新操作在某一个数据库范围内完成,则可以使用数据库内的本地事务保证一致性;对于跨库的多个操作,可通过补偿和重试,使其在一定的时间窗口内完成操作,这样就可以实现事务的最终一致性,突破事务遇到问题就滚回的传统思路。

如果采用事务补偿机制,则在遇到问题时,我们需要记录遇到问题的环境、信息、步骤、状态等,后续通过重试机制使其达到最终一致性,详细内容可以参考《分布式服务架构:原理、设计与实战》第2章,彻底理解ACID原理、CAP理论、BASE原理、最终一致性模式等内容。

本文来自于:

https://www.toutiao.com/a6545626478447428103/?tt_from=weixin&utm_campaign=client_share&article_category=stock&timestamp=1524215325&app=news_article&utm_source=weixin&iid=28070358035&utm_medium=toutiao_android&wxshare_count=1

原文地址:https://www.cnblogs.com/kaixinyufeng/p/8892684.html

时间: 2024-10-07 22:39:01

001---mysql分库分表的相关文章

MySQL分库分表方案

1. MySQL分库分表方案 1.1. 问题: 1.2. 回答: 1.2.1. 最好的切分MySQL的方式就是:除非万不得已,否则不要去干它. 1.2.2. 你的SQL语句不再是声明式的(declarative) 1.2.3. 你招致了大量的网络延时 1.2.4. 你失去了SQL的许多强大能力 1.2.5. MySQL没有API保证异步查询返回顺序结果 1.2.6. 总结 MySQL分库分表方案 翻译一个stackoverflow上的问答,关于分库分表的缺点的,原文链接: MySQL shard

企业Shell实战-MySQL分库分表备份脚本

本文来自http://www.xuliangwei.com/xubusi/252.html 免费视频讲解见 http://edu.51cto.com/course/course_id-5064.html 企业Shell实战-MySQL分库分表备份 今天是2015年的最后一天,大家都开心的跨年,而我还在苦逼的呵呵-省略 此处内容来自老男孩教育oldboy以及老男孩26期王续精彩分享整理而来  为表示感谢,特整理此篇博文分享给大家! 项目联系笔者QQ:572891887   也可以加入架构师交流群:

OneProxy实现MySQL分库分表

OneProxy实现MySQL分库分表 简介 Part1:写在最前 随着网站的壮大,MySQL数据库架构一般会经历一个过程: 当我们数据量比较小的时候,一台单实例数据库足矣.等我们数据量增大的时候,我们会采用一主多从的数据库架构来降低我们的读写io.当我们某张业务表达到几百万上千万甚至上亿时,就应该去进行分表处理.本文演示OneProxy对数据库实现分表处理,对前端应用是透明的. Part2:环境简介 HE1:192.168.1.248 Master1 HE3:192.168.1.250 Mas

MYSQL分库分表

1 基本思想之什么是分库分表? 从字面上简单理解,就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上. 2 基本思想之为什么要分库分表? 数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据 操作,增删改查的开销也会越来越大:另外,由于无法进行分布式式部署,而一台服务器的资源(CPU.磁盘.内存.IO等)是有限的,最终数据库所能承载的 数据量.数据处理能力都将遭遇瓶颈.

MYSQL分库分表和不停机更改表结构

在MYSQL分库分表中我们一般是基于数据量比较大的时间对mysql数据库一种优化的做法,下面我简单的介绍一下mysql分表与分库的简单做法. 1.分库分表 很明显,一个主表(也就是很重要的表,例如用户表)无限制的增长势必严重影响性能,分库与分表是一个很不错的解决途径,也就是性能优化途径,现在的案例是我们有一个1000多万条记录的用户表members,查询起来非常之慢,同事的做法是将其散列到100个表中,分别从members0到members99,然后根据mid分发记录到这些表中,牛逼的代码大概是

(转)企业Shell实战-MySQL分库分表备份脚本

本文来自http://www.xuliangwei.com/xubusi/252.html 免费视频讲解见 http://edu.51cto.com/course/course_id-5064.html 企业Shell实战-MySQL分库分表备份 今天是2015年的最后一天,大家都开心的跨年,而我还在苦逼的呵呵-省略 此处内容来自老男孩教育oldboy以及老男孩26期王续精彩分享整理而来  为表示感谢,特整理此篇博文分享给大家! 项目联系笔者QQ:572891887   也可以加入架构师交流群:

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

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

实现MySQL分库分表备份的脚本

1)准备测试数据:通过写脚本批量建库建表并插入测试数据. [[email protected] scripts]# cat ceshi.sh #/bin/bash PATH="/usr/local/mysql/bin:$PATH"                 #定义mysql命令所在路径 MYUSER=root                                                     #定义数据用户名 DBPATH=/server/backup   

分享一个 MySQL 分库分表类(php)

当一个表数据记录过大时就会出现性能瓶颈,而一般对应的解决办法是要么做分区表,要么分表,分区表就不说了,分表又分为垂直分割和水平分割,具体区别请自行搜索.一般而言,分库分表属于水平分割,按照一定的规则将数据插入到不同的表中去.而分库则可以很方便的转移数据库的压力,比如将一个很大库的分别放在不同的服务器上. 下面是我写的一个分库分表的实现: <?php /** * User: guoyu * Date: 14-8-12 * Time: 下午3:16 */ namespace App\Model\Da

MySQL分库分表工具oneproxy安装说明

                    oneproxy数据库中间件说明 #wget http://www.onexsoft.com/software/oneproxy-rhel5-linux64-v6.0.0-ga.tar.gz #tar -zxvf oneproxy-rhel5-linux64-v6.0.0-ga.tar.gz  -C /usr/local/ # cd /usr/local/oneproxy/ 1.指定中间件启动的shell脚本和启动文件的程序目录位置 # sed -i 's