Mysql 扩展性设计之数据切分、那么数据切分后会带来哪些问题呢?比如分布式事务、数据的一致性、垂直切分和水平切分应用场景

  • 前言、什么是数据切分
  • 垂直(纵向)切分、水平(横向)切分、他们各自的特点
    • 垂直切分
    • 水平切分
    • 联合使用解决方案
    • 垂直切分的具体分析、详解、结合案例
      • 具体分析
    • 经验之谈
    • 结合案例解剖
      • 案例背景
      • 分析
      • 剖析
    • 垂直切分的优点
    • 垂直切分的缺点
    • 不足之处
  • 水平切分
    • 水平切分的优点
    • 水平切分的缺点
  • 垂直与水平 相结合(联合使用)
    • 联合切分的优点
    • 联合切分的缺点
  • 数据切分及切分之后的数据整合方案
    • 简单介绍中间代理层都有哪些,
  • 数据切分与整合的遗留问题
  • 总结、敲黑板、划重点
  • 常见问题答疑
    • 一张表多少数据量合适?
    • 一般分几张表合适?
    • 分库分表之后事务如果保证?

前言、什么是数据切分

数据的切分(Sharding)根据切分的类型,可以分为两种切分模式

  • 第一种是按照不同的表(或者schema)来切分到不同的数据库上,称之为数据的垂直(纵向)切分
  • 另一种是根据表中的数据逻辑的关系、将同一个表中的数据按照某种条件拆分到多台数据库上,称之为水平(横向)切分

垂直(纵向)切分、水平(横向)切分、他们各自的特点

垂直切分

最大的特点就是规则简单、实施也方便、尤其适合业务之间的耦合度低、相互影响小、业务逻辑清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表拆分到不同数据库中,根据不同的表来拆分,对应用程序的影响也会更小,拆分规则也会相对来说比较简单

水平切分

水平切分相比垂直切分,显得稍微复杂一些,因为需要将同一个表中的不同数据拆分到不同数据库中,对于应用程序来说,拆分的规则本身就根据表名来拆分更为复杂、后期的数据维护也会更为复杂一些

联合使用解决方案

当我们某个表的数据量和访问量特别大的,通过垂直拆分将其放在独立的设备上之后仍无法满足性能要求时,这时我们就必须将垂直切分和水平切分相结合,先垂直切分,在水平切分,才能解决这种超大型表的性能问题。

垂直切分的具体分析、详解、结合案例

将数据库想象成为由很多个一大块一大块的“数据块(表)组成,我们垂直的将这些“数据块”切开,然后将他们分散到多台数据库主机上面。
通俗来讲就是讲一张大表拆分成多个小表、减少单表的数据量过大、通过拆分Schema、减少不必要的字段查询。

具体分析

一个架构设计比较完善的应用,总体功能模块是有很多模块组成的,而每一个功能模块所需要的数据对应到数据库就是一个个表。而在架构设计中,各个功能模块相互之间的交互点越少越好,系统的耦合度就越低,系统各个模块的维护,这样各个模块的维护性及扩展性就越好,这样呢,实现数据的垂直切分就更容易。
当我们的功能模块越清晰,耦合度越低,数据垂直切分的规则定义也就越容易。完全可以根据功能模块来进行数据的切分,不同功能模块的数据存放于不同的数据库主机中,可以很容易就避免掉跨数据库的 Join 存在,同时系统架构也非常的清晰。

当然有时,很难有系统能够做到所有功能模块所使用的表完全独立,完全不需要访问对方的表或者需要两个模块的表进行 Join 操作。这种情况下,我们就必须根据实际的应用场景进行评估权衡。决定是迁就应用程序将需要 Join 的表的相关某快都存放在同一个数据库中,还是让应用程序做更多的事情,也就是程序完全通过模块接口取得不同数据库中的数据,然后在程序中完成 merger操作。

经验之谈

根据笔者的经验、一般来说,如果是一个负载相对不是很大的系统,而且表关联又非常的频繁,那可能数据库让步,将几个相关模块合并在一起减少应用程序的工作的方案,可以减少较多的工作量,是一个可行的方案。

当然,通过数据库的让步,让多个模块集中共用数据源,实际上也是简介的默许了各模块架构耦合度增大的发展,可能会让以后的架构越来越恶化。尤其是当发展到一定阶段之后 ,发现数据库实在无法承担这些表所带来的压力,不得不面临再次切分的时候,所带来的架构改造成本可能会远远大于最初的时候。

所以,在数据库进行垂直切分的时候,如何切分,切分到什么样的程度,是一个比较考验人的难题。只能在实际的应用场景中通过平衡各方面的成本和收益,才能分析出一个真正适合自己的拆分方案。

结合案例解剖

案例背景

某个系统功能可以基本分为四个功能模块:用户,群组消息,相册以及事件,分别对应为如下这些表:

  1. 用户模块表:user,user_profile,user_group,user_photo_album
  2. 群组讨论表:groups,group_message,group_message_content,top_message
  3. 相册相关表:photo,photo_album,photo_album_relation,photo_comment
  4. 事件信息表:event

分析

  • 群组讨论模块和用户模块之间主要存在通过用户或者是群组关系来进行关联。一般关联的时候都会是通过用户的 id 或者 nick_name 以及 group 的 id 来进行关联,通过模块之间的接口实现不会带来太多麻烦;
  • 相册模块仅仅与用户模块存在通过用户的关联。这两个模块之间的关联基本就有通过用户 id关联的内容,简单清晰,接口明确;
  • 事件模块与各个模块可能都有关联,但是都只关注其各个模块中对象的 ID 信 息 ,同样可以做到很容易分拆。

剖析

可以将数据库按照功能模块相关的表进行一次垂直拆分,每个模块所涉及的表单独到一个数据库中,模块与模块之间的表关联都在应用系统端通过藉口来处理,如下图

通过这样的垂直切分之后,之前只能通过一个数据库来提供的服务,就被分拆成四个数据库来提供服务,服务能力自然是增加几倍了。

垂直切分的优点

  • 数据库的拆分简单明了,拆分规则明确
  • 应用程序模块清晰明确,整合容易
  • 数据维护方便易行,容易定位

垂直切分的缺点

  • 部分表关联无法在数据库级别完成,需要在程序中完成
  • 对于访问极其频繁且数据量超大的表仍然存在性能平静,不一定能满足要求
  • 事务处理相对更为复杂
  • 切分达到一定程度之后,扩展性会遇到限制
  • 过读切分可能会带来系统过渡复杂而难以维护

不足之处

针对于垂直切分可能遇到数据切分及事务问题,在数据库层面实在是很难找到一个较好的处理方案。

水平切分

一般来说,简单的水平切分主要是将某个访问极其平凡的表再按照某个字段的某种规则来分散到多个表之中,每个表中包含一部分数据。
简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。当然,为了能够比较容易的判定各行数据被切分到哪个数据库中了,切分总是都需要按照某种特定的规则来进行的。
如根据某个数字类型字段基于特定数目取模,某个时间类型字段的范围,或者是某个字符类型字段的 hash 值。如果整个系统中大部分核心表都可以通过某个字段来进行关联,那这个字段自然是一个进行水平分区的上上之选了,当然,非常特殊无法使用就只能另选其他了。

水平切分的优点

  • 表关联基本能够在数据库端全部完成
  • 不会存在某些超大型数据量和高负载的表遇到瓶颈的问题
  • 应用程序端整体架构改动相对较少
  • 事务处理相对简单
  • 只要切分规则能够定义好,基本上较难遇到扩展性限制

水平切分的缺点

  • 切分规则相对更为复杂,很难抽象出一个能够满足整个数据库的切分规则
  • 后期数据的维护难度有所增加,人为手工定位数据更困难
  • 应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难

垂直与水平 相结合(联合使用)

上面我们对垂直切分和水平切分有了一定的了解。同时也说了他们各自的优缺点、及应用场景,但是我们在实际的场景中、没有办法使用一种切分的方法来提供性能、和扩展性、在不同的业务场景下使用不同的切分方法。
一般来说随着业务的发展、在遇到瓶颈时、首先会进行数据的垂直切分、因为这样成本最小、服务当前的业务发展状况、通俗讲投入产出比吧,然而随着业务的不断扩张、负载和数据量也是持续增长、在稳定一段时期之后,再对数据水平切分。

实际上,在很多大型的系统中,垂直切分和水平切分基本上都是并行存在的,而且是经常在不断交替进行、以不断增加系统的扩展力,当然联合使用也存在一定程度上的优劣使。

联合切分的优点
  • 可以充分利用垂直切分和水平切分各自的优势而避免各自的缺陷
  • 让系统扩展性得到最大化提升
联合切分的缺点
  • 数据库系统架构比较复杂,维护难度更大
  • 应用程序架构也相对更复杂

数据切分及切分之后的数据整合方案

总的来说,存在两种解决思路:

  • 在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合
  • 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明
    可能90%人的都会采用第二种(中间代理层)解决方案。也是一个正确的解决方案。

简单介绍中间代理层都有哪些,

  • 利用 MySQL Proxy 实现数据切分及整合
  • 利用 Amoeba 实现数据切分及整合
  • 利用 HiveDB 实现数据切分及整合
  • 阿里云的DRDS 产品
  • Mycat 中间件 零侵入
  • 当当的sharding jdbc 中间件

数据切分与整合的遗留问题

  • 引入分布式事务的问题

    • 对应的解决方案:Seata https://github.com/seata/seata
  • 跨节点 Join 的问题
    • sharding jdbc 、drds 都支持的
  • 跨节点合并排序分页问题
    • sharding jdbc 、drds 都支持的

总结、敲黑板、划重点

  • 对垂直切分、一般情况下大表拆分小表
  • 对水平切分
    • 分表的策略、常用:hash取模,日期
    • 一旦水平切分之后、后期的扩展就比较麻烦、大部分情况下都是按照Hash取模。所以,前期一定要规划好,未来一到两年数据量、比如,单表的月增长量、保证业务在未来一到两年数据量能满足。
    • 规划时,尽可能保证单表500万左右的数据量、非核心业务可以稍微大点
    • 分库一般情况下也是hash 形式来进行
  • 架构设计、尽可能保证to c 业务单表查询、便于管理和维护、后期有利于加缓存、或者join 不超过三个、可以前期结合缓存使用
  • 目前大部分云产品DRDS、sharding jdbc 分库分表都是支持不按照分库或分表条件查询、比如分页或者做排序,这些都是支持,但是性能比较慢,原因是:会在中间代理层把所有的表进行挨个查询、在内存做Merger,性能比较差。对于业务后台或者内部系统,可以使用OLAP型数据库进行统计查询、比如:阿里云的ADB、可以通过DTS进行迁移
  • 目前大部分设计都是微服务、所以建议单个服务对应单个库、减低耦合、避免多个服务共享数据源、一旦业务起量、需要拆分时,不利于扩展性、另外单库的连接数也不够用、微服务肯定每个服务都有对应的连接池、当然还可以通过数据中间件,例如:mycat
  • 分库分表之后带来分布式事务问题
    • 如果保证数据的一致性,一般分为弱一致性、强一致性、最终一致性,

      • CAP原理中,有三个要素:

        • 一致性(Consistency)
        • 可用性(Availability)
        • 分区容忍性(Partition tolerance)
    • 一般来说使用分布式事务框架对性能必定产生一定的影响,建议根据业务情况对数据一致性做不同的处理,做到最终一致性即可、比如:通过MQ、或者Seata

常见问题答疑

一张表多少数据量合适?
  • 单表500万吧,非核心业务可以更多、另外还看成本
一般分几张表合适?
  • 根据单表的数据、估算未来一到两年的数据量、来算分多少张表合适
分库分表之后事务如果保证?
  • 比如:通过MQ来最终一致性、或者Seata框架来做,对性能有一定的影响、根据业务情况对数据一致性做不同的处理,做到最终一致性即可

Mysql 扩展性设计之数据切分、那么数据切分后会带来哪些问题呢?比如分布式事务、数据的一致性、垂直切分和水平切分应用场景相关推荐

  1. 面试被问mysql扩展性设计相关的点,你知道该如何回答吗

    面试被问mysql扩展性设计相关的点,你知道该如何回答吗 什么是扩展性 横向扩展(Scale Out) 和纵向扩展(Scale Up)区别 横向扩展 纵向扩展 事务相关性最小化原则 解决方案 敲黑板. ...

  2. Mysql 扩展性设计之Replication,在Mysql具有很相当重要的位置,主从、主主从,你了解他们的背后逻辑吗

    前言 什么是Replication,干什么用的呢 Replication是怎么个工作的呢,背后的逻辑或原理是什么样子的 Replication 整体介绍 Replication 线程总结 敲黑板,划重 ...

  3. 事务没提交的数据查的出来吗?_品牛栏山,论分布式事务

    上周末,我和一个在电商上市公司做开发的朋友一起喝酒聊天,他目前带一个研发团队,负责大系统中退货款相关的技术服务版块,混的挺不错,从一个初级程序员做到规模很大上市公司的技术负责人,一路过来也非常坎坷,刚 ...

  4. ES分布式机制的透明性,垂直扩容和水平扩容,数据rebalance,master节点,节点平等的分布式架构,shard和replica机制(学习)

    1.Elasticsearch对复杂分布式机制的透明影藏特性 Elasticsearch是一套分布式的系统,分布式是为了应对大数据量影藏了复杂的分布式机制. 分片机制(我们可以随随便便就将一些docu ...

  5. 实践 | Sentinel 扩展性设计

    Sentinel 提供多样的 SPI 接口用于提供扩展的能力.用户可以在用同一个 sentinel-core 的基础上自行扩展接口实现,从而可以方便地给 Sentinel 添加自定义的逻辑. 初始化逻 ...

  6. 实践 | Sentinel 扩展性设计 1

    摘要: Sentinel 提供多样的 SPI 接口用于提供扩展的能力.用户可以在用同一个 sentinel-core 的基础上自行扩展接口实现,从而可以方便地给 Sentinel 添加自定义的逻辑. ...

  7. SAP S/4HANA Customer Management(CRM)模块的扩展性设计

    标题:One order extensibility in S4HANA for Customer Management In SAP CRM we use Application Enhanceme ...

  8. mysql 数据表格切分_MySQL数据库垂直和水平切分

    replication的限制:一旦数据库过于庞大,尤其是当写入过于频繁,很难由一台主机支撑的时候,我们还是会面临到扩展瓶颈.数据切分(sharding):通过某种特定的条件,将我们存放在同一个数据库中 ...

  9. mysql双倍扩容_mysql扩展性架构实践N库到2N 库的扩容,2变4、4变8

    mysql扩展性架构实践N库到2N 库的扩容,2变4.4变8 http://geek.csdn.net/news/detail/52070 58同城 沈剑 http://www.99cankao.co ...

最新文章

  1. 扇贝编程python是干嘛的-产品观察 | 以对话式互动学习撬动转化,扇贝编程瞄准职教市场...
  2. C和C++中struct和typedef struct的异同
  3. Java:反射和注解从入门到放弃
  4. redis集群环境搭建入门
  5. Python脚本编译为可跨平台、跨架构执行的字节码文件pyc方法
  6. 论文查重库包含哪些?
  7. 第二人生,Second Life
  8. 在虚拟机中安装雨林木风XP镜像的正确步骤
  9. linux如何结束at命令,Linux命令总结--at命令(atq.atrm)
  10. BI工具和报表工具有什么不同
  11. 中兴zxr10路由器重启命令_ZXR10路由器基本操作和配置.doc
  12. 【运维心得】你不知道,运维也要写代码(3)
  13. ifup,ifdown命令详解
  14. 机器学习——回归模型
  15. Python中怎么解决GIL锁与深浅拷贝问题【详细】
  16. Android OpenGLES2.0(一)OpenGLES2.0基础介绍
  17. 谷歌浏览器在怎么添加迅雷_如何在Google搜索结果中添加作者信息
  18. Alcohol.120%.v1.9.8.7530.Retail.Incl.Activation.Keymaker-BetaMaster
  19. iOS 图片设置为圆角矩形,圆形等
  20. 银行数据治理的9大核心领域

热门文章

  1. 采用多种方式实现词频统计
  2. 《天天数学》连载08:一月八日
  3. 【BZOJ2326】【codevs2314】数学作业,第100篇博文纪念
  4. 装饰器python的通俗理解_2道极好的Python算法题 | 带你透彻理解装饰器的妙用
  5. [AHOI2004]实验基地 dp+枚举
  6. 【Python】Python3.7.3 - 虚拟环境:pyvenv过时;使用python -m venv命令
  7. 让服务程序进入demon模式的代码
  8. eclipse中java环境配置
  9. 使用python开发json、csv数据格式转换工具
  10. java get https_JAVA – 使用SSL证书和HTTPS的简单GET请求