架构实战案例解析
王庆友
前 1 号店首席架构师
18817 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 23 讲
架构实战案例解析
15
15
1.0x
00:00/00:00
登录|注册

18 | 可伸缩架构案例:数据太多,如何无限扩展你的数据库?

你好,我是王庆友。在第 16 讲中,我和你介绍了很多可伸缩的架构策略和原则。那么今天,我会通过 1 号店订单水平分库的实际案例,和你具体介绍如何实现系统的可伸缩。

问题和解决思路

2013 年,随着 1 号店业务的发展,每日的订单量接近 100 万。这个时候,订单库已有上亿条记录,订单表有上百个字段,这些数据存储在一个 Oracle 数据库里。当时,我们已经实现了订单的服务化改造,只有订单服务才能访问这个订单数据库,但随着单量的增长以及在线促销的常态化,单一数据库的存储容量和访问性能都已经不能满足业务需求了,订单数据库已成为系统的瓶颈。所以,对这个数据库的拆分势在必行。
数据库拆分一般有两种做法,一个是垂直分库,还有一个是水平分库。
垂直分库
简单来说,垂直分库就是数据库里的表太多,我们把它们分散到多个数据库,一般是根据业务进行划分,把关系密切的表放在同一个数据库里,这个改造相对比较简单。
水平分库
某些表太大,单个数据库存储不下,或者数据库的读写性能有压力。通过水平分库,我们把一张表拆成多张表,每张表存放部分记录,分别保存在不同的数据库里,水平分库需要对应用做比较大的改造。
当时,1 号店已经通过服务化,实现了订单库的垂直拆分,它的订单库主要包括订单基本信息表、订单商品明细表、订单扩展表。这里的问题不是表的数量太多,而是单表的数据量太大,读写性能差。所以,1 号店通过水平分库,把这 3 张表的记录分到多个数据库当中,从而分散了数据库的存储和性能压力。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

1号店订单水平分库的实际案例为读者提供了数据库扩展的解决方案。文章首先介绍了水平分库的两种方式:垂直分库和水平分库,并重点讨论了水平分库的实施过程。作者提出了量化分析的方法来确定分库维度,并介绍了根据ID范围和根据ID取模的数据分库方法及其优缺点。此外,文章还讨论了分库数量的选择和分库带来的新问题。在具体实施过程中,文章提到了分库路由、分页处理、分库字段映射等技术细节,并分享了1号店订单水平分库的总体技术架构和安全落地的实施过程。最终,文章总结了1号店订单水平分库的成果和经验教训,强调了分库策略的重要性,以及在实施过程中需要注意的要点。整体而言,本文详实全面,对于需要扩展数据库的技术人员具有一定的参考价值。文章通过具体案例和技术细节,帮助读者了解了数据库水平分库的实际操作和实施过程,为设计复杂方案的技术人员提供了宝贵的经验和思路。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《架构实战案例解析》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • 李博
    1 号店最终是根据用户 ID 后三位取模进行分库,初始分成了 6 个库,理论上可以支持多达 768 个库。 老师这个最大支持768怎么算出来的?

    作者回复: 你看的很仔细啊,三位数最大是999,从6开始翻倍,最大翻到768,这已经够用了。

    2020-04-01
    2
    13
  • Jxin
    1.分页为何不走es? 这样聚合多库数据觉得比较复杂,而复杂本身就是需要警惕的事。 2.取模那里,0库转移%12=7的数据。没有6号库,只有5号库,转移%12=11的数据。 3.用户id可以截取写入订单号中,以此减少一次中间表映射的成本。担心安全性,则做加密处理。毕竟加密解密是cpu密集操作,其效率正常都会比查表这种io操作快,更何况这表字段虽少,但写频繁,切行数不会少。

    作者回复: 1. 分页怎么处理具体要看场景,实时性要求不高的可以走大数据或ES,要求高的还是要并行直接查数据库。 2. 关于数据迁移逻辑,原来6个库(编号为0-5),分别放 Id %6后0-5的数据,现在新增加编号是6-11号库,原来0号库一半数据(id%12=6)要迁到6号库,文中说的6号库,指的是迁移后新加的6号库。 3. 文章最后提到,最后落的方案是按照用户id后三位取模,对订单编号进行改造,加入了用户ID后三位。

    2020-04-01
    2
    6
  • Geek_ae94ad
    现有数据库的表是主键id自增的方式,现在想分库分表,老数据如何做数据兼容操作?

    作者回复: 分库字段是这个主键id吗?如果不是的话,那老数据不影响。如果是,还是可以直接取模方式分,只是新id的算法要换下,改为由数据库外部服务统一生成,比如雪花算法等。

    2020-05-28
    4
  • biscuitlife
    停服分库有点low,老师有么有更好的办法?

    作者回复: 分库是比较大的动作,还是停服一下比较好,当然可以通过周密计划,大幅缩短停服时间。

    2021-06-28
    2
  • Middleware
    分页的处理方法可否进一步分享一下 可落地的实现办法

    作者回复: 最简单的方式就是所有库拿数据,然后在内存里重排取记录,从数据库拿可以使用多线程并发。 分页没有特别好办法,需要具体情况具体分析。

    2020-04-03
    2
  • 开心小毛
    请问王老师:在垂直分库之后,是否会存在跨数据库的外键 (foreign key constraint): 是否必须把存在外键关联的表分到同一个数据库中;还是说我们必须在分库之后必须删除外键限制,再在应用层模拟外键。

    作者回复: 现在数据库设计实践,一般不在数据库物理层面设置外键,而是在应用系统维护。

    2020-07-26
    2
    1
  • 蓝天
    1,老师这里分库是逻辑上的分库吧,不是物理上的吧,否则几张表一个库有点浪费 2,我们现在用的rds,现在一个慢sql全卡住了,微服务用rds是不是成本会高呢

    作者回复: 1. 物理机部署,分库本来的目的就是解决存储和性能的问题,使用逻辑库意义不大。 2. 如果用mysql,可以一台机器装多个实例,每个微服务使用自己的实例。

    2020-04-02
    1
  • 正在减肥的胖籽。
    老师中午好,请教你几个问题 1.水平拆分库,代码层面也就是修改路由。你们线上怎么实现平滑迁移?如果我现在4个表,需要拆分成8个表。上线的时候用户还需要正常访问。我现在没想到好的方案。

    作者回复: 凌晨2-3点短暂停系统,提前全网会发公告

    2020-04-01
    3
    1
  • AlfredLover
    精彩,分页这里,代码层面是循环去查询每个库的记录,还是每个库一个线程并行的方式去查询?

    作者回复: 文章后面有提到,dal层提供开关,让上层调用时选择是否并行执行

    2020-04-01
    1
  • Nero Lou
    请问根据用户ID分库的话,那些跟用户ID无关的表,比如商品。是不是得冗余到每个库中?好像微服务之类比较好分,维度太多的业务模型比较难搞

    作者回复: 水平分库针对具体的库,比如订单数据库使用用户ID,商品数据库使用商家id等。如果库里的某些表,不支持id分库,特殊情况,是可以冗余到每个库里。

    2022-08-18归属地:上海
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部