关于数据库的分库分表

数据切分方式

关系型数据库单表数据量增大,导致处理能力受限,成为业务系统的瓶颈。数据切分将单表的大量数据分为多张小表数据,或者分散存储在不同的数据库中,减少单表大数据导致的系统问题。
在数据切分上,可以分成两种方式,垂直(纵向)切分和水平(横向)切分,两者各有优劣势,根据系统业务,选择切分方式,梳理架构。

垂直(纵向)切分更像是基于领域驱动的设计方式,而水平(横向)切分或许才是我们默认讨论的分库分表操作。

垂直(纵向)切分

垂直切分是基于数据表的“列”进行的,数据表中字段较多可以根据业务耦合性,将不同的字段拆分开来,有一张多字段的表拆分为多个少字段的表。在查询过程中,因为数据库以行为单位进行查询并且加载到内存然后返回的,所以更少的字段访问的效率更高。显然垂直切分要依赖于业务的耦合性,将关系紧密的字段放在相同的表中,关系不密切的放入不同表中,这也是系统设计中的领域设计的思想。实践中,就是按照领域不同拆分为不同的微服务模块,每个微服务模块负责管理自己的数据表。

垂直切分优点
  1. 业务层面的松耦合,逻辑清晰
  2. 不同业务的数据重构和升级之间互不影响
  3. 数据表字段较少,有效提高数据库的读写性能
垂直切分缺点
  1. 如果不同的表在不同的数据库里,无法进行数据表的join操作,需要通过接口进行数据的聚合
  2. 增加了分布式事务的复杂性
  3. 如果业务数据量很大,例如记录用户信息的数据表,如果用户数量激增,垂直切分仍然会引起单表的数据量过大的问题
水平(横向)切分

水平切分是基于数据表的“行”进行的,可以进行库内分表和分库分表。将一张大数据表按照某种规则拆分成多个库的多张表中,或者一个库的多张表中。拆分后的小数据表只包含部分的数据。如果拆分为同一库中多张表,虽然表的数据量变小了,但是数据的请求仍然可能发送同一个物理机,这样分表的帮助不大。所以分库分表重要不仅仅使数据表变小了,还要将请求尽可能负载均匀的分配到不同的物理机上。

水平切分缺点
  1. 水平切分可以切实改善单张数据表数据量过大的问题,提升系统稳定和负载的能力
  2. 与业务耦合性少,水平切分不需要考虑业务场景
水平切分缺点
  1. 与垂直切分一样,多张表会引起分布式事务的复杂性
  2. join操作查询性能差
  3. 分页和排序查询更加复杂
  4. 不重复主键的复杂性,根据业务有确切的数据字段作为主键(例如,用户ID,订单ID等等)还好,如果主键在单表中设计的是自增ID,那么分库分表之后就需要更多的操作保证主键唯一

总结分库分表带来的问题,并给出解决方案

事务一致性问题

多个库多张表同时更新,不可避免的会带来事务一致性的问题。分布式事务一般使用XA协议或者2PC处理。但是在提交事务的过程中需要协调多个节点,可能导致事务执行时间过长,并且分布式事务访问临界资源时可能会提高死锁的概率。涉及的节点越多这种情况就会越明显。
当系统对于一致性要求并不那么高的时候,不要求实时的一致性,仅仅保证最终一致性即可,可以采用补偿事务的方式。例如,定期校验和同步标准数据源数据,或者记录出现的错误定时重试执行。

不同节点的join操作

当数据分布在不同的节点上时,此时join会带来性能问题。另外不同数据库的不同表之间也无法使用join操作。可以使用一些技术去避免使用join查询。

  • 对于所有系统都依赖的表,可以在每个数据库中都保存一份。当然前提这些表要通常很少会进行修改,否则会引起数据一致性问题。
  • 对于经常需要一起访问的数据可以冗余保存一份,例如网购的订单数据表保存下单用户ID的同时,也将用户昵称一起保存一份(用户昵称会在用户表中存放)。显然这种冗余数据的解决方式比较局限,需要相互依赖的数据较少,此外同样存在数据一致性问题。
  • 通过接口进行数据的聚合,查询出多张表的结果集,通过关联的字段拼装在一起。
  • 如果可以确定表之间的关系,将关联关系的表存放在相同的数据库中,并且存放在同一个节点上。
不同节点的分页limit和排序order by查询

在跨越节点进行分页或排序查询时,如果分页依赖的字段就是指定操作的字段时,可以比较容易定位到分片并返回结果集;如果指定操作的字段不是分页依赖的字段,就需要在不同的分片上将数据执行指定的查询操作,然后将不同分片的结果集合起来,再做一次相同的查询操作得到结果集,可参考ElasticSearch关于数据的操作中的搜索时的分页,这时如果页数很大,性能消耗很大。
同样Max、Min、Sum、Count之类的函数也需要先在每个分片上执行,然后集合所有的数据后再次计算得到结果。

全局主键避重问题

在分库分表时不能在使用自增的主键ID,因为这样不同表的主键就会出现重复,需要根据业务设计唯一的业务ID,例如用户ID,订单ID等。

  1. 利用数据库生成唯一ID
  2. Snowflake等分布式唯一ID算法

数据表切分时机

基本原则是能不切分就不切分。只要当数据增长过快,数据量过大,或者业务发展需要垂直拆分字段时,才需要对数据进行切分。还有关于安全性和可用性的考虑,对数据拆分后可以保证数据的隔离性,这样一部分数据有问题不会影响到所有。

几道面试题

商品表的schema(product_id, shop_id, ....)需要进行切分,查询场景根据product_id查询商品详情,和根据shop_id查询商品的列表。如何操作分库分表?

答:可以根据product_id取模进行水平切分,如果product_id生成算法可能出现热点分片,可以先对product_id进行hash取值再取模。创建shop_id和product_id的映射关系,缓存这个映射关系,通过shop_id可以查到所有关联的product_id,在通过product_id查询具体的库。

如何不影响服务前提下无缝进行分库分表

答:几种方法如下

  1. 创建分库分表,业务此时进行双写,然后同步双写时间戳之前的数据(保证分布式一致性),直到所有数据同步完成。
  2. 全局进行同步,记录开始同步后所有变化的数据,最后执行补偿操作。
  3. 监听原数据表的数据变化,将变化的数据发送到消息队列中,读取消息队列同步到分表中。触发原数据表中所有数据的变化,例如所有数据时间戳增加1毫秒,这样全局进行同步,消息队列可以保证数据的有序一致。

补充:假如分表使用的是hash值,可以考虑利用一致性哈希技术,这样在分表时如果只涉及到一个分片,那么影响也仅仅是当前的分片,不需要全部进行再hash运算,影响最小。



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容