数据库架构演变及分库分表

当生产环境中业务量激增,数据库数据量也会极具增加。当数据库的数据量达到一定程度时(数据库瓶颈),数据库宿主机负载超高,会严重影响业务,严重时会导致数据库宕机。
为了避免这种极端情况的发生,我们应当在发生前做好预案,用于解决数据库数据量过载的问题。
以下是我个人工作中使用的解决方案:
1)数据库主从或多主多从方案
2)数据库冷热数据拆分
3)数据库分库分表操作
4)在数据库前端增加缓存redis或memcached

一开始时,公司部分业务的架构如下(全都是单节点情况)

经过自己强调该架构严重的缺点:节点单一,服务中断情况严重等严峻问题,后演变为如下简图的架构:

上述架构中,我们更新代码实现了不中断服务,同时解决了部分单一节点问题。后来一段时间业务做推广优惠活动,业务量激增,数据库数据量成指数性增长。数据库负载一直居高不下。当前的架构已经无法满足业务需求,后又提出对数据库进行数据的冷热数据拆分和数据读写分离(可以考虑使用中间件Mycat、Atlas、MaxScale,也可以考虑让开发写路由规则,有些框架自带路由规则),这里我们使用Mycat,如下图架构,这里只显示后端:

随着时间的推移,单库单表已经达到业务忍受的极限,这时候已经在硬件还是在mysql参数调优上都已经无法满足业务。这时候提出了数据库的分库分表。这里主要讲解数据库的分库分表
分库分表一共有两种方案:
1) 垂直拆分
2) 水平拆分
1、 垂直拆分
所谓垂直拆分,就是将单一数据库拆分成多个数据库,可以考虑的方案:
1) 根据业务逻辑进行拆分
2) 根据冷热数据进行拆分
这里先讲解根据业务逻辑拆分:
这里以商品--订单--用户为例,当多种类商品存放于一个数据库和一张表中时,随着时间推移,数据量增大,单库单表查询能力下降,可以根据商品种类来进行拆分,比如公司的产品:高中、初中、小学,由单个表拆分成三个独立表。如果还大,继续拆分,高中拆分成高一、高二、高三。初中拆分成初一、初二、初三。小学拆分成小一、小二......小六。(所有的分库分表都源于生活中的逻辑)。
我们生产环境中针对数据进行了拆分,冷数据(采用MyISAM引擎),热数据(采用Innodb引擎),同时将MyISAM引擎的数据库的宿主机多采用redis或memcache进行缓存,Innodb引擎的数据库的宿主机针对业务情况分配计算型和内存型物理机,还是混合型,同时可以考虑使用redis做部分存储,用于缓解数据库压力。
垂直拆分优缺点:
优点:
1) 由单库单表拆分成多库多表,降低了数据库增删改查压力
2) 对冷热数据拆分,降低了成本并合理利用硬件
3) 对于垂直拆分的数据库,在设计数据库时就应当考虑好数据库架构的延展性,(否则会对后期的扩展造成很大的阻力)
4) 按照业务分库后,业务逻辑更加清晰,更方便运维管理。
缺点:
1) 对于联表查询,带来了不便,可以通过调用接口的方式来触发联表查询的操作,对整个系统而言,复杂度提高了。
2) 对于有些数据库,存在单库性能瓶颈影响整个业务情况。
3) 同时对于事务而言,复杂度提高了。
2、 水平拆分
所谓水平拆分,简单来说就是将一张表中的数据按照行拆分成多份存储到不同的数据库的表中。比如user表有9000条数据,将user表拆成user1、user2、user3三张表存放于不同的数据库中,user1存储前3000条数据,中间3000条数据存储到user2表中,最后3000条数据存放到user3表中。
水平拆分的分片维度(有很多算法来决定采用哪种水平拆分的方案)
1) 按照哈希切片,对某个字段进行求哈希值,然后除以分片的数量,最后取模,取模相同的数据为一个分片,这就是哈希分片。
这种分片方式没有时效性。对数据分散比较均匀,缺点是如果需要查询则需要对数据进行聚合处理。
2) 按照时间序列算法切片,有的业务会有明显的季度波动,可以使用时间算法。这种算法就是数据分配不均。
生产环境中,我们部分业务采用的是哈希算法和时间序列算法的混合式
说到水平拆分,不得不提的是水平拆分的路由规则
设计数据库的时候,就要考虑到数据库中各种表的路由规则,同时还需要考虑数据表将来按照什么样的路由规则来进行分库分表。
比如,某个新用户注册,这个用户是如何分配到哪个库哪个表中?一般在注册的时候都会系统自动分配一个uid。根据这个uid可以按照某种算法来进行分配。比如uid%4,(这里将一张表分成4个表),如果是1 则分到第一张表中,以此类推。

水平拆分的优缺点:
1) 单库单表的数据量最大就那么大,有数据量的限制,我们可以根据业务情况来分配,刚好达到最大(这个量很难把握),既能提高该表的操作性能又节省了资源
2) 因为对表的结构改变非常少,对于开发而言更改代码量非常少,只需要增加路由规则。
3) 对整体系统的稳定性和负载都有大大的提高
缺点:
1) jion操作非常困难,尤其是跨库的联表查询
2) 有的拆分规则很难抽象出来
3) 分片的事务一致性比较难解决
4) 还有数据库的扩容和维护比较困难
针对上述垂直拆分和水平拆分,都有以下缺点:
1) jion操作困难
2) 事务一致性困难
3) 多个数据源的管理变复杂。
如何解决事务一致性问题呢?(这个重要性排在第一位)
1) 采用本地事务的一致性(能用则用)
2) 分布式事务处理
分布式事务处理的解决方案:
1) 两阶段提交方案(最严格的方案,很少使用,因为是阻塞协议造成性能问题):分为准备(锁定资源)和提交(消费资源)两个阶段。这种方式依赖资源管理器。
2) 最大努力保证模式(最常用,极端情况需要实时补偿,将已提交的数据进行回滚)不依赖资源管理器
一共有两种操作:从消息队列中消费消息和更新数据库操作
开始消息事务?开始数据库事务?接收消息?更新数据库?提交数据库事务?提交消息事务
当更新数据库时,突然中断,会进行回滚,恢复到初始状态,特殊情况,如果提交数据库事务成功,但是提交消息事务失败,就会造成消息再次消费的情况。这个可以通过消息幂等处理(有时候很多消息无法满足幂等性比如update操作,可以考虑增加一个消息应用状态表来记录消息消耗情况和数据库事务情况),出现上述极端情况,需要实时补偿。这种补偿机制类似于TCC模式Try-Confirm-Cancel(如果try都成功了,它会重复confirm或重复cancel,直到都成功),TCC要求Confirm/Cancel都必须是幂等操作。

3) 事务补偿机制
前面两种方案,都不是最好的,事务补偿机既能保证性能又能尽最大可能保证事务的一致性。说白了就是突破事务一失败就回滚的思想,指定在一定的时间内不断提交直到成功为止,如果超时则回滚。
分库分表过程中带来的问题
1、 扩容和数据的迁移
数据已经分片,同时数据量已经快达到阈值,需要对集群进行扩容,都采用成倍扩容。
以下是5个扩容步骤:
1) 增加新的路由规则,对新的数据库采用新路由规则进行写,同时对旧数据库采用旧路由规则写。(双写,两套路由规则)
2) 将双写前的旧数据按照新规则写入到新数据库中(需要做大量的数据清洗工作)。
3) 将按照旧的分片规则的查询更改为按照新的分片规则查询。
4) 将双写的路由规则代码下线,只按照新规则写数据
5) 删除按照旧分片规则写入的历史数据。
2、 分库分表带来的联表查询问题
举例:
卖家和买家,卖家需要查看该商品卖出情况,买家需要查看自己的交易情况,可以考虑使用两个表,一个以买家维度,记录买家商品交易情况,一个以卖家维度,记录卖家该商品交易情况。也就是查询交易和交易的数据是分别存储的,并从不同的系统提供接口。
方法二:通过搜索引擎解决(大数据了)

参考文档:
https://blog.csdn.net/it_man/article/details/21593187

原文地址:http://blog.51cto.com/laodou/2110819

时间: 2024-11-21 06:00:40

数据库架构演变及分库分表的相关文章

一文让你精通数据库优化方案之分库分表

分库分表概述 读写分离分散数据库读写操作压力,分库分表分散存储压力 适用场景 类似读写分离,分库分表也是确定没有其他优化空间之后才采取的优化方案.那如果业务真的发展很快岂不是很快要进行分库分表了?那为何不一开始就设计好呢? 按照架构设计的"三原则"(简单原则,合适原则,演化原则),简单分析一下: 首先,这里的"如果"事实上发生的概率比较低,做10个业务有一个业务能活下去就很不错了,更何况快速发展,和中彩票的概率差不多.如果我们每个业务上来就按照淘宝.微信的规模去做架

【转】MYSQL数据库数据拆分之分库分表总结

http://wentao365.iteye.com/blog/1740691 数据存储演进思路一:单库单表单库单表是最常见的数据库设计,例如,有一张用户(user)表放在数据库db中,所有的用户都可以在db库中的user表中查到.数据存储演进思路二:单库多表随着用户数量的增加,user表的数据量会越来越大,当数据量达到一定程度的时候对user表的查询会渐渐的变慢,从而影响整个DB的性能.如果使用MySQL, 还有一个更严重的问题是,当需要添加一列的时候,mysql会锁表,期间所有的读写操作只能

数据库-数据库设计-分库分表

为什么要分库分表 分库分表的设计 带来的问题 扩容 分布式事务 多个路由字段怎么设置 关于分库分表最全的一篇文章 这里介绍设计分库分表框架时应该考虑的设计要点,并给出相应的解决方案. 一.整体的切分方式 简单来说,数据的切分就是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果,即分库分表. 数据的切分根据其切分规则的类型,可以分为如下两种切分模式. 垂直(纵向)切分:把单一的表拆分成多个表,并分散到不同的数据库(主机)上. 水平(横

直播平台的数据库架构演变

8月24日,阿里云数据库技术峰会到来,本次技术峰会邀请到了阿里集团和阿里云数据库老司机们,为大家分享了一线数据库实践经验和技术干货.在本次峰会上,特邀嘉宾映客直播架构师王振涛分享了映客直播作为创业公司从0至日活千万的数据库架构变迁,数据库在直播中的经典应用场景,数据库存储的优化思路,以及如何构建一个高可用数据库架构. 以下内容根据演讲嘉宾现场视频以及PPT整理而成. 本次分享的内容将主要围绕以下四个部分: 一.映客直播发展历程 二.直播遇上云数据库 三.风口上的数据库架构变迁 四.直播典型应用场

OneProxy分库分表演示--楼方鑫

OneProxy分库分表演示 (杭州平民软件有限公司) OneProxy是为MySQL精心设计的数据访问层,可以为任何开发语言提供对MySQL数据库的智能数据路由功能,比如单点切换.读写分离.分库分表等高级功能.并且允许你在公有云和私有云环境下自由布署,打造属于自己的数据架构. 如果在测试中发现问题,请联系我(微博:平民架构,微信:anysql)! 分库分表 Oracle从8.0.x版本开始在数据库内部支持分区表,可以将数据按某一个字段的某一规律来进行分片存贮,以降低数据库索引的层级,提高访问效

架构组件:基于Shard-Jdbc分库分表,数据库扩容方案

一.数据库扩容 1.业务场景 互联网项目中有很多"数据量大,业务复杂度高,需要分库分表"的业务场景. 这样分层的架构 (1)上层是业务层biz,实现业务逻辑封装: (2)中间是服务层service,封装数据访问: (3)下层是数据层db,存储业务数据: 2.扩容场景和问题 当数据量持续新增,面临着这样一些需求,两台数据库无法容纳,需要数据库扩容,这里选择2台-扩容到3台的模式,如下图: 这样扩容的问题 (1)分库分表的策略导致数据迁移量大: (2)影响数据的持续服务性: (3)指定时间

数据库分库分表

1. 数据库分库分表 1.1. 前言 1.1.1. 名词解释 1.2. 数据库架构演变 1.3. 分库分表前的问题 1.3.1. 用户请求量太大 1.3.2. 单库太大 1.3.3. 单表太大 1.4. 分库分表的方式方法 1.4.1. 垂直拆分 1.4.2. 水平拆分 1.5. 分库分表后面临的问题 1.5.1. 事务支持 1.5.2. 多库结果集合并(group by,order by) 1.5.3. 跨库join 1.6. 分库分表方案产品 1.7. 为什么不建议分库分表 1.8. 参考

【干货】数据库分库分表基础和实践

数据库架构的演变在业务数据量比较少的时代,我们使用单机数据库就能满足业务使用,随着业务请求量越来越多,数据库中的数据量快速增加,这时单机数据库已经不能满足业务的性能要求,数据库主从复制架构随之应运而生. 主从复制是将数据库写操作和读操作进行分离,使用多个只读实例(slaver replication)负责处理读请求,主实例(master)负责处理写请求,只读实例通过复制主实例的数据来保持与主实例的数据一致性.由于只读实例可以水平扩展,所以更多的读请求不成问题,随着云计算.大数据时代的到来,事情并

数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示

本文原文连接: http://blog.csdn.net/bluishglc/article/details/7696085 ,转载请注明出处!本文着重介绍sharding切分策略,如果你对数据库sharding缺少基本的了解,请参考我另一篇从基础理论全面介绍sharding的文章:数据库Sharding的基本思想和切分策略 第一部分:实施策略 图1.数据库分库分表(sharding)实施策略图解(点击查看大图) 1.准备阶段 对数据库进行分库分表(Sharding化)前,需要开发人员充分了解系