支撑百万级传感器的延时队列

支撑百万级传感器的延时队列

文/升哲科技刘鹏
摘要:本文主要描述升哲科技在打造物联智慧城市平台过程中关于如何实现延时队列服务的技术选型经验、延时队列服务的架构设计以及延时队列的底层细节实现原理。
升哲科技是一家物联网与人工智能领域的国家高新技术企业、独角兽企业。
要打造物联智慧城市平台,在业务中涉及到各种延时任务的需求,例如设备定时空气开关,定时更新设备状态,定时提醒等等,基于这些需求,需要一个可靠、实时、海量的延时队列服务作为基础设施。
那么延时队列是什么呢?延时队列不同于消息队列按照先入先出(FIFO)的顺序来消费,而是根据消息指定时间延时消费。延时队列的使用在我们日常应用也非常多,比如:
在电商平台购物,在30分钟内没有支付自动取消订单;
待处理的工单超过1天未处理,二次发送提醒。
以上场景往往都需要延时队列实现。
早期延时队列的实现采用了数据库扫表方式,服务定期查询到期的任务,再通过Kafka来中转消息。当任务量小,延时精度要求低时扫表方式还能应对,然而随着业务增长、任务数量不断增多,延时时间精度要求也变高,扫表的方式已经无法满足我们的业务,于是我们开始探索新的技术方案来支撑百万级任务的延时队列。
延时队列的设计目标
1.高可用:多副本部署,保证服务不出现单点故障;
2.可扩展:可随着业务量增长来扩容,同时生产消费的请求延时也要低;
3.兼容旧接口,保证旧的服务不需要做任何修改;
4.消息传递可靠,至少保证一次送达。
在开源社区已经存在一些解决方案:
方案
描述
Beanstalkd
BeanstalkdC语言实现,我们团队主要采用Golang和Java,二次开发有难度,beanstalkd不支持集群部署,高可用无法保证。
RabbitMQ延时队列
RabbitMQ提供了延时队列插件,需要单独开启插件使用,其原理是通过死信队列实现。
NSQ
NSQ开源延时队列,NSQ支持延时队列。
DelayQueue延时队列
JDK中提供了一组实现延时队列的API,位于Java.util.concurrent包下DelayQueue。
时间轮算法
时间轮是一个算法,在Netty、Akka、Quartz、ZooKeeper、Kafka等组件中都有使用,适合做统一调度器。
RedisSortedSet
RedisSortedSet利用它的score属性,启用一个线程轮询,根据score获取超时的数据,然后触发超时操作。
考虑到运维难度和可扩展性,最终我们选择了开源项目Lmstfy作为基础来进行二次开发,选择Lmstfy的原因如下:
●无状态服务,使用Redis来持久化,Redis的高可用方案已经非常成熟,在公/私有云都有Paas服务可使用;
●支持扩容,可以配置多个Redis集群;
●提供Java/Go/Rust/PHP客户端,监控面板完善;
●采用Golang开发,高并发性能优秀,也方便后续二次开发。
1.Delayer:无状态服务,提供给业务服务调用,兼容旧接口,在Delayer这一层直接操作Redis实现了任务删除和更新任务等等功能;
2.Lmstfy:无状态服务,提供延时队列基础服务,底层实现采用;
3.RedisSentinel集群:保证Redis发生故障时自动主备切换。
●namespace-用于隔离业务,也可以通过配置namespace绑定不同的Redis集群;
●queue-队列,用区分同一业务不同消息类型;
●job-业务定义的业务,主要包含以下几个属性:
○id:任务ID,全局唯一;
○delay:任务延时下发时间,单位是秒;
○tries:任务最大重试次数,tries=N表示任务会最多下发N次;
○ttr(timetorun):任务预期执行时间,超过ttr则认为任务消费失败,触发任务自动重试。
Lmstfy的Redis存储由四部分组成:
●Timer:使用ZSET结构来存储延时任务,Score即任务的到期时间来排序;
●Readyqueue-使用LIST结构,存储已经到期的延时任务,实现FIFO消费;
●Deadletter-使用LIST结构,消费失败(重试次数到达上限)的任务,可以手动重新放回到队列;
●Jobpool–string类型,存储消息meta信息;
●Jobmapping-string-存储应用自定义id和job的关联关系。
创建任务会生成一个JobID,JobID包括写入时间戳、随机数和延时时长,然后将任务的meta信息写入Redis,Key为j/{namespace}/queue/{id},当任务延时时间(delay)=0,(实时消息队列我们使用Kafka)表示不需要延时则直接写到ReadyQueue(List),当延时时间(delay)=n(n>0),表示需要延时,将延时加上当前系统时间作为绝对时间戳写到Timer(sortedset),Timer的实现是利用ZSET根据绝对时间戳进行排序,再由一个goroutine定期轮询将到期的任务通过redisluascript来将数据转移到ReadyQueue(List)中。
支持延时的任务队列本质上是两个数据结构的结合:ReadyQueue(LIST)和SortedSet。
SortedSet用来实现延时的部分,将任务按照到期时间戳升序存储,随后定期将到期的任务迁移至ReadyQueue(LIST)。
任务的具体内容只会存储一份在Jobpool里面,其他的如ReadyQueue只是存储Jobid,这样可以节省内存空间。
Lmstfy本身不支持删除和更新,我们在Delayer层中在创建任务同时在Redis中创建了一个MappingKey,客户端可以自定一个ID关联到Jobid,Delayer提供了删除和更新(先删除再创建)API,我们业务还需要支持多次执行的功能,在处理JobAck时根据任务参数重新插入队列,结合我们二次开发整体结构如下:
通过本地限定1核CPU压测生产消息数据如下:
200万任务量占内存600MB+,其中包括mappingkey导致key数量翻倍。
以下是单核CPU的环境下压测结果,任务创建可高达1500TPS:
延时任务到期时间比较分散的情况下,消费表现如下接800TPS:
封装lmstfy的方案已足够支撑当前的使用场景,但还是有一些不足之处,比如:
●在Delayer中操作Redis中的任务,无法保证原子性;
●任务创建和消费另外会多一次网络请求,产生不必要的开销;
●无法支持循环任务;
●Lmstfy采用HTTP协议,无法发挥更好性能。
未来,我们计划融合两个服务,完善任务CRUD功能,减少网络开销,并采用GRPC来替换HTTP协议通讯。

主题测试文章,只做测试使用。发布者:最新稳定辅助网,转转请注明出处:https://www.744broad.com/17249.html

(0)
上一篇 2023年3月11日 上午1:51
下一篇 2023年3月11日 上午1:56

相关推荐

  • 月嫂体检出来梅毒阳性,医生说可以继续带小孩,真正原因是被误诊

    月嫂体检出来梅毒阳性,医生说可以继续带小孩,真正原因是被误诊 近日一位家长带着月嫂来看化验单。化验单上显示RPR阳性,家长很担心,月嫂是不是得了梅毒了,有没有传染给小孩呢?看了一下化验单,月嫂45岁,虽然RPR显示阳性,但TPPA是阴性。询问了一下月嫂相关病史,又做了查体,未发现任何皮损。考虑检测结果是假阳性。只要住过院的病人都知道,住院以后要做相关的血液检…

    RUST资讯 2023年3月10日
    30
  • 波卡解锁3400万DOT,你抛了吗?

    波卡解锁3400万DOT,你抛了吗? 作者:Kylin编辑:小回DeFi的余温还未消散,波卡接力成为市场焦点。四年的沉淀,让波卡成为众多投资者心中比肩以太坊的“跨链之王”,无论生态、技术,还是社区等方面,波卡已然仅次于以太坊。“让区块链变得更伟大”,GavinWood的愿景正被视作改变加密货币世界的重要力量。随着主网发布,Polkadot的原生代币DOT在不…

    RUST资讯 2023年2月23日
    50
  • 搭载M1芯片的Mac软件兼容性怎么样?值得购买吗?

    搭载M1芯片的Mac软件兼容性怎么样?值得购买吗? 苹果的M1芯片是基于ARM架构的自研芯片,推出之后就使用在自家的Mac产品线中,这一芯片的对于软件的兼容性怎么样,比如adobe全家桶、Offfice等软件的兼容效果如何呢,我们来一起看下吧。1、微软Office是会有适合苹果新架构的原生编译的版本,旧的x86应用通过Rosetta2转换兼容(目前可以按照2…

    RUST资讯 2023年2月24日
    60
  • iPhone X手机进水不开机刷机报错4013,防水不等于抗水且用且珍惜

    iPhone X手机进水不开机刷机报错4013,防水不等于抗水且用且珍惜 今天客户送来一台iPhoneX,描述的故障是手机不开机,刷机报错4013;后壳玻璃摔坏,需要更换后玻璃。这手机到底经历了什么?只能检测后才能知道具体的故障了。故障分析重新刷机,看进度有点像CPU的问题,但iPhoneX两块主板是通过中柱焊接在一起的,CPU的几率比较小,总线有问题也会引…

    RUST资讯 2023年2月18日
    80
  • Steam特别好评开放世界游戏《腐蚀》夏促中!限时半价

    Steam特别好评开放世界游戏《腐蚀》夏促中!限时半价 开发商FacepunchStudios旗下开放世界生存游戏《腐蚀(Rust)》目前正在参与Steam夏促活动中,截止7月8日前购买可以享受到半价优惠,仅需80.5元。本作一款在Steam上有着高人气的开放世界生存游戏,于2013年开启抢先体验,在中途做出了重新开发等大胆变更的同时继续进化,并于2018年…

    RUST资讯 2023年2月21日
    30
  • 豆瓣日记 T.J.克拉克如何“向理念告别” 3

    豆瓣日记: T.J.克拉克如何“向理念告别” 3 本文作者“CUT”,欢迎去豆瓣App关注Ta。第一章雅克-路易大卫的现代主义第二章从毕沙罗到塞尚的现代主义PabloPicasso,“DanceoftheVeils”,1907第三章从唯物主义到立体主义再到抽象主义“唯物主义”,作为一种政治理论的概念,其与绘画艺术中的唯物主义概念的关系不可能轻易地被论证,除非…

    RUST资讯 2023年2月25日
    40
  • 《当今奇人周兴和》励志小说连载之二十六● 猫与老鼠的游戏

    《当今奇人周兴和》励志小说连载之二十六● 猫与老鼠的游戏 猫与老鼠的游戏Gamebetweencatandmouse朋友的预言很快就应验了。Thefriend’sprophecywassoonfulfilled.干什么涉及到经济利益的事,都有一张张有形和无形的网编织在那里,都有一条条有形和无形的链条勾连在一起,你周兴和只是一个出身低微的农民发明者…

    RUST资讯 2023年2月13日
    80
  • Polkadot波卡

    Polkadot波卡 区块链技术一直在自我革新,不断向前发展。可以说,Polkadot波卡就是区块链技术发展变革的一个典型。Polkadot将会实现一个完全去中心化的互联网,用户拥有完全控制权力。它构想的互联网是每个人的身份和数据是由自己来掌控,不受任何中央机构的影响。Polkadot旨在通过连接私链、联盟链、公链、开放式网络和预言机以及尚未创建的未来技术。…

    RUST资讯 2023年2月19日
    90
  • 使用 Rust 构建分布式 Key-Value Store

    使用 Rust 构建分布式 Key-Value Store 构建一个分布式Key-ValueStore并不是一件容易的事情,我们需要考虑很多的问题,首先就是我们的系统到底需要提供什么样的功能,譬如:上面的问题在系统设计之初,就需要考虑好,作为整个系统的设计目标。为了实现这些特性,我们就需要考虑到底采用哪一种实现方案,取舍各个方面的利弊等。后面,我将以我们开发…

  • 一个显示代码信息的统计程序 —-Tokei

    一个显示代码信息的统计程序 —-Tokei 注意:看仔细了,是Tokei不是TokeyTokei是一个显示代码信息的统计程序,它会显示文件数、文件中的总行数以及不同语言的代码、注释和空格信息赶紧去体验尝鲜吧评论中提供了github开源地址 打赏赞微海报分享

关注微信