架构面试题—大并发量的订单的解析

问题描述:做一个电商平台,如何设置一个在买家下订单后的”第60秒“发短信通知卖家发货,需要考虑的是像淘宝一样的大并发量的订单。

原问题链接

https://www.oschina.net/question/926166_2137672

最基础设计

最直观能想到的解决办法就是使用延迟队列的实现原理,其就是一个按时间排好序的队列,每次put的时候排序,然后take的时候就计算时间是否过期,如果过期则返回队列第一个元素进行消费,否则当前线程阻塞X秒后弹出第一个元素,这个就是DelayQueue 的思路。

这种实现是最基础的,但是也是问题最多的

1.DelayQueue 的最大容量是有上限的,承受不住过多的订单
2.每次来新的订单都要进行排序插入合适位置,订单量级过大时性能会很低
3.这种方案只适合单机,无法横向进行分布式扩展

升级版

针对上述的问题,我们采用Redis集群来替代DelayQueue 的设计

1.生成订单后,立即往redis群集写订单信息(信息包含下单时间)。
2.根据redis集群的结点数量,开启相应倍数(大于等于1)的线程数,n个线程扫描一个结点
3.各线程每次扫描得到的都是下单时间等于60s的订单,再对这些订单发送短信,并相应的从redis移除

这种方法解决了基础版的三个问题,在升级版里还有一些点可以进行细化优化

1.订单量爆发时,可以将每个订单直接扔进redis,将压力分给集群
2.订单流量中低时,可以利用redis的SortedSet(有序集合)来进行操作,增大redis的扫描线程的颗粒度,进而提升处理效率
3.Redis并发时的数据一致性问题,可以通过redis事务灵活解决

到这里基本就可以解决本文所说的高并发量的带时间延迟的问题了,我们再深入想一想这种设计的问题,如果时间不固定跨度广的情况下其实轮询的方式是不那么理想的会空转cpu

时间轮(TimingWheel)

Kafka中存在大量的延迟操作,比如延迟生产、延迟拉取以及延迟删除等。Kafka并没有使用JDK自带的Timer或者DelayQueue来实现延迟的功能,而是基于时间轮自定义了一个用于实现延迟功能的定时器(SystemTimer)。

JDK的Timer和DelayQueue和redis的SortedSet插入和删除操作的平均时间复杂度为O(nlog(n)),并不能满足Kafka的高性能要求,而基于时间轮可以将插入和删除操作的时间复杂度都降为O(1)。

时间轮的应用并非Kafka独有,其应用场景还有很多,在Netty、Akka、Quartz、Zookeeper等组件中都存在时间轮的踪影。

参考下图,Kafka中的时间轮(TimingWheel)是一个存储定时任务的环形队列,每个元素可以存放一个定时任务列表(TimerTaskList)。TimerTaskList是一个双向链表,元素是(TimerTaskEntry),其中封装了真正的定时任务TimerTask。

image.png

时间轮由多个时间格组成,每个时间格代表当前时间轮的基本时间跨度(tickMs)。时间轮的时间格个数是固定的,可用wheelSize来表示,那么整个时间轮的总体时间跨度(interval)可以通过公式 tickMs × wheelSize计算得出。

时间轮还有一个表盘指针(currentTime)currentTime当前指向的时间格也属于到期部分,表示刚好到期,需要处理此时间格所对应的TimerTaskList的所有任务。

时间轮就像时钟一样,可以通过秒表指向谁就执行谁,当时间跨度大时,可以增加时间轮的级别,如图

image.png

第一层的时间轮tickMs=1ms, wheelSize=20, interval=20ms。
第二层的时间轮的tickMs为第一层时间轮的interval,即为20ms。每一层时间轮的wheelSize是固定的,都是20,那么第二层的时间轮的总体时间跨度interval为400ms。
以此类推,这个400ms也是第三层的tickMs的大小,第三层的时间轮的总体时间跨度为8000ms。

时间轮的优点

1.把任务轮询的多个线程改装为了秒针的单一轮询
2.从毫秒级或者秒级任务获取执行改装为批量的范围获取
3.扩展性极好,颗粒度可以根据业务场景自适应
4.插入和删除操作的时间复杂度都降为O(1)

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

推荐阅读更多精彩内容