欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

没有 redis 也可以或许支撑小米在 劳务派遣系统印度把亚马逊搞挂了事件的秒杀办理方案

点击: 次  来源:昆山软开发 时间:2017-11-30

原文出处: Daniel Qian

没有redis也可以或许支撑“小米在印度把亚马逊搞挂了”事件的秒杀办理方案。

小米在印度冲破了多项记录:

  1. 4分钟内卖出了高出250,000台。 —OPS:1042次抢购/S
  2. 成为最快的手机抢购勾当。
  3. 抢购前我们收到了100万“到货提醒”。
  4. 亚马逊每分钟收到高出500万个点击。
  5. 亚马逊在这个期间每秒收到1500个订单(这是印度电商公司所有销售中最高的)。 —OPS:1500次下单请求/S

机能表示

先说一下机能表示吧,因为各人对这个较量感乐趣。

硬件情况(Tomcat、Artemis、Jmeter、Oracle,backend都在这台电脑上):

  • MacBook Pro (Retina, 15-inch, Mid 2014)
  • 2.2 GHz Intel Core i7
  • 16 GB 1600 MHz DDR3
  • 512G SSD
  • 软件情况:

  • java version “1.8.0_131″
  • Artemis 1.5.4
  • Oracle XE 11g (Docker)
  • Tomcat 8.5.14 (1个)
  • 相关设置见如何筹备情况

    测试Jmeter剧本见如何Benchmark:

  • 300线程,轮回1000次,共30w请求
  • 一共Benchmark了两次,因为JIT的干系,第二次的机能表示更好。

    第一次功效

  • QPS:300000 in 00:01:57 = 2569.8/s Avg: 108 Min: 0 Max: 41102 Err: 164 (0.05%)
  • TPS:299836订单 / 121秒 = 2477条/s
  • PS. 数据库表示从后端措施的日志中阐明的。

    第二次功效

    不重启Tomcat和Artemis,把数据库的数据规复后,昆山软件开发,重启了后端措施

  • QPS:300000 in 00:00:35 = 8527.8/s Avg: 20 Min: 0 Max: 4515 Err: 2 (0.00%)
  • TPS:246873订单 / 46 秒 = 5366条 / s
  • 数据库记录数偏少是因为Artemis行列满了,把动静丢掉了。

    架构说明

    从陈设拓扑上看,架构分为4个部门:

    1. webapp,可集群陈设,运行在Tomcat中
    2. ActiveMQ Artemis,认真webapp和backend之间的通信
    3. backend,只能单个陈设,独立运行,内部利用Disruptor
    4. Oracle数据库

    ActiveMQ Artemis

    ActiveMQ Artemis是JBoss把HornetQ捐赠到Apache基金会后更名的项目,今朝是ActiveMQ下的子项目。

    HornetQ是当年台甫鼎鼎的高机能动静中间件,因此ActiveMQ Artemis也具备相当的机能表示。

    本项目操作它做webapp和backend之间的动静通信。

    Disruptor

    Disruptor是LMAX公司开源的高机能内存行列。Disruptor可以或许让开拓人员只需写单线程代码,就可以或许得到很是强悍的机能表示,同时制止了写并发编程的难度和坑。 其本质思想在于多线程未必比单线程跑的快。

    backend操作它把从ActiveMQ Artemis得到请求串行化,判定商品库存是否富裕,更新剩余库存,最后异步写入数据库。

    利用内存、制止IO

    本项目对付库存是否富裕的判定既不在数据库层面,也没有操作redis,更不涉及任何IO。

    backend措施在启动时将数据库中的库存数据加载到内存中,库存富裕判定、更新剩余库存的行动都是在内存中举办的,共同Disruptor绕过了并发编程的内存可见性、同步、锁等问题,劳务派遣管理系统,机能很是强。

    也许有人会说,在实际项目中把商品信息都放到内存中不现实,怕会产生OOM,其实这个要看详细环境。

    在本项目中商品在内存中相关类是Item.java,在操作jol-cli(点此下载)查察其memory-layout后发明,其巨细为24byte:

    me.chanjar.jms.server.memdb.Item object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 int Item.amount N/A 16 4 Long Item.id N/A 20 4 (loss due to the next object alignment) Instance size: 24 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

    Long占用的内存也为24b:

    java.lang.Long object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 (alignment/padding gap) N/A 16 8 long Long.value N/A Instance size: 24 bytes Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

    假设你有100W商品需要秒杀,昆山软件开发,那么其占用内存 = 1,000,000 * (24b + 4b + 24b) = 52,000,000b = 49m。仅仅只占49m。

    优化项

    架构上的优化点

    1. 下单请求异步处理惩罚,请求返回的本次请求的ID,客户端拿这个ID到另行提倡请求查询功效
    2. 在秒杀期间,商品库存信息在内存中,库存判定及库存扣减都在内存中举办,之后异步到数据库
    3. 操作Disruptor将并发请求串行化,同时制止了多线程编程巨大度
    4. 丢弃数据库事务,回收最终一致性

    和JMS相关的优化点

    1. 重用JMS Connection、Session、MessageProducer、MessageConsumer,而不是每次都建设这些工具(Spring的JmsTemplate就是这么干的)
    2. 将JMS Session设定为transacted=false, AUTO_ACKNOWLEDGE
    3. 发送JMS动静时DeliveryMode=NON_PERSISTENT
    4. 封锁Artemis的重发、动静耐久机制