淘宝千亿量级超大规模电商系统后端数据库设计实践-演道网

冬日来临,春天还会远吗?不管四季变换,PHP技术大全永远是你身边最温情的陪伴。

问题背景

    电商网站诸如jd.com,tmall.com等,订单数据量一直在膨胀,每年产生个上千亿那都是正常的,要知道,人家阿里11.11(狗节?)那天,每一秒平均产生15.7w笔订单,也就是说当天一共产生了15.7*10000*86400=13,564,800,000,

嗯,135.65亿订单。那么问题来了,像这样超大规模的订单数据的存储,如果事先没有想好可伸缩的数据架构方案,那么在不远的将来肯定会到达业务性能的瓶颈,成为限制发展的首要技术难题。

分库分表的维度选择

    通常来说分库分表都是通过订单id经过简单hash得到一个数字hash,然后采用一定的算法获取hash值得后五位mod(32*32=1024)得到,32(数据库)*32(每个数据库32个分表),这里最好保持hash得到的值能够以最大的随机性命中这1024张表中的其中一张表,但是问题来了,这样分库分表,还是无法解决若干个数据库的若干个表读写IO很高的问题

需要解决的几个问题

这样分库分表订单id如何高效生成?snowflake算法?不建议,为什么?我们设计分库分表的最终目的是为了服务用户,同时便于开发运维以及销售运营等系统的设计,所以猿哥建议我们最终应该以用户的uid为主线,从uid出发,所以与此uid相关的订单,礼品,评论,签到等一系列表都最好放在同一个库的同一张表里面,方便进行关联查询。那么新的问题来了,我们把新注册的用户应该放在哪个库的哪张表呢?猿哥想的是这样的,可以通过几张内存hashtable来记录这些字段信息ht_load_balance(db_index,table_index,day_[read/write]_[peak|valley],month_[read/write]_[peak|valley],year_[read/write]_[peak|valley],total_count),这张表用于记录指定库指定表的负载统计情况,可以看到它统计的最小维度是day(天),这个信息的同步计划可以根据以往经验固定在凌晨3点左右执行。

接下来,我们就可以通过这个ht_load_balance来设计负载算法,保证每一个数据库,以及每一个数据库中的每一张表的的Read/Write的IO是均衡的,关于这个算法的选择思路,请小伙伴们自己发挥想象力,在此就不打算深入探讨了。假设现在我们注册一个新用户,通过上面的负载均衡算法挖掘到了db100,table1000(请容许猿哥吹牛逼!),然后我们把新用户的数据插入到表中得到一个自增id,接着问题来了,我们怎么知道,这个用户的uid放在那张表呢?这个简单,还是使用hashtable来存放(uid=>dbIndex_tableIndex,我们看到这是最简单的kv store方式存储的,可以考虑使用redis的hashtable,或者google的基于GFS的bigtable来实现,这个速度快得没话说!假设有100亿个账户,接着,我们还必须创建(order_id=>uid),(product_id=>uid),(gift_id=>uid),(comment_id=>uid)等多组映射关系,方便路由多个id到指定的库表,这样我们就把面向用户的库表设计好了,接着新的问题来了。

1)运营想搞一个促销活动,打算向最近三个月购买总额超过2000元的客户推送一条促销的短信消息。

答案:好解决,分布式作业,通过制定的查询条件找到满足条件的用户手机号码,接着发送短信。

2)运营想知道销售的主要来源区域便于加强运营分析能力,当然这个也简单。

3)公司新推出了100款重点促销的商品(分布在不同的库表中),想知道这几款商品的实时销售量,点击量,这个貌似也不难。

4)接下来,难点来了,销售想知道商家的销售额排行的前100w名,该怎么办?这就有点难办了!猿哥的解决思路还是创建一个(uid=>sale_amount)kv-store,用来存储实时变更的销售额信息,离线计算。

其它诸如大数据分析,离线任务(客户端推送,短信群发等)都可以通过类似的思路解决。

系统可扩展性

通过上面的ht_load_balance负载均衡算法,我们知道了新来的用户数据应该放到那个数据库,当指定库的指定表达到最佳性能数值时(假设total_count=500w条记录,这个数值的选择可以通过一些压测模拟和生产统计手段分析得到)时,我们添加一个新的数据库服务器,并把数据库初始化的库表信息同步到ht_load_balance记录中,那么新的用户数据总是会命中新的数据库服务器,并在一定的时候达到平衡,当这个数据量快要达到临界值的时候,系统管理员,快速响应,再次部署新的服务器,从而保证服务器的扩展性。

系统的高可用性

由于极小的故障概率可能会出现的原因,通常每一台数据库服务器都会有一到多台地域彼此隔离的冷热双备服务器待命,就算其中一台出现故障,服务器节点故障侦测到异常,会马上进行切换。

本文还有几个主题

  1. 旧数据迁移原则,例如腾讯qq超过一定的年限便开始冻结,甚至释放,而这些数据都会被迁移到旧数据服务器中存底。

  2. LRU算法,让最活跃的用户享受最快速的服务。

  3. 。。。

当然还有一些细节上的问题,限于篇幅和精力,本文就不在深究了,有兴趣的小伙伴可以自己发散思维,尽情思考,争取把这个世界架构的美妙得不可言。

参考文章列表:

  1. 大众点评订单系统分库分表实践:http://tech.meituan.com/dianping_order_db_sharding.html

  2. google bigtable:

    http://baike.baidu.com/item/BigTable

  3. 关于bigtable的论文:

    http://dblab.xmu.edu.cn/post/google-bigtable/

4.GFS:

http://baike.baidu.com/item/GFS/1813072

微信扫描二维码,关注PHP技术大全!

让知识地带无限蔓延!

转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn