使用ChronicleQueue创建低延迟的TB级别的队列DZone
本文介绍如何使用开源 Chronicle Queue创建巨大的持久队列,同时保持可预测和一致的低延迟。
在本文中,目标是维护来自市场数据馈送的对象队列(例如,在交易所交易的证券的最新价格)。也可以选择其他业务领域,例如来自物联网设备的感官输入或读取汽车行业的碰撞记录信息。原理是一样的。
首先,定义一个持有市场数据的类:
public class MarketData extends SelfDescribingMarshallable { int securityId; long time; float last; float high; float low; // Getters and setters not shown for brevity }
注意:在实际场景中,使用float和double保存货币值时必须非常小心,否则可能会导致舍入问题 [Bloch18, Item 60]。但是,在这篇介绍性文章中,我想保持简单。
还有一个小的实用函数MarketDataUtil::create将在调用时创建并返回一个新的随机MarketData对象:static MarketData create() { MarketData marketData = new MarketData(); int id = ThreadLocalRandom.current().nextInt(1000); marketData.setSecurityId(id); float nextFloat = ThreadLocalRandom.current().nextFloat(); float last = 20 + 100 * nextFloat; marketData.setLast(last); marketData.setHigh(last * 1.1f); marketData.setLow(last * 0.9f); marketData.setTime(System.currentTimeMillis()); return marketData; }
现在,目标是创建一个持久、并发、低延迟、可从多个进程访问并且可以容纳数十亿个对象的队列。
天真的方法
有了这些类,就可以探索使用ConcurrentLinkedQueue的简单方法:public static void main(String[] args) { final Queue queue = new ConcurrentLinkedQueue<>(); for (long i = 0; i < 1e9; i++) { queue.add(MarketDataUtil.create()); } }
导致失败的有几个原因:ConcurrentLinkedQueue将为添加到队列中的每个元素创建一个包装节点。这将有效地使创建的对象数量增加一倍。对象放置在 Java 堆上,导致堆内存压力和垃圾收集问题。在我的机器上,这导致我的整个 JVM 变得无响应,唯一的办法是使用"kill -9"强行杀死它。无法从其他进程(即其他 JVM)读取队列。一旦 JVM 终止,队列的内容就会丢失。因此,队列不是持久的。
查看其他各种标准 Java 类,可以得出结论,不支持大型持久队列。
Chronicle Queue
Chronicle Queue 是一个开源库,旨在满足上述要求。这是设置和使用它的一种方法:public static void main(String[] args) { final MarketData marketData = new MarketData(); final ChronicleQueue q = ChronicleQueue .single("market-data"); final ExcerptAppender appender = q.acquireAppender(); for (long i = 0; i < 1e9; i++) { try (final DocumentContext document = appender.acquireWritingDocument(false)) { document .wire() .bytes() .writeObject(MarketData.class, MarketDataUtil.recycle(marketData)); } } }
使用配备 2.3 GHz 8 核英特尔酷睿 i9 的 MacBook Pro 2019 时,仅使用一个线程即可插入每秒超过 3,000,000 条消息。队列通过给定目录"market-data"中的内存映射文件持久化。人们会期望MarketData对象至少占用 4 (int securityId) + 8 (long time) + 4*3 (float last, high 和 low) = 24 字节。
在上面的示例中,附加了 10 亿个对象,导致映射文件占用 30,148,657,152 个字节,这意味着每条消息大约 30 个字节。在我看来,这确实非常有效。
从编年史队列中读取很简单。继续上面的示例,下面显示了如何从队列中读取前两个MarketData对象:public static void main(String[] args) { final ChronicleQueue q = ChronicleQueue .single("market-data"); final ExcerptTailer tailer = q.createTailer(); for (long i = 0; i < 2; i++) { try (final DocumentContext document = tailer.readingDocument()) { MarketData marketData = document .wire() .bytes() .readObject(MarketData.class); System.out.println(marketData); } } }
还有许多其他功能超出了本文的范围。例如,可以将队列文件设置为以特定间隔(例如每天、每小时或每分钟)滚动,从而有效地创建信息分解,以便随着时间的推移清理旧数据。还有一些规定能够隔离 CPU 并将 Java 线程锁定到这些隔离的 CPU,从而显着减少应用程序抖动。
Chronicle Queue更多:使用Chronicle Queue创建低延迟的TB级别的队列 - DZone
docker常用命令常用命令dockerversion显示docker的版本信息dockerinfo显示docker的系统信息,包括镜像和容器的数量docker命令help帮助命令帮助文档地址http
git命令别名让命令行操作起飞信奉命令行是艺术的伙伴一定不会错过alias给常用命令加速这个功能。今天就给git加加速。日常操作飞一样的感觉。让GUI相形见绌。ggitgagitaddgaagitaddallg
欧盟启动430亿欧元芯片投资计划欧洲跟随美国制定了大规模增加半导体制造的计划,布鲁塞尔方面正试图确保驱动全球经济的芯片供应。欧盟委员会(EuropeanCommission)公布一项430亿欧元的投资计划时表示,
我对大数据等高科技向纵深发展的一点思考cp我看是否利用大数据,互联网,5G,北斗导航等等这些数字化的信息服务于农业,从而调整有针对性的农业生产,像利用大数据分析全国各地农业生产种植品种是否合理?不能今年市场短缺产品,明
在重庆跑滴滴收入怎么样?今年我坐过一次滴滴车,当时我问了司机一天能挣多少钱?她说200一300元一天,主要是平台收取费用太高,百分之二十几,现在还有T3出行,也是网约车,再加上出租车,也许等到疫情过后会有
为什么Android们的相机不愿用大底了?硬哲学底大一级压死人,这个老法师口中的金科玉律,在智能手机上似乎已经失效。不同相机所搭载不同尺寸的传感器尺寸。图片来自henrys。com智能手机摄像头的底虽然逐步变大,但仍然没能迈过一
国芯科技董秘回复国芯科技的芯片可以应用在基于数字人民币的新型支付生态,包括数字钱包数字货币方面国芯科技(688262)02月11日在投资者关系平台上答复了投资者关心的问题。投资者你公司上市才不到一个月,股价就跌破发行价,请问公司的价值在哪里?公司的这种形象和表现,如何让投资
药店里2元钱一盒的阿莫西林与十几元的效果差别大吗?谢谢邀请,这个类似的问题我以前回答过。这个跟我回答2块钱的维生素c和100块的维生素c有什么区别?是一个道理的。2元钱一盒的阿莫西林与几十元一盒的主要区别在于生产提取工艺外包装,对
求介绍企业怎么做弹性福利效果更好?弹性福利,可以在很大程度上帮助企业管理好员工福利这项成本支出,并能兼顾员工对于企业福利的满意度。根据关爱通调研显示,优质企业提供更丰富的员工福利项目,整体福利水平明显高于普通企业,
从滴滴总裁患癌这件事引发的深思,这三类女性应做好防范远离癌症2015年9月30日,滴滴公司内部的一封邮件引发热议,发件人是滴滴高管柳青,柳传志之女。柳青在邮件里用寥寥几语道出自己罹患乳腺癌即将离开工作岗位去接受治疗,虽然语言诙谐幽默,字里行
姚班麻省理工的学霸们开了个公司,IDGOPPO都投了在创投圈,这样的一幕并不罕见。2月9日,宸境科技完成数千万美元A轮融资,投资方包括上海人工智能产业股权投资基金IDG资本三七互娱OPPO等,本轮融资将主要用于技术研发产品落地及优秀