加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

mysql数据库切分介绍

发布时间:2022-03-01 09:27:38 所属栏目:MySql教程 来源:互联网
导读:这篇文章主要介绍mysql数据库切分是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! mysql数据库切分 前言 通过MySQLReplication功能所实现的扩展总是会受到数据库大小的限制。一旦数据库过于庞大,尤其是当写入过于频繁,非
  这篇文章主要介绍mysql数据库切分是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
 
  mysql数据库切分
  前言
  通过MySQLReplication功能所实现的扩展总是会受到数据库大小的限制。一旦数据库过于庞大,尤其是当写入过于频繁,非常难由一台主机支撑的时候,我们还是会面临到扩展瓶颈。这时候,我们就必须许找其它技术手段来解决这个瓶颈,那就是我们这一章所要介绍恶的数据切分技术。
 
  何谓数据切分
  可能非常多读者朋友在网上或者杂志上面都已经多次见到关于数据切分的相关文章了,仅仅只是在有些文章中称之为数据的Sharding。事实上无论是称之为数据的Sharding还是数据的切分,其概念都是一样的。
 
  简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。数据的切分同一时候还能够提高系统的总体可用性,由于单台设备Crash之后。仅仅有总体数据的某部分不可用,而不是全部的数据。
 
 
  当我们某个(或者某些)表的数据量和訪问量特别的大,通过垂直切分将其放在独立的设备上后仍然无法满足性能要求,这时候我们就必须将垂直切分和水平切分相结合。先垂直切分,然后再水平切分。才干解决这样的超大型表的性能问题。
 
  以下我们就针对垂直、水平以及组合切分这三种数据切分方式的架构实现及切分后数据的整合进行对应的分析。
 
  数据的垂直切分
  我们先来看一下,数据的垂直切分究竟是怎样一个切分法的。数据的垂直切分。也能够称之为纵向切分。将数据库想象成为由非常多个一大块一大块的“数据块”(表)组成。我们垂直的将这些“数据块”切开,然后将他们分散到多台数据库主机上面。这样的切分方法就是一个垂直(纵向)的数据切分。
 
  一个架构设计较好的应用系统。其总体功能肯定是由非常多个功能模块所组成的。而每一个功能模块所须要的数据对应到数据库中就是一个或者多个表。
 
 
  一般来说。假设是一个负载相对不是非常大的系统,并且表关联又非常的频繁。那可能数据库让步。将几个相关模块合并在一起降低应用程序的工作的方案能够降低较多的工作量。是一个可行的方案。
 
  当然。通过数据库的让步,让多个模块集中共用数据源,实际上也是简单介绍的默许了各模块架构耦合度增大的发展,可能会让以后的架构越来越恶化。尤其是当发展到一定阶段之后,发现数据库实在无法承担这些表所带来的压力。不得不面临再次切分的时候。所带来的架构改造成本可能会远远大于最初的时候。
 
  所以。在数据库进行垂直切分的时候,怎样切分,切分到什么样的程度,是一个比較考验人的难题。仅仅能在实际的应用场景中通过平衡各方面的成本和收益。才干分析出一个真正适合自己的拆分方案。
 
  比方在本书所使用演示样例系统的example数据库,我们简单的分析一下。然后再设计一个简单的切分规则,进行一次垂直垂直拆分。
 
  系统功能能够基本分为四个功能模块:用户,群组消息,相冊以及事件。分别对应为例如以下这些表:
 
  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信息,相同能够做到非常easy分拆。
 
  所以。我们第一步能够将数据库依照功能模块相关的表进行一次垂直拆分。每一个模块所涉及的表单独到一个数据库中,模块与模块之间的表关联都在应用系统端通过藉口来处理。例如以下图所看到的:
 
  mysql数据库切分是什么
 
  通过这样的垂直切分之后。之前仅仅能通过一个数据库来提供的服务。就被分拆成四个数据库来提供服务,服务能力自然是添加几倍了。
 
  垂直切分的长处
 
  ◆ 数据库的拆分简单明了,拆分规则明白;
 
  ◆ 应用程序模块清晰明白,整合easy。
 
  ◆ 数据维护方便易行,easy定位。
 
  垂直切分的缺点
 
  ◆ 部分表关联无法在数据库级别完毕。须要在程序中完毕。
 
  ◆ 对于訪问极其频繁且数据量超大的表仍然存在性能平静,不一定能满足要求。
 
  ◆ 事务处理相对更为复杂;
 
  ◆ 切分达到一定程度之后,扩展性会遇到限制;
 
  ◆ 过读切分可能会带来系统过渡复杂而难以维护。
 
  针对于垂直切分可能遇到数据切分及事务问题,在数据库层面实在是非常难找到一个较好的处理方案。实际应用案例中,数据库的垂直切分大多是与应用系统的模块相对应,同一个模块的数据源存放于同一个数据库中,能够解决模块内部的数据关联问题。而模块与模块之间,则通过应用程序以服务接口方式来相互提供所须要的数据。
 
  尽管这样做在数据库的总体操作次数方面确实会有所添加,可是在系统总体扩展性以及架构模块化方面,都是故意的。可能在某些操作的单次响应时间会稍有添加。可是系统的总体性能非常可能反而会有一定的提升。而扩展瓶颈问题。就仅仅能依靠下一节将要介绍的数据水平切分架构来攻克了。
 
  数据的水平切分
  上面一节分析介绍了数据的垂直切分,这一节再分析一下数据的水平切分。数据的垂直切分基本上能够简单的理解为依照表依照模块来切分数据,而水平切分就不再是依照表或者是功能模块来切分了。一般来说,简单的水平切分主要是将某个訪问极其平庸的表再依照某个字段的某种规则来分散到多个表之中。每一个表中包括一部分数据。
 
  简单来说。我们能够将数据的水平切分理解为是依照数据行的切分。就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其它的数据库中。当然,为了能够比較easy的判定各行数据被切分到哪个数据库中了,切分总是都须要依照某种特定的规则来进行的。
 
  如依据某个数字类型字段基于特定数目取模,某个时间类型字段的范围。或者是某个字符类型字段的hash值。假设整个系统中大部分核心表都能够通过某个字段来进行关联。那这个字段自然是一个进行水平分区的上上之选了,当然,非常特殊无法使用就仅仅能另选其它了。
 
  一般来说,像如今互联网非常火爆的Web2.0类型的站点。基本上大部分数据都能够通过会员用户信息关联上,可能非常多核心表都非常适合通过会员ID来进行数据的水平切分。
 
  而像论坛社区讨论系统。就更easy切分了,非常easy依照论坛编号来进行数据的水平切分。
 
  切分之后基本上不会出现各个库之间的交互。
 
  如我们的演示样例系统。全部数据都是和用户关联的。那么我们就能够依据用户来进行水平拆分,将不同用户的数据切分到不同的数据库中。当然,唯一有点差别的是用户模块中的groups表和用户没有直接关系。所以groups不能依据用户来进行水平拆分。对于这样的特殊情况下的表,我们全然能够独立出来。单独放在一个独立的数据库中。
 
  事实上这个做法能够说是利用了前面一节所介绍的“数据的垂直切分”方法。我将在下一节中更为具体的介绍这样的垂直切分与水平切分同一时候使用的联合切分方法。
 
  所以,对于我们的演示样例数据库来说,大部分的表都能够依据用户ID来进行水平的切分。不同用户相关的数据进行切分之后存放在不同的数据库中。如将全部用户ID通过2取模然后分别存放于两个不同的数据库中。
 
  每一个和用户ID关联上的表都能够这样切分。这样,基本上每一个用户相关的数据。都在同一个数据库中,即使是须要关联,也能够非常简单的关联上。
 
  我们能够通过下图来更为直观的展示水平切分相关信息:水平切分的长处
 
  mysql数据库切分是什么
 
  ◆ 表关联基本能够在数据库端全部完毕;
 
  ◆ 不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;
 
  ◆ 应用程序端总体架构修改相对较少;
 
  ◆ 事务处理相对简单;
 
  ◆ 仅仅要切分规则能够定义好。基本上较难遇到扩展性限制;
 
  水平切分的缺点
 
  ◆ 切分规则相对更为复杂,非常难抽象出一个能够满足整个数据库的切分规则;
 
  ◆ 后期数据的维护难度有所添加,人为手工定位数据更困难;
 
  ◆ 应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难。
 
  垂直与水平切分的联合使用
  上面两节内容中。我们分别,了解了“垂直”和“水平”这两种切分方式的实现以及切分之后的架构信息。同一时候也分析了两种架构各自的优缺点。可是在实际的应用场景中,除了那些负载并非太大。业务逻辑也相对较简单的系统能够通过上面两种切分方法之中的一个来解决扩展性问题之外。恐怕其它大部分业务逻辑略微复杂一点,系统负载大一些的系统,都无法通过上面不论什么一种数据的切分方法来实现较好的扩展性。而须要将上述两种切分方法结合使用,不同的场景使用不同的切分方法。
 
  在这一节中。我将结合垂直切分和水平切分各自的优缺点,进一步完好我们的总体架构,让系统的扩展性进一步提高。
 
  一般来说。我们数据库中的全部表非常难通过某一个(或少数几个)字段全部关联起来,所以非常难简单的仅仅通过数据的水平切分来解决全部问题。而垂直切分也仅仅能解决部分问题,对于那些负载非常高的系统,即使仅仅仅仅是单个表都无法通过单台数据库主机来承担其负载。
 
  我们必须结合“垂直”和“水平”两种切分方式同一时候使用,充分利用两者的长处,避开其缺点。
 
  每一个应用系统的负载都是一步一步增长上来的,在開始遇到性能瓶颈的时候,大多数架构师和DBA都会选择先进行数据的垂直拆分,由于这样的成本最先。最符合这个时期所追求的最大投入产出比。然而。随着业务的不断扩张。系统负载的持续增长,在系统稳定一段时期之后,经过了垂直拆分之后的数据库集群可能又再一次不堪重负,遇到了性能瓶颈。
 
  这时候我们该怎样抉择?是再次进一步细分模块呢,还是寻求其它的办法来解决?假设我们再一次像最開始那样继续细分模块,进行数据的垂直切分,那我们可能在不久的将来,又会遇到如今所面对的相同的问题。并且随着模块的不断的细化,应用系统的架构也会越来越复杂,整个系统非常可能会出现失控的局面。
 
  这时候我们就必须要通过数据的水平切分的优势,来解决这里所遇到的问题。并且,我们全然不必要在使用数据水平切分的时候,推倒之前进行数据垂直切分的成果,而是在其基础上利用水平切分的优势来避开垂直切分的弊端。解决系统复杂性不断扩大的问题。
 
  而水平拆分的弊端(规则难以统一)也已经被之前的垂直切分解决掉了。让水平拆分能够进行的得心应手。
 
  对于我们的演示样例数据库。假设在最開始。我们进行了数据的垂直切分,然而随着业务的不断增长,数据库系统遇到了瓶颈,我们选择重构数据库集群的架构。怎样重构?考虑到之前已经做好了数据的垂直切分,并且模块结构清晰明白。
 
  而业务增长的势头越来越猛。即使如今进一步再次拆分模块,也坚持不了太久。
 
  我们选择了在垂直切分的基础上再进行水平拆分。
 
  在经历过垂直拆分后的各个数据库集群中的每一个都仅仅有一个功能模块。而每一个功能模块中的全部表基本上都会与某个字段进行关联。如用户模块全部都能够通过用户ID进行切分,群组讨论模块则都通过群组ID来切分。相冊模块则依据相冊ID来进切分。最后的事件通知信息表考虑到数据的时限性(仅仅仅仅会訪问近期某个事件段的信息),则考虑按时间来切分。
 
  下图展示了切分后的整个架构:
 
  mysql数据库切分是什么
 
  实际上,在非常多大型的应用系统中,垂直切分和水平切这两种数据的切分方法基本上都是并存的。并且经常在不断的交替进行,以不断的添加系统的扩展能力。我们在应对不同的应用场景的时候,也须要充分考虑到这两种切分方法各自的局限,以及各自的优势。在不同的时期(负载压力)使用不同的结合方式。
 
  联合切分的长处
 
  ◆ 能够充分利用垂直切分和水平切分各自的优势而避免各自的缺陷;
 
  ◆ 让系统扩展性得到最大化提升。
 
  联合切分的缺点
 
  ◆ 数据库系统架构比較复杂。维护难度更大。
 
  ◆ 应用程序架构也相对更复杂;
 
  数据切分及整合方案
  通过前面的章节。我们已经非常清晰了通过数据库的数据切分能够极大的提高系统的扩展性。可是,数据库中的数据在经过垂直和(或)水平切分被存放在不同的数据库主机之后,应用系统面临的最大问题就是怎样来让这些数据源得到较好的整合。可能这也是非常多读者朋友非常关心的一个问题。这一节我们主要针对的内容就是分析能够使用的各种能够帮助我们实现数据切分以及数据整合的总体解决方式。
 
  数据的整合非常难依靠数据库本身来达到这个效果,尽管MySQL存在Federated存储引擎,能够解决部分相似的问题。可是在实际应用场景中却非常难较好的运用。那我们该怎样来整合这些分散在各个MySQL主机上面的数据源呢?
 
  总的来说,存在两种解决思路:
 
  1. 在每一个应用程序模块中配置管理自己须要的一个(或者多个)数据源。直接訪问各个数据库,在模块内完毕数据的整合;
 
  2. 通过中间代理层来统一管理全部的数据源。后端数据库集群对前端应用程序透明;
 
  可能90%以上的人在面对上面这两种解决思路的时候都会倾向于选择另外一种,尤其是系统不断变得庞大复杂的时候。
 
  确实。这是一个非常正确的选择,尽管短期内须要付出的成本可能会相对更大一些,可是对整个系统的扩展性来说,是非常有帮助的。
 
  所以,对于第一种解决思路我这里就不准备过多的分析,以下我重点分析一下在另外一种解决思路中的一些解决方式。
 
 
  ★利用MySQLProxy实现数据切分及整合
 
  MySQLProxy是MySQL官方提供的一个数据库代理层产品,和MySQLServer一样,相同是一个基于GPL开源协议的开源产品。可用来监视、分析或者传输他们之间的通讯信息。他的灵活性同意你最大限度的使用它,眼下具备的功能主要有连接路由,Query分析,Query过滤和修改,负载均衡。以及主要的HA机制等。
 
  实际上,MySQLProxy本身并不具有上述全部的这些功能。而是提供了实现上述功能的基础。
 
  要实现这些功能,还须要通过我们自行编写LUA脚本来实现。
 
  MySQLProxy实际上是在client请求与MySQLServer之间建立了一个连接池。全部client请求都是发向MySQLProxy,然后经由MySQLProxy进行对应的分析。推断出是读操作还是写操作,分发至对应的MySQLServer上。对于多节点Slave集群,也能够起做到负载均衡的效果。以下是MySQLProxy的基本架构图:
 
  mysql数据库切分是什么
 
  通过上面的架构简图。我们能够非常清晰的看出MySQLProxy在实际应用中所处的位置,以及能做的基本事情。
 
  关于MySQLProxy更为具体的实施细则在MySQL官方文档中有非常具体的介绍和演示样例。感兴趣的读者朋友能够直接从MySQL官方站点免费下载或者在线阅读,我这里就不累述浪费纸张了。
 
  ★利用Amoeba实现数据切分及整合
 
  Amoeba是一个基于Java开发的,专注于解决分布式数据库数据源整合Proxy程序的开源框架,基于GPL3开源协议。眼下,Amoeba已经具有Query路由,Query过滤,读写分离,负载均衡以及HA机制等相关内容。
 
  Amoeba 主要解决的以下几个问题:
 
  1. 数据切分后复杂数据源整合;
 
  2. 提供数据切分规则并降低数据切分规则给数据库带来的影响。
 
  3. 降低数据库与client的连接数。
 
  4. 读写分离路由;
 
  我们能够看出,Amoeba所做的事情,正好就是我们通过数据切分来提升数据库的扩展性所须要的。
 
  Amoeba并非一个代理层的Proxy程序,而是一个开发数据库代理层Proxy程序的开发框架,眼下基于Amoeba所开发的Proxy程序有AmoebaForMySQL和AmoebaForAladin两个。
 
  AmoebaForMySQL主要是专门针对MySQL数据库的解决方式,前端应用程序请求的协议以及后端连接的数据源数据库都必须是MySQL。对于client的不论什么应用程序来说,AmoebaForMySQL和一个MySQL数据库没有什么差别。不论什么使用MySQL协议的client请求,都能够被AmoebaForMySQL解析并进行对应的处理。下如能够告诉我们AmoebaForMySQL的架构信息(出自Amoeba开发人员博客):
 
  mysql数据库切分是什么
 
  AmoebaForAladin则是一个适用更为广泛。功能更为强大的Proxy程序。
 
  他能够同一时候连接不同数据库的数据源为前端应用程序提供服务,可是仅仅接受符合MySQL协议的client应用程序请求。也就是说,仅仅要前端应用程序通过MySQL协议连接上来之后,AmoebaForAladin会自己主动分析Query语句,依据Query语句中所请求的数据来自己主动识别出该所Query的数据源是在什么类型数据库的哪一个物理主机上面。下图展示了AmoebaForAladin的架构细节(出自Amoeba开发人员博客):
 
  mysql数据库切分是什么
 
  咋一看,两者好像全然一样嘛。细看之后,才会发现两者主要的差别仅在于通过MySQLProtocalAdapter处理之后。依据分析结果推断出数据源数据库。然后选择特定的JDBC驱动和对应协议连接后端数据库。
 
  事实上通过上面两个架构图大家可能也已经发现了Amoeba的特点了,他仅仅仅仅是一个开发框架。我们除了选择他已经提供的ForMySQL和ForAladin这两款产品之外。还能够基于自身的需求进行对应的二次开发。得到更适应我们自己应用特点的Proxy程序。
 
  当对于使用MySQL数据库来说。不论是AmoebaForMySQL还是AmoebaForAladin都能够非常好的使用。当然,考虑到不论什么一个系统越是复杂,其性能肯定就会有一定的损失,维护成本自然也会相对更高一些。所以,对于仅仅须要使用MySQL数据库的时候,我还是建议使用AmoebaForMySQL。
 
  关于Amoeba更为具体的用法读者朋友能够通过Amoeba开发人员博客(http://amoeba.sf.net)上面提供的使用手冊获取,这里就不再细述了。
 
  ★利用HiveDB实现数据切分及整合
 
  和前面的MySQLProxy以及Amoeba一样,HiveDB相同是一个基于Java针对MySQL数据库的提供数据切分及整合的开源框架,仅仅是眼下的HiveDB仅仅支持数据的水平切分。
 
  主要解决大数据量下数据库的扩展性及数据的高性能訪问问题,同一时候支持数据的冗余及主要的HA机制。
 
  HiveDB的实现机制与MySQLProxy和Amoeba有一定的差异,他并非借助MySQL的Replication功能来实现数据的冗余,而是自行实现了数据冗余机制,而其底层主要是基于HibernateShards来实现的数据切分工作。
 
  在HiveDB中,通过用户自己定义的各种Partitionkeys(事实上就是制定数据切分规则),将数据分散到多个MySQLServer中。在訪问的时候。在执行Query请求的时候。会自己主动分析过滤条件,并行从多个MySQLServer中读取数据,并合并结果集返回给client应用程序。
 
  单纯从功能方面来讲,HiveDB可能并不如MySQLProxy和Amoeba那样强大,可是其数据切分的思路与前面二者并无本质差异。此外,HiveDB并不仅仅仅仅是一个开源爱好者所共享的内容,而是存在商业公司支持的开源项目。
 
  以下是HiveDB官方站点上面一章图片,描写叙述了HiveDB怎样来组织数据的基本信息,尽管不能具体的表现出太多架构方面的信息,可是也基本能够展示出其在数据切分方面独特的一面了。
 
  mysql数据库切分是什么
 
  ★ mycat 数据整合:具体http://www.songwie.com/articlelist/11
 
  ★ 其它实现数据切分及整合的解决方式
 
  除了上面介绍的几个数据切分及整合的总体解决方式之外,还存在非常多其它相同提供了数据切分与整合的解决方式。如基于MySQLProxy的基础上做了进一步扩展的HSCALE,通过Rails构建的SpockProxy。以及基于Pathon的Pyshards等等。
 
 
  数据切分与整合可能存在的问题
  这里。大家应该对数据切分与整合的实施有了一定的认识了。也许非常多读者朋友都已经依据各种解决方式各自特性的优劣基本选定了适合于自己应用场景的方案,后面的工作主要就是实施准备了。
 
  在实施数据切分方案之前,有些可能存在的问题我们还是须要做一些分析的。
 
  一般来说,我们可能遇到的问题主要会有以下几点:
 
  ◆ 引入分布式事务的问题。
 
  ◆ 跨节点Join的问题;
 
  ◆ 跨节点合并排序分页问题。
 
  1. 引入分布式事务的问题
 
  一旦数据进行切分被分别存放在多个MySQLServer中之后,无论我们的切分规则设计的多么的完美(实际上并不存在完美的切分规则),都可能造成之前的某些事务所涉及到的数据已经不在同一个MySQLServer中了。
 
 
  也就是说。仅仅要我们愿意。全然能够将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务。并通过应用程序来总控各个小事务。
 
  当然,这样作的要求就是我们的俄应用程序必须要有足够的健壮性。当然也会给应用程序带来一些技术难度。
 
  2.跨节点Join的问题
 
  上面介绍了可能引入分布式事务的问题,如今我们再看看须要跨节点Join的问题。
 
  数据切分之后。可能会造成有些老的Join语句无法继续使用。由于Join使用的数据源可能被切分到多个MySQLServer中了。
 
  对待这类问题,我还是推荐通过应用程序来进行处理,先在驱动表所在的MySQLServer中取出对应的驱动结果集。然后依据驱动结果集再到被驱动表所在的MySQLServer中取出对应的数据。可能非常多读者朋友会觉得这样做对性能会产生一定的影响,是的,确实是会对性能有一定的负面影响,可是除了此法,基本上没有太多其它更好的解决的方法了。
 
  并且,由于数据库通过较好的扩展之后,每台MySQLServer的负载就能够得到较好的控制。单纯针对单条Query来说,其响应时间可能比不切分之前要提高一些,所以性能方面所带来的负面影响也并非太大。更何况。相似于这样的须要跨节点Join的需求也并非太多。相对于总体性能而言,可能也仅仅是非常小一部分而已。所以为了总体性能的考虑,偶尔牺牲那么一点点。事实上是值得的。毕竟系统优化本身就是存在非常多取舍和平衡的过程。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读