文档章节

金币商城架构漫谈

v
 voilin
发布于 2017/05/23 23:24
字数 1747
阅读 1
收藏 0

开篇

金币商城(下称“商城”)是众多App内的一个产品,随着App使用的用户越来越多,商城对于用户留存的提升,扮演着重要的角色;做为提高用户黏性的核心产品,在拥有很好用户体验的同时,也必须存在着一个高效、稳定的系统。

分库分表

商城,是一个基于虚拟货币(下称“金币”)进行运营的产品,也就意味着,我们需要给用户发放金币,用于用户兑换各种奖品。我们需要详细记录用户金币的收支情况,并提供给用户查询。在redis、memcache盛行的时代,构建一个几十万QPS的只读系统并不复杂,需要做到:无状态服务+多级缓存,并且能够进行水平扩展,应该就差不多了。而商城需要记录每秒十万的用户行为,需要的是每秒数十万(这里翻倍了)的数据读写(insert&update)操作,这种量级是无法在单实例数据上完成的,那么该如何分库分表。

分库分表原则

Tip 1 . 在做设计时,首先要明确3个事情

  1. 业务场景,不要空谈设计,场景是什么
  2. 目标,系统需要做到的目标是什么
  3. 分析上述两点,得到什么结论

那么,对于用户行为数据的场景是:1.用户A查询自己的所有金币记录(不能查别人的),2.查看商城内金币数量分布情况。对于第二个场景可以直接通过大数据进行统计分析(不进行详细解读)。对于第一个场景,系统需要做到的目标是:用户A只进行一次查询,就可以得到所有数据(不考虑分页场景)。分析上述两点,得到结论:按用户id进行分库分表。(分析过程有些磨叽了,哈哈,忍着) 原则明确后,能够开始进行分库分表吗?不能。需要进一步确认,如何分?分多少?扩容成本?对于数据库扩容,我们选择以2的N次幂进行扩容,这种方式的好处是,进行扩容时,只需要将数据copy一份就可以,上层应用增加数据库节点,无需考虑数据迁移问题(可靠性高),不好的地方是,会产生脏数据,这个问题并没太多影响,按照扩容后规则,删除即可。对于分表,我们将金币记录在每个库中拆成5份。

Tip 2 .为什么要进行分库分表

  1. 服务器资源(cpu、磁盘、内存、IO)遇到瓶颈
  2. 数据量变大,数据操作(crud)开销变大

部署图如下:

image

算法

数据编号=uid%4,表编号=uid%5

算法流程图如下:

image

目前业内对分库实现方案有两种

  1. 客户端分库分表,在客户端完成分库分表操作,直接链接数据库。
  2. 中间件(例如:cobar),客户端链接中间件,由中间件完成分库分表操作。

这两种方案各有利弊,客户端分库分表由于直连数据库,所以性能比使用中间件要高。而使用中间件,能够很好的将分库分表操作与客户端隔离,数据调整对上层透明,便于统一管理。

订单id生成策略

为什么要关注id生成策略?全局唯一,全局有序,业务隔离,不容易被猜到等等,这些都不是关键。重点讨论下,如何让看似无意义的id,对系统后续扩展带来意义。

Java领域著名的唯一id应该算是uuid了,不过uuid太长,而且包含字母,不适合做为订单id。通过调研,我们借鉴了Twitter的Snowflake算法来实现,算法思想是在64位长整型数字中,存储node编号,并且有序,同时支持并发。

为了便于订单数据后期扩展,我们有必要在订单id生成时,就将其做好分库分表准备(虽然目前订单量不多)

image

其中serverid,占2位,最大支持2^2台服务器(0-3),dbid占6位,最大支持2^6个数据库,其他以此类推。

最终一致性

订单数据除了用户维度查询外,还有通过商品维度来查询的场景,例如:按照商品,进行订单发货。为了解决这个问题,我们对应的策略是,将订单数据进行冗余,并按照商品维度进行存储。方案虽然简单,但是保持两个订单库数据的一致性是一件很麻烦的事情。

显然单机数据库事务是无法解决的(数据不在同一个数据库中),所以要保证数据一致性,需要引入强一致性的分布式事务,这个方案先不谈实现成本问题,就凭其超低的效率,这是我们无法接收的。所以引入异步数据同步,来实现数据的最终一致性。当然,异步同步数据也会带来数据不一致(消息总线丢消息,嘿嘿),所以我们又引入了实时监控服务,实时计算数据差异,并进行一致性同步。

流程图如下:

image

Tip 3 . 类似这种存在多个纬度的数据存储问题,都可以采用这种方案来解决

数据库高可用

这是个经典的议题了,我们在这个方案上,并无创新,用几张图来简单说明下。 image image image

Hold住流量

如何让商城在大流量下存活?这是一个类似抢购或者秒杀场景如何应对的问题,对于这个问题在@沈剑 的《秒杀系统优化思路》中已经写的很清晰了,那么,我再补充一下。

中心思路路仍然是”逐层消耗流量“,应用层面对大流量情况下,很有可能自身难保,还没来得及拦截流量,自身就已经OOM了。那么该如何优化这个方案?见下图: image

在ngx层进行优化,有两个方案:

  1. 达到应用层最大处理能力时,Hold住流量,让请求排队,逐步施放流量到应用层。
  2. 达到应用层最大处理能力时,抛弃多余流量。

我们采用的第二个方案。

==【完】==

© 著作权归作者所有

v
粉丝 0
博文 1
码字总数 1747
作品 0
东城
私信 提问
聊聊架构_Index

架构漫谈 【读后有感】架构漫谈(一):什么是架构? 【读后有感】架构漫谈(二):认识概念是理解架构的基础 【读后有感】架构漫谈(三):如何做好架构之识别问题 【读后有感】架构漫谈(四...

陶邦仁
2016/02/19
211
0
达令家模式APP系统平台定制开发

  达令家模式APP系统平台定制开发《苏134-1619-5045》达令家APP系统开发,达令家APP模式平台搭建,达令家模式开发系统。      达令家APP模式解说:   达令家app是一款电商购物类软件...

系统平台APP开发
2018/04/20
0
0
漫谈业务系统从0到1的设计

摘要:互联网公司常常将产品方向分为两类,C端和B端,C端主要是面向客户和消费者的系统,B端的范围则相对模糊,给供应商或商家使用的系统,给内部业务人员使用的系统,都统称为B端系统。C端和...

goYangKun
2017/12/14
0
0
高性能服务器开发 2018 年原创汇总

版权声明:欢迎关注我的微信公众号:「easyserverdev」,中文名:『高性能服务器开发』。 https://blog.csdn.net/analogous_love/article/details/86483266 2018 年就这样过去了,总结一下 ...

analogous_love
01/14
0
0
活动简报|DECENT参加2018中国石墨烯开发者大会

2018年1月21日,周六,DECENT应邀参加了由BLOCKCHAIN CENTER主办的石墨烯开发者技术大会。会议期间,各基于此架构的项目围绕石墨烯技术进行了主题演讲,为众开发者交流分享了石墨烯技术的独特...

DECENTplatform
04/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一个简单易用的Linux文本编辑器:nano的安装与使用

许多状况下咱们都必要编纂云主机里的文本情节,而现时用的比力多的文本编纂器是vim,这个估量许多人都以为很难用,这边伏笔VPS引荐一个简略易用的文本编纂器nano,比vim简略许多,很轻易上手...

shzwork
22分钟前
1
0
go recover

异常、错误常见语言处理 一般语言都有其错误处理方式,就以鄙人熟悉的php来距离吧。 PHP有多个级别的错误处理方式,以防止程序在还未正确执行完毕时,就造成了程序的提前结束。 try/catch/fi...

o0无忧亦无怖
41分钟前
0
0
玩转混合云+边缘计算,且看ZStack Mini!

文章导读:2019年4月16日,ZStack新品和合作伙伴战略发布会上,面向集团客户和边缘场景需求,ZStack重磅推出ZStack Mini超融合一体机(以下简称:ZStack Mini)和ZStack多云管理平台(以下简...

ZStack社区版
42分钟前
1
0
springboot 整合redis

springboot整合redis官方是有文档的: 英文看不懂可以翻译,代码应该看得懂, 这个是自动注入的。当然也可以xml注入,手动配置。 整合步骤: pom文件: <!-- spring boot web --> ...

jason_kiss
46分钟前
2
0
手机耗电问题,大部分是没有正确使用这个“锁”

当安卓设备闲置时,设备很快会进入休眠状态,以达到省电和减少CPU占用的目的。但有些应用在手机灭屏甚至系统休眠时,依然频繁占用CPU处理事件或唤醒屏幕提示用户消息,这类行为会导致手机耗电...

安卓绿色联盟
47分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部