数据库拆分
随着用户量的不断提升,对网站应用的并发量也将不断增高。这将会导致应用卡顿延迟,更严重甚至会导致系统整个崩溃。而解决这种情况的发生,下意识便是如何降低用户对系统数据库操作。
1、采用redis,memcache等缓存技术,降低对数据库的读操作。
2、其次可以考虑进行数据库的读写分离操作
3、当我们使用缓存,以及数据库的读写分离之后,数据库的压力还是很大的时候,这时候就要考虑一下数据库的拆分。
一.整体的切分方式
简单来说,数据的切分就是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果,即分库分表。
数据的切分根据其切分规则的类型,可以分为如下两种切分模式。
垂直(纵向)切分:把单一的表拆分成多个表,并分散到不同的数据库(主机)上。
水平(横向)切分:根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上。
垂直拆分:
垂直拆分是通过业务将不同的表分类,分布到不同的数据库上面。这就能将数据库的总体压力平摊下去。淘宝就是通过业务分成交易数据库,用户数据库,支付数据库。甚至会更加的细分文字信息用mongdb等
案例如下:
#有如下几张表
--------------+--------------+------------------
用户信息(User)+ 交易记录(Pay)+ 商品(Commodity)|
--------------+--------------+------------------
针对以上案例,垂直切分就是根据每个表的不同业务进行切分,比如User表、Pay表和Commodity表,将每个表切分到不同的数据库上。
垂直切分的优点如下:
- 拆分后业务清晰,拆分规则明确。
- 系统之间进行整合或扩展很容易。
- 按照成本、应用的等级、应用的类型等将表放到不同的机器上,便于管理。
- 便于实现动静分离、冷热分离的数据库表的设计模式。
- 数据维护简单。
垂直切分的缺点如下:
- 部分业务表无法关联(Join),只能通过接口方式解决,提高了系统的复杂度。
- 受每种业务的不同限制,存在单库性能瓶颈,不易进行数据扩展和提升性能。
- 事务处理复杂。
垂直切分除了用于分解单库单表的压力,也用于实现冷热分离,也就是根据数据的活跃度进行拆分,因为对拥有不同活跃度的数据的处理方式不同。
我们可将本来可以在同一个表中的内容人为地划分为多个表。所谓“本来”,是指按照关系型数据库第三范式的要求,应该在同一个表中,将其拆分开就叫作反范化(Denormalize)
例如,对配置表的某些字段很少进行修改时,将其放到一个查询性能较高的数据库硬件上;对配置表的其他字段更新频繁时,则将其放到另一个更新性能较高的数据库硬件上。
这里我们再举一个例子:在微博系统的设计中,一个微博对象包括文章标题、作者、分类、创建时间等属性字段,这些字段的变化频率低,查询次数多,叫作冷数据。而博客的浏览量、回复数、点赞数等类似的统计信息,或者别的变化频率比较高的数据,叫作活跃数据或者热数据。我们把冷热数据分开存放,就叫作冷热分离,在MySQL的数据库中,冷数据查询较多,更新较少,适合用MyISAM引擎,而热数据更新比较频繁,适合使用InnoDB存储引擎,这也是垂直拆分的一种。
我们推荐在设计数据库表结构时,就考虑垂直拆分,根据冷热分离、动静分离的原则,再根据使用的存储引擎的特点,对冷数据可以使用MyISAM,能更好地进行数据查询;对热数据可以使用InnoDB,有更快的更新速度,这样能够有效提升性能。
其次,对读多写少的冷数据可配置更多的从库来化解大量查询请求的压力;对于热数据,可以使用多个主库构建分库分表的结构,请参考下面关于水平切分的内容,后续的三四五章提供了不同的分库分表的具体实施方案。
注意,对于一些特殊的活跃数据或者热点数据,也可以考虑使用Memcache、Redis之类的缓存,等累计到一定的量后再更新数据库,例如,在记录微博点赞数量的业务中,点赞数量被存储在缓存中,每增加1000个点赞,才写一次数据。
水平拆分:
垂直拆分后遇到单机瓶颈,可以使用水平拆分。相对于垂直拆分的区别是:垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中。
分库分表需要涉及到对应的SQL路由规则主库备库等,例如:淘宝设计了一套TDDL来解决这些问题,应用端只需配置对应的规则即可,对应用端的没有任何侵入的设计。
水平拆分,总之,一般先分库,如果分库后查询仍然慢,于是按照分库的思想开始做分表的工作数据库采用分布式数据库(所有节点的数据加起来才算是整体数据),文件系统采用分布式文件系统任何强大的单一服务器都满足不了大型系统持续增长的业务需求,数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
与垂直切分对比,水平切分不是将表进行分类,而是将其按照某个字段的某种规则分散到多个库中,在每个表中包含一部分数据,所有表加起来就是全量的数据。
简单来说,我们可以将对数据的水平切分理解为按照数据行进行切分,就是将表中的某些行切分到一个数据库表中,而将其他行切分到其他数据库表中。
这种切分方式根据单表的数据量的规模来切分,保证单表的容量不会太大,从而保证了单表的查询等处理能力,例如将用户的信息表拆分成User1、User2等,表结构是完全一样的。我们通常根据某些特定的规则来划分表,比如根据用户的ID来取模划分。
例如,在博客系统中,当读取博客的量很大时,就应该采取水平切分来减少每个单表的压力,并提升性能。
以微博表为例,当同时有100万个用户在浏览时,如果是单表,则单表会进行100万次请求,假如是单库,数据库就会承受100万次的请求压力;假如将其分为100个表,并且分布在10个数据库中,每个表进行1万次请求,则每个数据库会承受10万次的请求压力,虽然这不可能绝对平均,但是可以说明问题,这样压力就减少了很多,并且是成倍减少的。
水平切分的优点如下:
- 单库单表的数据保持在一定的量级,有助于性能的提高。
- 切分的表的结构相同,应用层改造较少,只需要增加路由规则即可。
- 提高了系统的稳定性和负载能力。
水平切分的缺点如下:
- 切分后,数据是分散的,很难利用数据库的Join操作,跨库Join性能较差。
- 拆分规则难以抽象。
- 分片事务的一致性难以解决。
- 数据扩容的难度和维护量极大。
综上所述,垂直切分和水平切分的共同点如下:
- 存在分布式事务的问题。
- 存在跨节点Join的问题。
- 存在跨节点合并排序、分页的问题。
- 存在多数据源管理的问题。
在了解这两种切分方式的特点后,我们就可以根据自己的业务需求来选择,通常会同时使用这两种切分方式,垂直切分更偏向于业务拆分的过程,在技术上我们更关注水平切分的方案。