文档章节

唯品会的订单分库分表实践总结以及关键步骤

Carl_
 Carl_
发布于 2016/06/29 09:58
字数 2358
阅读 84
收藏 8
点赞 0
评论 0

随着唯品会业务的快速发展,订单量的不断增长,原有的订单存储架构已经不能满足公司的发展了,特别是在大促高峰期,原订单库已经成为抢购瓶颈,已经严重制约公司的发展。

唯品会旧订单库包含几十张订单相关表,旧订单库是典型的一主多从架构;主库容量已接近服务器物理空间上限,同时也已经达到MySQL的处理上限,很快将无法再处理新增订单。

旧订单库面临的问题有:

1、超大容量问题

  • 订单相关表都已经是超大表,最大表的数据量已经是几十亿,数据库处理能力已经到了极限;

  • 单库包含多个超大表,占用的硬盘空间已经接近了服务器的硬盘极限,很快将无空间可用;

2、性能问题

单一服务器处理能力是有限的,单一订单库的TPS也有上限,不管如何优化,总会有达到上限,这限制了单位时间的订单处理能力,这个问题在大促时更加明显,如果不重构,订单达到一定量以后,就无法再继续增长,严重影响到用户体验。

3、升级扩展问题

  • 单一主库无法灵活的进行升级和扩展,无法满足公司快速发展要求;

  • 所有的订单数据都放在同一库里面,存在单点故障的风险;

综上所述,容量、性能问题是急需解决的问题,扩展是为了将来3~5年内能够很好的满足唯品会快速发展的需要,而不需要每隔几个月花费人力物力去考虑扩容等问题。

解决方法思考

1、解决容量问题

我们可以考虑到最直接的方式是增加大容量硬盘,或者对IO有更高要求,还可以考虑增加SSD硬盘来解决容量的问题。此方法无法解决单表数据量问题。

可以对数据表历史数据进行归档,但也需要频繁进行归档操作,而且不能解决性能问题。

2、解决性能问题

提高数据库服务器的配置,这个可以提升一定数量的QPS和TPS,但仍然不能解决单服务器连接数、IO读写存在上限的问题,此方法仍然存在单点故障的问题。

拆分方法探讨

常见的数据库拆分方式有三种:垂直拆分、水平拆分、垂直水平拆分。

1、垂直拆分

垂直拆库是根据数据库里面的数据表的相关性进行拆分,比如:一个数据库里面既存在用户数据,又存在订单数据,那么垂直拆分可以把用户数据放到用户库、把订单数据放到订单库。如下图:
垂直拆表是对数据表进行垂直拆分的一种方式,常见的是把一个多字段的大表按常用字段和非常用字段进行拆分,每个表里面的数据记录数一般情况下是相同的,只是字段不一样,使用主键关联,如下图:

2、水平拆分

水平拆分是把单表按某个规则把数据分散到多个表的拆分方式,比如:把单表1亿数据按某个规则拆分,分别存储到10个相同结果的表,每个表的数据是1千万,拆分出来的表,可以分别放至到不同数据库中,即同时进行水平拆库操作,如下图:
水平拆分可以降低单表数据量,让每个单表的数据量保持在一定范围内,从而提升单表读写性能。但水平拆分后,同一业务数据分布在不同的表或库中,可能需要把单表事务改成跨表事务,需要转变数据统计方式等。

3、垂直水平拆分

垂直水平拆分,是综合了垂直和水平拆分方式的一种混合方式,垂直拆分把不同类型的数据存储到不同库中,再结合水平拆分,使单表数据量保持在合理范围内,提升总TPS,提升性能,如下图:

垂直拆分策略

原订单库把所有订单相关的数据(订单销售、订单售后、订单任务处理等数据)都放在同一数据库中,不符合电商系统分层设计,对于订单销售数据,性能第一,需要能够在大促高峰承受每分钟几万到几十万订单的压力;而售后数据,是在订单生成以后,用于订单物流、订单客服等,性能压力不明显,只要保证数据的及时性即可;所以根据这种情况,把原订单库进行垂直拆分,拆分成订单售后数据、订单销售数据、其他数据等,如下图:

水平拆分策略

垂直拆分从业务上把订单下单数据与下单后处理数据分开,但对于订单销售数据,由于数据量仍然巨大,最大的订单销售相关表达到几十亿的数据量,如果遇到大型促销(如:店庆128、419、618、双十一等等),数据库TPS达到上限,单销售库单订单表仍然无法满足需求,还需要进一步进行拆分,在这里使用水平拆分策略。

订单分表是首先考虑的,分表的目标是保证每个数据表的数量保持在1000~5000万左右,在这个量级下,数据表的大小与性能是最理想的。

如果几十个分表都放到一个订单库里面,运行于单组服务器上,则受限于单组服务器的处理能力,数据库的TPS有限,所以需要考虑分库,把分表放到分库里面,减轻单库的压力,增加总的订单TPS。

1、用户编号HASH切分

使用用户编号哈希取模,根据数据量评估,把单库拆分成n个库,n个库分别存放到m组服务器中,如下图:
每组服务器容纳4个库,如果将来单服务器达到性能、容量等瓶颈,可以直接把数据库水平扩展为2倍服务器集群,还可以继续扩展为4倍服务器集群。水平扩展可以支撑公司在未来3~5年的快速订单增长。

使用用户编号进行 sharding,可以使得创建订单的处理更简单,不需要进行跨库的事务处理,提高下单的性能与成功率。

2、订单号索引表

根据用户编号进行哈希分库分表,可以满足创建订单和通过用户编号维度进行查询操作的需求,但是根据统计,按订单号进行查询的占比达到80%以上,所以需要解决通过订单号进行订单的CURD等操作,所以需要建立订单号索引表。

订单号索引表是用于用户编号与订单号的对应关系表,根据订单号进行哈希取模,放到分库里面。根据订单号进行查询时,先查出订单号对应的用户编号,再根据用户编号取模查询去对应的库查询订单数据。

订单号与用户编号的关系在创建订单后是不会更改的,为了进一步提高性能,引入缓存,把订单号与用户编号的关系存放到缓存里面,减少查表操作,提升性能,索引不命中时再去查表,并把查询结果更新到缓存中。

3、分布式数据库集群

订单水平分库分表以后,通过用户编号,订单号的查询可以通过上面的方法快速定位到订单数据,但对于其他条件的查询、统计操作,无法简单做到,所以引入分布式数据库中间件。

下图是基本构架:

总结与思考

技术架构与业务场景息息相关,不能脱离实际的业务场景、历史架构、团队能力、数据体量等等去做架构重构,对于一家快速发展的电子商务公司,订单系统是核心,订单库是核心的核心,订单库的重构就像汽车在高速公路上跑着的过程中更换轮胎。

本文是对唯品会订单库重构——采用分库分表策略对原订单库表进行拆分的粗略总结,在订单库重构过程中遇到的问题远远超过这些,比如:历史数据的迁移、各外围系统的对接等,但这些在公司强大的技术团队面前,最终都顺利的解决,新旧订单库顺利的切换,给公司快速的业务发展提供坚实的保障。

本文转载自:http://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=512113930&idx=1&sn=72a157196ba0c949168dbfd25...

共有 人打赏支持
Carl_
粉丝 39
博文 387
码字总数 12168
作品 0
广州
每秒处理10万订单支付架构

一、库分表 在redis,memcached等缓存系统盛行的互联网时代,构建一个支撑每秒十万只读的系统并不复杂,无非是通过一致性哈希扩展缓存节点,水平扩展web服务器等。支付系统要处理每秒十万笔订...

rickiyeat ⋅ 2017/11/09 ⋅ 0

每秒处理10万订单乐视集团支付架构

声明:本文为CSDN原创投稿文章,未经许可,禁止任何形式的转载。 作者:梁阳鹤,乐视网boss平台技术部架构师,主要负责乐视集团支付,乐视会员系统,商业运营平台等系统架构工作。开源数据访...

chaun ⋅ 2016/05/11 ⋅ 1

分库分表的几种常见形式以及可能遇到的难题

引言 在谈论数据库架构和数据库优化的时候,我们经常会听到“分库分表”、“分片”、“Sharding”…这样的关键词。让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增...

无寄语 ⋅ 2016/09/09 ⋅ 0

乐视秒杀架构解读:从零开始搭建百万每秒订单系统

在各种秒杀活动大行其道的今天,订单系统的性能与稳定日益重要。乐视集团作为这一技术的佼佼者,在多次的电商狂欢节中都能抢占商机、拔得头筹,其表现无疑为其他企业和厂商提供了非常有价值的...

DBAplus社群 ⋅ 2016/06/15 ⋅ 0

分库分表的几种常见形式以及可能遇到的难题

前言 在谈论数据库架构和数据库优化的时候,我们经常会听到“分库分表”、“分片”、“Sharding”…这样的关键词。让人感到高兴的是,这些朋友所服务的公司业务量正在(或者即将面临)高速增...

火力全開 ⋅ 2016/10/14 ⋅ 0

美团外卖订单中心的演进

【前言】 美团外卖从2013年9月成交第一单以来,已走过了三个年头。期间,业务飞速发展,美团外卖由日均几单发展为日均500万单(9月11日已突破600万)的大型O2O互联网外卖服务平台。平台支持的...

www19 ⋅ 2016/10/27 ⋅ 0

在实践中使用ShardingJdbc组件的正确姿势(一)

文章摘要:在设计系统时,需要根据实际的业务情况来选用合适的组件构建系统。 在互联网时代,随着业务数量的暴增和应用规模的不断扩大,无论是oracle还是mysql这样子的关系型数据库,都会面临...

癫狂侠 ⋅ 05/08 ⋅ 0

每秒处理10万高并发订单的某集团支付系统架构详情

随着乐视硬件抢购的不断升级,乐视集团支付面临的请求压力百倍乃至千倍的暴增。作为商品购买的最后一环,保证用户快速稳定的完成支付尤为重要。所以在15年11月,我们对整个支付系统进行了全面...

404Code ⋅ 2017/12/22 ⋅ 0

近几个月博客阅读整理

java Java finally语句到底是在return之前还是之后执行? 白话JVM-深入虚拟机字节码执行引擎 详细分析Java中断机制 TOMCAT源码分析 Flink内存管理源码解读之基础数据结构 Flink内存管理源码解...

oO脾气不坏Oo ⋅ 2016/04/23 ⋅ 0

乐视秒杀:每秒十万笔交易的数据架构解读

随着乐视硬件抢购的不断升级,乐视集团支付面临的请求压力百倍乃至千倍的暴增。作为商品购买的最后一环,保证用户快速稳定地完成支付尤为重要。所以在2015年11月,我们对整个支付系统进行了全...

-wangming- ⋅ 2016/05/10 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

使用 vue-cli 搭建项目

vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一、 安装 node.js 首先需要安装node环境,可以直接到中...

初学者的优化 ⋅ 7分钟前 ⋅ 0

设计模式 之 享元模式

设计模式 之 享元模式 定义 使用共享技术来有效地支持大量细粒度对象的复用 关键点:防止类多次创建,造成内存溢出; 使用享元模式来将内部状态与外部状态进行分离,在循环创建对象的环境下,...

GMarshal ⋅ 23分钟前 ⋅ 0

SpringBoot集成Druid的最简单的小示例

参考网页 https://blog.csdn.net/king_is_everyone/article/details/53098350 建立maven工程 Pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM......

karma123 ⋅ 今天 ⋅ 0

Java虚拟机基本结构的简单记忆

Java堆:一般是放置实例化的对象的地方,堆分新生代和老年代空间,不断未被回收的对象越老,被放入老年代空间。分配最大堆空间:-Xmx 分配初始堆空间:-Xms,分配新生代空间:-Xmn,新生代的大小一...

算法之名 ⋅ 今天 ⋅ 0

OSChina 周日乱弹 —— 这么好的姑娘都不要了啊

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @TigaPile :分享曾惜的单曲《讲真的》 《讲真的》- 曾惜 手机党少年们想听歌,请使劲儿戳(这里) @首席搬砖工程师 :怎样约女孩子出来吃饭,...

小小编辑 ⋅ 今天 ⋅ 8

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部