1号店订单系统水平分库的实践之路以及关键步骤

转载:1号店订单系统水平分库的实践之路以及关键步骤

随着大型互联网应用的发展,海量数据的存储和访问成为系统设计的瓶颈,分布式处理成为不二选择。数据库拆分,特别是水平分库是个高难度的活,涉及一系列技术决策。

本人有幸负责1号店订单水平分库的方案设计及实施落地,本人结合项目实践,对水平分库做一个系统地剖析,希望为大家水平分库(包括去IOE)改造提供总体思路,主要内容包括:

水平分库说明

分库维度-- 根据哪个字段分库

分库策略-- 记录如何分配到不同库

分库数量-- 初始库数量及库数量如何增长

路由透明-- 如何实现库路由,支持应用透明

分页处理-- 跨多个库的分页case如何处理

Lookup映射—非分库字段映射到分库字段,实现单库访问

整体架构-- 分库的整体技术架构

上线步骤-- 分库改造实施上线

项目总结

水平分库说明

数据库拆分有两种:

1)   垂直分库

数据库里的表太多,拿出部分到新的库里,一般是根据业务划分表,关系密切的表放同一数据库,应用修改数据库连接即可,比较简单。

2)   水平分库

某张表太大,单个数据库存储不下或访问性能有压力,把一张表拆成多张,每张表存放部分记录,保存在不同的数据库里,水平分库需要对系统做大的改造。

1号店核心的订单表存储在Oracle数据库,记录有上亿条,字段有上百个,访问的模式也是复杂多样,随着业务快速增长,无论存储空间或访问性能都面临巨大挑战,特别在大促时,订单库已成为系统瓶颈。

通常有两种解决办法:

Scale up,升级Oracle数据库所在的物理机,提升内存/存储/IO性能,但这种升级费用昂贵,并且只能满足短期需要。

Scale out,把订单库拆分为多个库,分散到多台机器进行存储和访问,这种做法支持水平扩展,可以满足长远需要。

1号店采取后一种做法,它的订单库主要包括订单主表/订单明细表(记录商品明细)/订单扩展表,水平分库即把这3张表的记录分到多个数据库中,订单水平分库效果如下图所示:

原来一个Oracle库被多个MySQL库取代,支持1主多备和读写分离,主备之间通过MySQL自带的数据同步机制(SLA<1秒),所有应用通过订单服务访问订单数据。

分库维度

水平分库首先要考虑根据哪个字段作为分库维度,选择标准是尽量避免应用代码和SQL性能受影响,这就要求当前SQL在分库后,访问尽量落在单个库里,否则单库访问变成多库扫描,读写性能和应用逻辑都会受较大影响。

对于订单拆分,大家首先想到的是按照用户Id拆分,结论没错,但最好还是数据说话,不能拍脑袋。好的做法是首先收集所有SQL,挑选where语句最常出现的过滤字段,比如用户Id/订单Id/商家Id,每个字段在SQL中有三种情况:

单Id过滤,如用户Id=?

多Id过滤,如用户Id IN (?,?,?)

该Id不出现

然后进一步统计,假设共有500个SQL访问订单库,3个过滤字段出现情况如下:

过滤字段单Id过滤多Id过滤不出现

用户Id12040330

订单Id6080360

商家Id150485

结论明显,应该选择用户Id进行分库。

等一等,这只是静态分析,每个SQL访问的次数是不一样的,因此还要分析每个SQL的访问量。我们分析了Top15执行最多的SQL (它们占总执行次数85%),如果按照用户Id分库,这些SQL 85%落到单个数据库, 13%落到多个数据库,只有2%需要遍历所有数据库,明显优于使用其他Id进行分库。

通过量化分析,我们知道按照用户Id分库是最优的,同时也大致知道分库对现有系统的影响,比如这个例子中,85%的SQL会落到单个数据库,这部分的访问性能会优化,坚定了各方对分库的信心。

分库策略

分库维度确定后,如何把记录分到各个库里呢?一般有两种方式:

根据数值范围,比如用户Id为1-9999的记录分到第一个库,10000-20000的分到第二个库,以此类推。

根据数值取模,比如用户Id mod n,余数为0的记录放到第一个库,余数为1的放到第二个库,以此类推。

两种分法的优劣比较如下:

评价指标按照范围分库按照Mod分库

库数量前期数目比较小,可以随用户/业务按需增长前期即根据mode因子确定库数量,数目一般比较大

访问性能前期库数量小,全库查询消耗资源少,单库查询性能略差前期库数量大,全库查询消耗资源多,单库查询性能略好

调整库数量比较容易,一般只需为新用户增加库,老库拆分也只影响单个库困难,改变mod因子导致数据在所有库之间迁移

数据热点新旧用户购物频率有差异,有数据热点问题新旧用户均匀到分布到各个库,无热点

实践中,为了处理简单,选择mod分库的比较多。同时二次分库时,为了数据迁移方便,一般是按倍数增加,比如初始4个库,二次分裂为8个,再16个。这样对于某个库的数据,一半数据移到新库,剩余不动,对比每次只增加一个库,所有数据都要大规模变动。

补充下,mod分库一般每个库记录数比较均匀,但也有些数据库,存在超级Id,这些Id的记录远远超过其他Id,比如在广告场景下,某个大广告主的广告数可能占总体很大比例。如果按照广告主Id取模分库,某些库的记录数会特别多,对于这些超级Id,需要提供单独库来存储记录。

分库数量

分库数量首先和单库能处理的记录数有关,一般来说,Mysql 单库超过5000万条记录,Oracle单库超过1亿条记录,DB压力就很大(当然处理能力和字段数量/访问模式/记录长度有进一步关系)。

在满足上述前提下,如果分库数量少,达不到分散存储和减轻DB性能压力的目的;如果分库的数量多,好处是每个库记录少,单库访问性能好,但对于跨多个库的访问,应用程序需要访问多个库,如果是并发模式,要消耗宝贵的线程资源;如果是串行模式,执行时间会急剧增加。

最后分库数量还直接影响硬件的投入,一般每个分库跑在单独物理机上,多一个库意味多一台设备。所以具体分多少个库,要综合评估,一般初次分库建议分4-8个库。

路由透明

分库从某种意义上来说,意味着DB schema改变了,必然影响应用,但这种改变和业务无关,所以要尽量保证分库对应用代码透明,分库逻辑尽量在数据访问层处理。当然完全做到这一点很困难,具体哪些应该由DAL负责,哪些由应用负责,这里有一些建议:

对于单库访问,比如查询条件指定用户Id,则该SQL只需访问特定库。此时应该由DAL层自动路由到特定库,当库二次分裂时,也只要修改mod 因子,应用代码不受影响。

对于简单的多库查询,DAL负责汇总各个数据库返回的记录,此时仍对上层应用透明。

对于带聚合运算的多库查询,如带groupBy/orderby/min/max/avg等关键字,建议DAL汇总单个库返回的结果,上层应用做进一步处理。一方面DAL全面支持各种case,实现很复杂;另一方面,从1号店实践来看,这样的例子不多,在上层应用作针对性处理,更加灵活。

DAL可进一步细分为JDBC和DAL两层,基于JDBC层面实现分库路由,系统开发难度大,灵活性低,目前也没有很好的成功案例;一般是基于持久层框架进一步封装成DDAL(分布式数据访问层),实现分库路由,1号店DAL即基于iBatis进行上层封装而来。

分页处理

分库后,有些分页查询需要遍历所有库,这些case是分库最大的受害者L。

举个分页的例子,比如要求按时间顺序展示某个商家的订单,每页100条记录,由于是按商家查询,需要遍历所有数据库,假设库数量是8,我们来看下分页处理逻辑:

如果取第1页数据,则需要从每个库里按时间顺序取前100条记录,8个库汇总后有800条,然后对这800条记录在应用里进行二次排序,最后取前100条。

如果取第10页数据,则需要从每个库里取前1000(100*10)条记录,汇总后有8000条记录,然后对这8000条记录二次排序后取(900,1000)条记录。

分库情况下,对于第k页记录,每个库要多取100*(k-1)条记录,所有库加起来,多取的记录更多,所以越是靠后的分页,系统要耗费更多内存和执行时间。

对比没分库的情况,无论取那一页,都只要从单个DB里取100条记录,而且无需在应用内部做二次排序,非常简单。

那如何解决分库情况下的分页问题呢?有以下几种办法:

如果是在前台应用提供分页,则限定用户只能看前面n页,这个限制在业务上也是合理的,一般看后面的分页意义不大(如果一定要看,可以要求用户缩小范围重新查询)。

如果是后台批处理任务要求分批获取数据,则可以加大page size,比如每次获取5000条记录,有效减少分页数(当然离线访问一般走备库,避免冲击主库)。

分库设计时,一般还有配套大数据平台汇总所有分库的记录,有些分页查询可以考虑走大数据平台。

Lookup映射

分库字段只有一个,比如这里是用户Id,但订单表还有其他字段可唯一区分记录,比如订单Id,给定一个订单Id,相应记录一定在某个库里。如果盲目地查询所有分库,则带来不必要的开销,Lookup映射可根据订单Id,找到相应的用户Id,从而实现单库定位。

可以事先检索所有订单Id和用户Id,保存在Lookup表里,Lookup表的记录数和订单库记录总数相等,但它只有2个字段,所以存储和查询性能都不是问题。实际使用时,一般通过分布式缓存来优化Lookup性能。对于新增的订单,除了写订单表,同时要写Lookup表。

整体架构

1号店订单水平分库的总体技术架构如下图所示:

上层应用通过订单服务/分库代理和DAL访问数据库。

代理对订单服务实现功能透明,包括聚合运算,非用户Id到用户Id的映射。

Lookup表用于订单Id/用户Id映射,保证按订单Id访问时,可以直接落到单个库,Cache是Lookup的内存数据映像,提升性能,cache故障时,直接访问Lookup表。

DAL提供库的路由,根据用户Id定位到某个库,对于多库访问,DAL支持可选的并发访问模式,并支持简单记录汇总。

Lookup表初始化数据来自于现有分库数据,新增记录时,直接由代理异步写入。

上线步骤

订单表是核心业务表,它的水平拆分影响很多业务,本身的技术改造也很大,很容易出纰漏,上线时,必须谨慎考虑,1号店整个方案实施过程如下:

首先实现Oracle和MySQL两套库并行,所有数据访问指向Oracle库,通过数据同步程序把数据从Oracle拆分到多个MySQL分库,比如3分钟增量同步一次。

按照上述架构图搭建整个体系,选择几个对数据实时性不高的访问例子(如访问历史订单),转向MySQL分库访问,然后逐渐增加更多非实时case,以检验整套体系可行性。

如果性能和功能都没问题,再一次性把所有实时读写访问转向MySQL,废弃Oracle。

这个上线步骤多了数据同步程序的开发(大约1人周工作量,风险很低),但分散了风险,把第一步的技术风险(Lookup/DAL等基础设施改造)和第二步的业务功能风险(Oracle改MySQL语法)分开。1号店两阶段上线都是一次性成功,特别是第二阶段上线,100多个依赖方应用简单重启即完成升级,中间没有出现一例较大问题。

项目总结

1号店完成订单水平分库的同时,把订单库从Oralce迁到MySQL,设备从小型机换成X86服务器,通过水平分库和去IOE,不但支持订单量未来增长,并且总体成本也大幅下降。

由于去IOE和订单分库一起实施,带来双重的性能影响,我们花了很大精力做性能测试,为了模拟真实场景,大家通过Tcpcopy把线上实际的查询流量引到测试环境,先后经过13轮的性能测试,最终6个MySQL库相对一个Oracle,平均SQL执行时间基本持平,性能不降低的情况下,优化了架构,节省了成本。

对核心表做水平分库之前,必须先做好服务化,即外部系统通过统一的订单服务访问相关表,不然很容易遗漏一些SQL。

1号店最终是根据用户Id后三位取模,初始分6个库,理论上支持多达768个库,并且对订单Id生成规则做了改造,使其包括用户Id后三位,这样新订单Id本身包含库定位所需信息,无需走Lookup机制,随着老订单归档到历史库,上述架构中lookup部分可废弃。

水平分库是一项系统性工作,首先需要在理论模式指导下,结合实际情况,每个方面做出最优选择。其次对于特殊场景,如跨库分页,没有银弹,可以灵活处理,不走常规路。最后控制好节奏,系统改造、数据迁移、上线实施等各个环节做好衔接,全局一盘棋。

大胆设计,小心求证,谨慎实施,分库并不难。

作者介绍

王庆友,前1号店首席架构师,先后就职于ebay、腾讯、1号店等公司,精通电商业务,擅长复杂系统业务建模和架构分析,同时在构建大规模的分布式系统方 面有丰富实践,尤其在大型系统的SOA改造方面有很深入的理论和实践,目前在寻找合作机会,微信号Brucetwins,个人公众号”架构之道”,欢迎一起聊架构。随着大型互联网应用的发展,海量数据的存储和访问成为系统设计的瓶颈,分布式处理成为不二选择。数据库拆分,特别是水平分库是个高难度的活,涉及一系列技术决策。

本人有幸负责1号店订单水平分库的方案设计及实施落地,本人结合项目实践,对水平分库做一个系统地剖析,希望为大家水平分库(包括去IOE)改造提供总体思路,主要内容包括:

水平分库说明

分库维度-- 根据哪个字段分库

分库策略-- 记录如何分配到不同库

分库数量-- 初始库数量及库数量如何增长

路由透明-- 如何实现库路由,支持应用透明

分页处理-- 跨多个库的分页case如何处理

Lookup映射—非分库字段映射到分库字段,实现单库访问

整体架构-- 分库的整体技术架构

上线步骤-- 分库改造实施上线

项目总结

水平分库说明

数据库拆分有两种:

1)   垂直分库

数据库里的表太多,拿出部分到新的库里,一般是根据业务划分表,关系密切的表放同一数据库,应用修改数据库连接即可,比较简单。

2)   水平分库

某张表太大,单个数据库存储不下或访问性能有压力,把一张表拆成多张,每张表存放部分记录,保存在不同的数据库里,水平分库需要对系统做大的改造。

1号店核心的订单表存储在Oracle数据库,记录有上亿条,字段有上百个,访问的模式也是复杂多样,随着业务快速增长,无论存储空间或访问性能都面临巨大挑战,特别在大促时,订单库已成为系统瓶颈。

通常有两种解决办法:

Scale up,升级Oracle数据库所在的物理机,提升内存/存储/IO性能,但这种升级费用昂贵,并且只能满足短期需要。

Scale out,把订单库拆分为多个库,分散到多台机器进行存储和访问,这种做法支持水平扩展,可以满足长远需要。

1号店采取后一种做法,它的订单库主要包括订单主表/订单明细表(记录商品明细)/订单扩展表,水平分库即把这3张表的记录分到多个数据库中,订单水平分库效果如下图所示:

原来一个Oracle库被多个MySQL库取代,支持1主多备和读写分离,主备之间通过MySQL自带的数据同步机制(SLA<1秒),所有应用通过订单服务访问订单数据。

分库维度

水平分库首先要考虑根据哪个字段作为分库维度,选择标准是尽量避免应用代码和SQL性能受影响,这就要求当前SQL在分库后,访问尽量落在单个库里,否则单库访问变成多库扫描,读写性能和应用逻辑都会受较大影响。

对于订单拆分,大家首先想到的是按照用户Id拆分,结论没错,但最好还是数据说话,不能拍脑袋。好的做法是首先收集所有SQL,挑选where语句最常出现的过滤字段,比如用户Id/订单Id/商家Id,每个字段在SQL中有三种情况:

单Id过滤,如用户Id=?

多Id过滤,如用户Id IN (?,?,?)

该Id不出现

然后进一步统计,假设共有500个SQL访问订单库,3个过滤字段出现情况如下:

过滤字段单Id过滤多Id过滤不出现

用户Id12040330

订单Id6080360

商家Id150485

结论明显,应该选择用户Id进行分库。

等一等,这只是静态分析,每个SQL访问的次数是不一样的,因此还要分析每个SQL的访问量。我们分析了Top15执行最多的SQL (它们占总执行次数85%),如果按照用户Id分库,这些SQL 85%落到单个数据库, 13%落到多个数据库,只有2%需要遍历所有数据库,明显优于使用其他Id进行分库。

通过量化分析,我们知道按照用户Id分库是最优的,同时也大致知道分库对现有系统的影响,比如这个例子中,85%的SQL会落到单个数据库,这部分的访问性能会优化,坚定了各方对分库的信心。

分库策略

分库维度确定后,如何把记录分到各个库里呢?一般有两种方式:

根据数值范围,比如用户Id为1-9999的记录分到第一个库,10000-20000的分到第二个库,以此类推。

根据数值取模,比如用户Id mod n,余数为0的记录放到第一个库,余数为1的放到第二个库,以此类推。

两种分法的优劣比较如下:

评价指标按照范围分库按照Mod分库

库数量前期数目比较小,可以随用户/业务按需增长前期即根据mode因子确定库数量,数目一般比较大

访问性能前期库数量小,全库查询消耗资源少,单库查询性能略差前期库数量大,全库查询消耗资源多,单库查询性能略好

调整库数量比较容易,一般只需为新用户增加库,老库拆分也只影响单个库困难,改变mod因子导致数据在所有库之间迁移

数据热点新旧用户购物频率有差异,有数据热点问题新旧用户均匀到分布到各个库,无热点

实践中,为了处理简单,选择mod分库的比较多。同时二次分库时,为了数据迁移方便,一般是按倍数增加,比如初始4个库,二次分裂为8个,再16个。这样对于某个库的数据,一半数据移到新库,剩余不动,对比每次只增加一个库,所有数据都要大规模变动。

补充下,mod分库一般每个库记录数比较均匀,但也有些数据库,存在超级Id,这些Id的记录远远超过其他Id,比如在广告场景下,某个大广告主的广告数可能占总体很大比例。如果按照广告主Id取模分库,某些库的记录数会特别多,对于这些超级Id,需要提供单独库来存储记录。

分库数量

分库数量首先和单库能处理的记录数有关,一般来说,Mysql 单库超过5000万条记录,Oracle单库超过1亿条记录,DB压力就很大(当然处理能力和字段数量/访问模式/记录长度有进一步关系)。

在满足上述前提下,如果分库数量少,达不到分散存储和减轻DB性能压力的目的;如果分库的数量多,好处是每个库记录少,单库访问性能好,但对于跨多个库的访问,应用程序需要访问多个库,如果是并发模式,要消耗宝贵的线程资源;如果是串行模式,执行时间会急剧增加。

最后分库数量还直接影响硬件的投入,一般每个分库跑在单独物理机上,多一个库意味多一台设备。所以具体分多少个库,要综合评估,一般初次分库建议分4-8个库。

路由透明

分库从某种意义上来说,意味着DB schema改变了,必然影响应用,但这种改变和业务无关,所以要尽量保证分库对应用代码透明,分库逻辑尽量在数据访问层处理。当然完全做到这一点很困难,具体哪些应该由DAL负责,哪些由应用负责,这里有一些建议:

对于单库访问,比如查询条件指定用户Id,则该SQL只需访问特定库。此时应该由DAL层自动路由到特定库,当库二次分裂时,也只要修改mod 因子,应用代码不受影响。

对于简单的多库查询,DAL负责汇总各个数据库返回的记录,此时仍对上层应用透明。

对于带聚合运算的多库查询,如带groupBy/orderby/min/max/avg等关键字,建议DAL汇总单个库返回的结果,上层应用做进一步处理。一方面DAL全面支持各种case,实现很复杂;另一方面,从1号店实践来看,这样的例子不多,在上层应用作针对性处理,更加灵活。

DAL可进一步细分为JDBC和DAL两层,基于JDBC层面实现分库路由,系统开发难度大,灵活性低,目前也没有很好的成功案例;一般是基于持久层框架进一步封装成DDAL(分布式数据访问层),实现分库路由,1号店DAL即基于iBatis进行上层封装而来。

分页处理

分库后,有些分页查询需要遍历所有库,这些case是分库最大的受害者L。

举个分页的例子,比如要求按时间顺序展示某个商家的订单,每页100条记录,由于是按商家查询,需要遍历所有数据库,假设库数量是8,我们来看下分页处理逻辑:

如果取第1页数据,则需要从每个库里按时间顺序取前100条记录,8个库汇总后有800条,然后对这800条记录在应用里进行二次排序,最后取前100条。

如果取第10页数据,则需要从每个库里取前1000(100*10)条记录,汇总后有8000条记录,然后对这8000条记录二次排序后取(900,1000)条记录。

分库情况下,对于第k页记录,每个库要多取100*(k-1)条记录,所有库加起来,多取的记录更多,所以越是靠后的分页,系统要耗费更多内存和执行时间。

对比没分库的情况,无论取那一页,都只要从单个DB里取100条记录,而且无需在应用内部做二次排序,非常简单。

那如何解决分库情况下的分页问题呢?有以下几种办法:

如果是在前台应用提供分页,则限定用户只能看前面n页,这个限制在业务上也是合理的,一般看后面的分页意义不大(如果一定要看,可以要求用户缩小范围重新查询)。

如果是后台批处理任务要求分批获取数据,则可以加大page size,比如每次获取5000条记录,有效减少分页数(当然离线访问一般走备库,避免冲击主库)。

分库设计时,一般还有配套大数据平台汇总所有分库的记录,有些分页查询可以考虑走大数据平台。

Lookup映射

分库字段只有一个,比如这里是用户Id,但订单表还有其他字段可唯一区分记录,比如订单Id,给定一个订单Id,相应记录一定在某个库里。如果盲目地查询所有分库,则带来不必要的开销,Lookup映射可根据订单Id,找到相应的用户Id,从而实现单库定位。

可以事先检索所有订单Id和用户Id,保存在Lookup表里,Lookup表的记录数和订单库记录总数相等,但它只有2个字段,所以存储和查询性能都不是问题。实际使用时,一般通过分布式缓存来优化Lookup性能。对于新增的订单,除了写订单表,同时要写Lookup表。

整体架构

1号店订单水平分库的总体技术架构如下图所示:

上层应用通过订单服务/分库代理和DAL访问数据库。

代理对订单服务实现功能透明,包括聚合运算,非用户Id到用户Id的映射。

Lookup表用于订单Id/用户Id映射,保证按订单Id访问时,可以直接落到单个库,Cache是Lookup的内存数据映像,提升性能,cache故障时,直接访问Lookup表。

DAL提供库的路由,根据用户Id定位到某个库,对于多库访问,DAL支持可选的并发访问模式,并支持简单记录汇总。

Lookup表初始化数据来自于现有分库数据,新增记录时,直接由代理异步写入。

上线步骤

订单表是核心业务表,它的水平拆分影响很多业务,本身的技术改造也很大,很容易出纰漏,上线时,必须谨慎考虑,1号店整个方案实施过程如下:

首先实现Oracle和MySQL两套库并行,所有数据访问指向Oracle库,通过数据同步程序把数据从Oracle拆分到多个MySQL分库,比如3分钟增量同步一次。

按照上述架构图搭建整个体系,选择几个对数据实时性不高的访问例子(如访问历史订单),转向MySQL分库访问,然后逐渐增加更多非实时case,以检验整套体系可行性。

如果性能和功能都没问题,再一次性把所有实时读写访问转向MySQL,废弃Oracle。

这个上线步骤多了数据同步程序的开发(大约1人周工作量,风险很低),但分散了风险,把第一步的技术风险(Lookup/DAL等基础设施改造)和第二步的业务功能风险(Oracle改MySQL语法)分开。1号店两阶段上线都是一次性成功,特别是第二阶段上线,100多个依赖方应用简单重启即完成升级,中间没有出现一例较大问题。

项目总结

1号店完成订单水平分库的同时,把订单库从Oralce迁到MySQL,设备从小型机换成X86服务器,通过水平分库和去IOE,不但支持订单量未来增长,并且总体成本也大幅下降。

由于去IOE和订单分库一起实施,带来双重的性能影响,我们花了很大精力做性能测试,为了模拟真实场景,大家通过Tcpcopy把线上实际的查询流量引到测试环境,先后经过13轮的性能测试,最终6个MySQL库相对一个Oracle,平均SQL执行时间基本持平,性能不降低的情况下,优化了架构,节省了成本。

对核心表做水平分库之前,必须先做好服务化,即外部系统通过统一的订单服务访问相关表,不然很容易遗漏一些SQL。

1号店最终是根据用户Id后三位取模,初始分6个库,理论上支持多达768个库,并且对订单Id生成规则做了改造,使其包括用户Id后三位,这样新订单Id本身包含库定位所需信息,无需走Lookup机制,随着老订单归档到历史库,上述架构中lookup部分可废弃。

水平分库是一项系统性工作,首先需要在理论模式指导下,结合实际情况,每个方面做出最优选择。其次对于特殊场景,如跨库分页,没有银弹,可以灵活处理,不走常规路。最后控制好节奏,系统改造、数据迁移、上线实施等各个环节做好衔接,全局一盘棋。

大胆设计,小心求证,谨慎实施,分库并不难。

作者介绍

王庆友,前1号店首席架构师,先后就职于ebay、腾讯、1号店等公司,精通电商业务,擅长复杂系统业务建模和架构分析,同时在构建大规模的分布式系统方 面有丰富实践,尤其在大型系统的SOA改造方面有很深入的理论和实践,目前在寻找合作机会,微信号Brucetwins,个人公众号”架构之道”,欢迎一起聊架构。

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

推荐阅读更多精彩内容