- 本文节选自即将出版的《可伸缩服务架构:框架与中间件》一书,作者:李艳鹏、杨彪、李海亮、贾博岩、刘淏。
- 点击文末原文链接可以直达《可伸缩服务架构:框架与中间件》书籍主页。
简单来说,数据的切分就是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果,即分库分表。
数据的切分根据其切分规则的类型,可以分为如下两种切分模式。
垂直(纵向)切分:把单一的表拆分成多个表,并分散到不同的数据库(主机)上。
水平(横向)切分:根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上。
垂直切分
一个数据库由多个表构成,每个表对应不同的业务,垂直切分是指按照业务将表进行分类,将其分布到不同的数据库上,这样就将数据分担到了不同的库上(专库专用)。
案例如下#有如下几张表--------------+--------------+------------------
用户信息(User)+ 交易记录(Pay)+ 商品(Commodity)|
--------------+--------------+------------------
针对以上案例,垂直切分就是根据每个表的不同业务进行切分,比如User表、Pay表和Commodity表,将每个表切分到不同的数据库上。
垂直切分的优点
目录⊙ 拆分后业务清晰,拆分规则明确
⊙ 系统之间进行整合或扩展很容易
⊙ 按照成本、应用的等级、应用的类型等将表放到不
同的机器上,便于管理
⊙ 便于实现动静分离、冷热分离的数据库表的设计模
式
⊙ 数据维护简单
垂直切分的缺点
目录⊙ 部分业务表无法关联(Join),只能通过接口方式
解决,提高了系统的复杂度
⊙ 受每种业务的不同限制,存在单库性能瓶颈,不易
进行数据扩展和提升性能
⊙ 事务处理复杂
垂直切分除了用于分解单库单表的压力,也用于实现冷热分离,也就是根据数据的活跃度进行拆分,因为对拥有不同活跃度的数据的处理方式不同。
我们可将本来可以在同一个表中的内容人为地划分为多个表。所谓“本来”,是指按照关系型数据库第三范式的要求,应该在同一个表中,将其拆分开就叫作反范化(Denormalize)。
例如,对配置表的某些字段很少进行修改时,将其放到一个查询性能较高的数据库硬件上;对配置表的其他字段更新频繁时,则将其放到另一个更新性能较高的数据库硬件上。
这里我们再举一个例子,在微博系统的设计中,一个微博对象包括文章标题、作者、分类、创建时间等属性字段,这些字段的变化频率低,查询次数多,叫作冷数据。而博客的浏览量、回复数、点赞数等类似的统计信息,或者别的变化频率比较高的数据,叫作活跃数据或者热数据。我们把冷热数据分开存放,就叫作冷热分离,在MySQL的数据库中,冷数据查询较多,更新较少,适合用MyISAM引擎,而热数据更新比较频繁,适合使用InnoDB存储引擎,这也是垂直拆分的一种。
我们推荐在设计数据库表结构时,就考虑垂直拆分,根据冷热分离、动静分离的原则,再根据使用的存储引擎的特点,对冷数据可以使用MyISAM,能更好地进行数据查询;对热数据可以使用InnoDB,有更快的更新速度,这样能够有效提升性能。
其次,对读多写少的冷数据可配置更多的从库来化解大量查询请求的压力;对于热数据,可以使用多个主库构建分库分表的结构,请参考下面关于水平切分的内容,后续的3.3节、3.4节和3.5节提供了不同的分库分表的具体实施方案。
注意,对于一些特殊的活跃数据或者热点数据,也可以考虑使用Memcache、Redis之类的缓存,等累计到一定的量后再更新数据库,例如,在记录微博点赞数量的业务中,点赞数量被存储在缓存中,每增加1000个点赞,才写一次数据。
水平切分
与垂直切分对比,水平切分不是将表进行分类,而是将其按照某个字段的某种规则分散到多个库中,在每个表中包含一部分数据,所有表加起来就是全量的数据。简单来说,我们可以将对数据的水平切分理解为按照数据行进行切分,就是将表中的某些行切分到一个数据库表中,而将其他行切分到其他数据库表中。
这种切分方式根据单表的数据量的规模来切分,保证单表的容量不会太大,从而保证了单表的查询等处理能力,例如将用户的信息表拆分成User1、User2等,表结构是完全一样的。我们通常根据某些特定的规则来划分表,比如根据用户的ID来取模划分。
例如,在博客系统中,当读取博客的量很大时,就应该采取水平切分来减少每个单表的压力,并提升性能。以微博表为例,当同时有100万个用户在浏览时,如果是单表,则单表会进行100万次请求,假如是单库,数据库就会承受100万次的请求压力;假如将其分为100个表,并且分布在10个数据库中,每个表进行1万次请求,则每个数据库会承受10万次的请求压力,虽然这不可能绝对平均,但是可以说明问题,这样压力就减少了很多,并且是成倍减少的。
水平切分的优点
目录⊙ 单库单表的数据保持在一定的量级,有助于性能的
提高
⊙切分的表的结构相同,应用层改造较少,只需要增
加路由规则即可
⊙提高了系统的稳定性和负载能力
水平切分的缺点
目录⊙ 切分后,数据是分散的,很难利用数据库的Join操
作,跨库Join性能较差
⊙ 拆分规则难以抽象
⊙ 分片事务的一致性难以解决
⊙ 数据扩容的难度和维护量极大
综上所述,垂直切分和水平切分的共同点如下
存在分布式事务的问题。
存在跨节点Join的问题。
存在跨节点合并排序、分页的问题。
存在多数据源管理的问题。
在了解这两种切分方式的特点后,我们就可以根据自己的业务需求来选择,通常会同时使用这两种切分方式,垂直切分更偏向于业务拆分的过程,在技术上我们更关注水平切分的方案。
- 本文节选自即将出版的《可伸缩服务架构:框架与中间件》一书,作者:李艳鹏、杨彪、李海亮、贾博岩、刘淏。
- 点击文末原文链接可以直达《可伸缩服务架构:框架与中间件》书籍主页。
简单来说,数据的切分就是通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果,即分库分表。
数据的切分根据其切分规则的类型,可以分为如下两种切分模式。
垂直(纵向)切分:把单一的表拆分成多个表,并分散到不同的数据库(主机)上。
水平(横向)切分:根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上。
垂直切分
一个数据库由多个表构成,每个表对应不同的业务,垂直切分是指按照业务将表进行分类,将其分布到不同的数据库上,这样就将数据分担到了不同的库上(专库专用)。
案例如下#有如下几张表--------------+--------------+------------------
用户信息(User)+ 交易记录(Pay)+ 商品(Commodity)|
--------------+--------------+------------------
针对以上案例,垂直切分就是根据每个表的不同业务进行切分,比如User表、Pay表和Commodity表,将每个表切分到不同的数据库上。
垂直切分的优点
目录⊙ 拆分后业务清晰,拆分规则明确
⊙ 系统之间进行整合或扩展很容易
⊙ 按照成本、应用的等级、应用的类型等将表放到不
同的机器上,便于管理
⊙ 便于实现动静分离、冷热分离的数据库表的设计模
式
⊙ 数据维护简单
垂直切分的缺点
目录⊙ 部分业务表无法关联(Join),只能通过接口方式
解决,提高了系统的复杂度
⊙ 受每种业务的不同限制,存在单库性能瓶颈,不易
进行数据扩展和提升性能
⊙ 事务处理复杂
垂直切分除了用于分解单库单表的压力,也用于实现冷热分离,也就是根据数据的活跃度进行拆分,因为对拥有不同活跃度的数据的处理方式不同。
我们可将本来可以在同一个表中的内容人为地划分为多个表。所谓“本来”,是指按照关系型数据库第三范式的要求,应该在同一个表中,将其拆分开就叫作反范化(Denormalize)。
例如,对配置表的某些字段很少进行修改时,将其放到一个查询性能较高的数据库硬件上;对配置表的其他字段更新频繁时,则将其放到另一个更新性能较高的数据库硬件上。
这里我们再举一个例子,在微博系统的设计中,一个微博对象包括文章标题、作者、分类、创建时间等属性字段,这些字段的变化频率低,查询次数多,叫作冷数据。而博客的浏览量、回复数、点赞数等类似的统计信息,或者别的变化频率比较高的数据,叫作活跃数据或者热数据。我们把冷热数据分开存放,就叫作冷热分离,在MySQL的数据库中,冷数据查询较多,更新较少,适合用MyISAM引擎,而热数据更新比较频繁,适合使用InnoDB存储引擎,这也是垂直拆分的一种。
我们推荐在设计数据库表结构时,就考虑垂直拆分,根据冷热分离、动静分离的原则,再根据使用的存储引擎的特点,对冷数据可以使用MyISAM,能更好地进行数据查询;对热数据可以使用InnoDB,有更快的更新速度,这样能够有效提升性能。
其次,对读多写少的冷数据可配置更多的从库来化解大量查询请求的压力;对于热数据,可以使用多个主库构建分库分表的结构,请参考下面关于水平切分的内容,后续的3.3节、3.4节和3.5节提供了不同的分库分表的具体实施方案。
注意,对于一些特殊的活跃数据或者热点数据,也可以考虑使用Memcache、Redis之类的缓存,等累计到一定的量后再更新数据库,例如,在记录微博点赞数量的业务中,点赞数量被存储在缓存中,每增加1000个点赞,才写一次数据。
水平切分
与垂直切分对比,水平切分不是将表进行分类,而是将其按照某个字段的某种规则分散到多个库中,在每个表中包含一部分数据,所有表加起来就是全量的数据。简单来说,我们可以将对数据的水平切分理解为按照数据行进行切分,就是将表中的某些行切分到一个数据库表中,而将其他行切分到其他数据库表中。
这种切分方式根据单表的数据量的规模来切分,保证单表的容量不会太大,从而保证了单表的查询等处理能力,例如将用户的信息表拆分成User1、User2等,表结构是完全一样的。我们通常根据某些特定的规则来划分表,比如根据用户的ID来取模划分。
例如,在博客系统中,当读取博客的量很大时,就应该采取水平切分来减少每个单表的压力,并提升性能。以微博表为例,当同时有100万个用户在浏览时,如果是单表,则单表会进行100万次请求,假如是单库,数据库就会承受100万次的请求压力;假如将其分为100个表,并且分布在10个数据库中,每个表进行1万次请求,则每个数据库会承受10万次的请求压力,虽然这不可能绝对平均,但是可以说明问题,这样压力就减少了很多,并且是成倍减少的。
水平切分的优点
目录⊙ 单库单表的数据保持在一定的量级,有助于性能的
提高
⊙切分的表的结构相同,应用层改造较少,只需要增
加路由规则即可
⊙提高了系统的稳定性和负载能力
水平切分的缺点
目录⊙ 切分后,数据是分散的,很难利用数据库的Join操
作,跨库Join性能较差
⊙ 拆分规则难以抽象
⊙ 分片事务的一致性难以解决
⊙ 数据扩容的难度和维护量极大
综上所述,垂直切分和水平切分的共同点如下
存在分布式事务的问题。
存在跨节点Join的问题。
存在跨节点合并排序、分页的问题。
存在多数据源管理的问题。
在了解这两种切分方式的特点后,我们就可以根据自己的业务需求来选择,通常会同时使用这两种切分方式,垂直切分更偏向于业务拆分的过程,在技术上我们更关注水平切分的方案。