流着码农的血,为突破理论极限值而生 | 阿里中间件性能挑战赛内部赛全记录

近日,第三届阿里中间件性能挑战赛内部总决赛在西溪园区举行,经过前期线上比赛和现场解题思路答辩,来自阿里云数据库技术团队的资深专家曹伟(鸣嵩)获得本次比赛总冠军并揽得大奖。

线上比赛阶段得分屡创新高,现场解题思路答辩交流活跃,气氛热烈,精彩纷呈的内部赛为今年的中间件性能挑战赛开了一个好头,期待在接下来的外部赛上涌现出更多好成绩和令人耳目一新的工程创新。

作为阿里中间件(Aliware)举办的历史最悠久的工程视角赛事,自举办以来,受到业界工程师和高校技术爱好者的一贯支持和好评。2014年中间件性能挑战赛作为初创赛事,主要面向集团内部;2015和2016年又连续举办了两届,面向群体扩充到高校学生和社会参赛选手。今年单独设置了内部赛,单独出题和比赛,并最终和外部赛的同学在总决赛前的极客挑战赛上一决高低。据悉本次内部赛报名参赛的规模创历年新高。

真实场景再现,赛题贴近实战接地气

本次挑战赛的主题为“挑战双十一万亿级消息引擎”,比赛场景当然离不开大家最熟悉的阿里双11,海量业务场景下的技术需求模拟,赛题本身具有非常强的实战意义。本次内部赛题目主要解决的是NewSQL领域中使用最频繁的一个场景–分页排序,其对应的SQL执行为order by id limit k,n。

主要的技术挑战为”分布式”的策略,赛题中使用多个文件模拟多个数据分片。简单来说,就是通过10个文件模拟了数据的分片,每个分片1GB的数据大小,给定的机器配置是24核,JVM堆内存限制2.5G,磁盘读写为490-500MB/s左右。在这样给定资源限制的情况下,如何快速建索引支持分页查询top(k,n)场景。

看似一个简单的问题,但要取得好成绩则需要多方面的综合实力,首先选手要了解硬件,需要考虑IO和内存优化,毕竟10GB文件顺序读取理论值可能就在20秒左右,内存上的一些约束也促使选手需要考虑更好的数据压缩。

同时选手也需要在数据结构和算法上有一个比较好的设计思路,构建类似的索引信息来满足多次的top(k,n)的查询。综合来看,需要选手具有比较强的系统优化和算法设计能力,另外赛题基本是参考了NewSQL领域的一个真实业务场景,整个比赛的优化思路也对真实业务有一定的借鉴性。

时隔两年卫冕,阿里老司机有话说

本次大赛冠军获得者鸣嵩同学,在阿里内部也是一位技术大神,他的座右铭就是Linux创始人Linus Torvalds在邮件列表里说过的那句名言:“Talk is cheap. Show me the code. ”,在公司内部各种安全、算法、文件系统方面的比赛总是名列前茅。

说来也巧,鸣嵩同学还是第一届中间件性能挑战赛的冠军获得者,这次夺冠是时隔两年后的卫冕。作为一名中间件性能挑战赛的老司机,鸣嵩同学表示和评委都很熟,但比赛成绩还是靠实力说话!

 鸣嵩同学在分享解题思路 鸣嵩同学在分享解题思路

鸣嵩同学计算机体系架构方面科班出身,但毕业后就直接投身软件行业,先是从事搜索技术研发,2001年加入阿里做数据库研发和支持工作,长期在一线解决出现的各种工程问题和BUG,累计了大量的实战经验。正是这样的学习和工作经历,锻炼了他的技术功底和综合的实力,在面对上述的问题,能够拿出更好更加全面考虑的解决方案。下面是他的解题思路分享。

成绩综述:

先说一下成绩:最终线上跑分的成绩在22.9s,去掉评测方法引入的1.1s,5次查询含建索引总时间21.8s,因为读10GB文件就需要21.5s时间,所以这个成绩还是很接近底线的,跑到这个分数需要综合利用java GC、操作系统的page cache和脏页回写机制、ext4文件系统原理、以及SSD的一些知识,整体来理解和分析系统瓶颈在哪里、对系统建立模型、并找到规避的方法。

算法设计:

问题本身用很多种数据结构都可以实现,搞数据库和搞ACM的同学对这道题的第一反应是不一样的。我之前做过五年的搜索引擎,分布式和本地的索引框架都写过,所以第一反应是借鉴Lucene的方法,skip list + sequence file。

具体算法是这样:原始文件切割成小分片,喂给24个worker;每个worker读数据,处理数据,定期批量写索引出去;最后查询会去读每个worker生成的所有索引文件,通过跳表快速seek。

本地索引的格式如下:每个分片的随机数通过Array.sort排序成一个有序数组,直接写入一个顺序文件里,采用delta encoding和变长整数方法压缩,long型随机数可以从8字节压到6字节。为了提高查询效率,还加了一个skip list支持索引文件里随机seek。

IO上的优化:

这套算法实现完后,第一次跑花了30s时间,主要原因是一旦开始写盘时,SSD的读能力就下降的很厉害,我就开始想方法去压制写盘。首先是要搞清楚为什么会写盘,这台机器的内存应该是蛮大的,我们阿里的内核一般配置的脏页回写超时时间是30s,理论上page cache能buffer住所有的脏页,那为什么程序运行过程中还会写盘呢?

最后找到原因了,和ext4文件系统的挂载参数有关,从ext3开始起,文件系统开始支持日志(journal),文件的inode被修改后,需要刷到journal里,这样系统crash了文件系统能恢复过来,阿里内核配置默认5s刷一次journal,ext4还有一个配置项叫挂载方式,有ordered和writeback两个选项,区别是ordered在把inode刷到journal里之前,会把inode的所有脏页先回写到磁盘里。不错,我们的评测机器就是配的ordered,这样脏页写入page cache,5s后就被回写到SSD里,从而影响了SSD读性能。

在搞清楚IO机制后,问题就简化为如何利用这个机制规避写盘。一个简单的方法就是控制程序流程,倒数5s才开始写文件。

结果耗时分析:

程序启动后开始预读,把10GB数据加载到page cache里,从12.2s开始起处理数据,要写文件的中间结果先缓存在jvm堆内存里,直到17.0s才开始第一次写文件,这样21.8s程序结束的时候,操作系统还没有真正开始写SSD过程,这样读盘性能就不会受到干扰。

总结:

可以看到,用page cache来做IO还是蛮不靠谱的,所以在开发重IO的服务器,比如数据库时,我们一般都不依赖于page cache,更多使用DIO来写文件,自己管理buffer,java里可以多看看堆外内存。IO发起也建议用AIO来代替堵塞IO模型,甚至我们现在在操作NVMe盘时都旁路掉Linux kernel,直接使用用户态驱动和用户态文件系统。

应用服务器的文件系统挂载选项可以考虑换成writeback,小文件读访问比较多的话,加上noatime,对提升IO性能是有好处的。

通过内部赛冠军鸣嵩同学的解题思路和经历的分享,期待能够给更多的同学和参数选手带来思想上的突破,在接下来的比赛中取得更好的成绩!

对于这次时隔两年后的卫冕,鸣嵩同学表示有点小确幸。他认为参加每一次编程比赛都是一场马拉松,跑到终点除了好的idea之外最需要的是毅力。比赛过程中最有意思的事情是,你会看到事先被预测出的一个个“理论极限值”,先是被逼近,然后被突破,最后被踏平,选手们的技术手段整体上在不断提高,这也体现着竞技的精神:“更高、更快、更强”。在获奖感言环节,他还总结了以下三方面的感悟:

1、 从工程师角度,这种比赛的精髓就是以成为杰出工程师的标准来要求自己,不断突破大家和自己认为不可能的数字(理论极限);通过比赛可以看到众多热血的技术新人,清晰地看到人才梯队越来越壮大;

2、 从比赛角度出发,作为一个软件工程师,能够从系统底层,比如操作系统、编译器、JVM、分布式系统和文件系统等方面来综合考虑,最终给出一个解决方案,是本次比赛获胜的关键,希望业务和应用开发的工程师们能够在这方面多涉猎一些,这些才能在工程师的道路上走得更好更远;

3、 从赛事角度出发,阿里中间件(Aliware)作为阿里技术的“科普”名片,传递给集团其他BU的工程师和外部同行,阿里巴巴作为技术公司,一直以来都在践行技术驱动商业的模式,让更多的技术人在我们的技术平台上迸发他们的创意和想法,改变现在塑造未来。

技术大牛寄语,期待更好的你

为了更好地促进现场交流,阿里中间件技术部负责人蒋江伟(小邪)、业务平台事业部负责人墙辉(玄难)和数据技术及产品部总监朋新宇(小芃)作为评委嘉宾到场,和现场同学共赴代码和算法的盛宴,体验性能优化的极致挑战之路。在获奖同学分享解题思路和心得经验的间歇,各位嘉宾也发表了对选手分享内容的点评和对大赛的期待:

小邪:“首先,我被这样的气氛和热情所感染,大家经常说,生活不仅是眼前的苟且(工作),还有诗和远方,今天晚上这样的比赛就是我们工程师的很容易看到的诗和远方。在工作之余放松自己,追求极致自我。

我每次来到决赛现场,还有一个特别切身的感受就是—突破和惊喜,可以看到和学到其他人是如何来写程序,如何来优化程序,如何来突破各种不可能的。从我经历的这几届来说,每次同学们的比赛成绩都能突破我们组委会所预料成绩的理论值,看到我们同学的各种奇思妙想。不瞒大家说,我和多隆同学(阿里传奇程序员,阿里巴巴合伙人)都曾经参加过类似的比赛,但都没有进入前十名,所以同学们的表现还是非常棒的!”

小芃:“第一次参加这样的活动,听的我热血沸腾。不难看出,现场的各位同学和我一样,身上都流着码农的血,在最近的各种会海中,这是我感觉最酣畅淋漓的几小时。外面很多人在关注我们是一家什么样的技术公司,我们阿里内部的技术人,是如何使用这些技术的?在使用和实践过程中是否不断反哺来提升这些技术?这些都值得我们去考虑。

另外,作为一家大数据公司,难得有这样的比赛,公司内部开放这么好的数据给大家,让大家在最真实的环境中来验证自己的算法和技术方案,我觉得这是一个非常难得的机会。所以对于本次大赛来说,比赛名次并不是最重要的,真正的那种想赢和极客的精神才应该是我们所珍视的。”

玄难:“首先这个比赛非常好玩,我去年就参加过,但是很不幸成绩垫底。今天来参加这个现场总决赛,看到各位获奖同学来分享他们的解题思路,看到非常多有意思和有价值的技术思考;另外,基础中间件性能的突破,对我们整体的技术体系帮助非常大,看到大家今天玩的这么好,并且能找到接下来技术工作的突破点,我觉的还是非常不错的。”

阿里中间件(Aliware)作为国内顶级的中间件技术团队,一直在致力于推动中间件行业和生态的发展,举办中间件性能挑战赛是具体措施之一。期望这样的技术工程类赛事和所有竞技赛事一样,追求“更高、更快、更强”;通过比赛实战,让大家感受到技术工匠精神的真实存在,激励参赛选手在各自技术领域不断精益求精,大胆突破以前的不可能,整体提升中间件行业的理论和工程实践水平;不过还有最重要的一点,通过比赛让大家玩的开心:)

欲了解本次大赛的详情及赛事最新动态,可访问官方网站:https://tianchi.aliyun.com/

企业级互联网架构Aliware,让您的业务能力云化:https://www.aliyun.com/aliware