本文由 Adam Storm 发表在 cockroachlabs.com,经原作者授权由 InfoQ 中文站翻译并分享
我是一个数据库极客。或者更准确的说,是一个数据库管理系统(DBMS)极客。我最喜欢数据库的地方在于,尽管数据库无处不在,且现代社会离开它将无法正常运转,却仍然很难得到恰当地构建。这其中的部分难点在于,数据库很复杂,并且其架构借鉴了计算机科学几乎所有的领域。
然而,我对数据库的热爱并非一直如此强烈。还在上大学的时候,我不惜一切代价逃避数据库的课程,并揣测数据库领域没有太多的新知识要学习(这很不正确),所有最困难的问题都已经被解决了。我的逃避很快就让自己尝到苦头,因为毕业后,IBM 当地的 DBMS 开发团队录用了我,我决定加入他们。
刚加入 IBM 时,我在一个自动计算(Autonomic Computing)团队工作。该团队的任务是通过自动化难以人工执行的任务或容易出错的任务(例如物理数据库设计、统计信息收集、内存管理),来使数据库管理员的工作更轻松。具体点说,我被任命领导一个团队,这个团队的目标是自动调整 DBMS 的各种内存配置参数以优化性能。
“尽管这项工作令我精疲力尽(我不止一次在身旁的笔记本上睡着了),但能针对棘手问题提出创新性的解决方案还是很有意义的。最终我们的成果在产品中是默认启用的,并且如今仍然得到成千上万客户的使用。”
在我们刚开始自动化内存调优的工作时,当时现有的所有学术方法都存在一定限制,使它们无法在工业产品中实现。
例如,当时有几种可用于调整缓冲区缓存的方法,但是其中很多都需要将查询划分为多个类并指定响应时间目标。这些查询划分和目标指定常常像底层内存调优的那么难。此外,尽管有关单个内存使用者调优(例如缓存、工作内存、锁定内存等)有许多文章,但还没有研究成果去探讨如何统一所有的方法,来建立一种自动调优一组内存使用者的机制。
在调查中,我们还发现一些复杂的问题,这些问题使得在复杂的 DBMS 上进行内存调优变得困难。例如,DBMS 中最大的查询内存使用者之一是排序所需的内存。当查询包含 ORDER BY 子句,并且没有相应的索引可用时,系统必须对数据进行排序。在内存中执行排序是最高效的。但是,如果排序太大而无法全部存储在内存中,大多数系统都可以通过将已排序的行写入临时表来将其“溢出”到磁盘。
然后,临时表在可能被写入磁盘前(如果出现高速缓存不足以容纳整个临时表的情况,临时表就会被写入磁盘)由系统缓存(在回写缓存中)。排序内存和缓存内存之间存在交互,这一事实使内存的调优变得困难。理想情况下,系统将优化排序内存的大小,以防止溢出(即使它们从未溢出到磁盘,这也是很昂贵的),但是添加额外的缓存内存会给人一种调优的错觉,因为它可以加快排序溢出的执行速度。
第二个复杂问题是,大多数学术方法都假定调整单独的参数不会互相影响。 实际上,情况远非如此。例如,当减小回写缓存的大小时,必须释放存在于内存中的所有脏页,并将它们写入磁盘。因此,频繁减少缓存大小带来的结果是增加了 I / O 子系统的负担。
此外,由于必须释放连续的内存块才能供其他内存使用者使用,因此将内存页面写入磁盘必须等待所有并发事务当前正在使用的页面。 在实践中,我们发现有必要对这些减少内存的成本进行建模,并采用控制理论方法来减少内存使用者大小的频繁波动。
这些挑战加在一起使该项目需要付出非常多的努力,因为我还经验不足,所以尤为如此。 我不仅需要绞尽脑汁地思考 DBMS 中执行内存管理的复杂方式,同时还要学习控制理论、商业软件开发,而且还要首次领导一个团队。
我非常感激的是,我在 IBM Research 中有非常优秀的伙伴,有一名非常棒的经理和导师,以及一个非常宽容的团队。尽管这项工作令我精疲力尽(我不止一次趴在笔记本上睡着了),但能够针对棘手问题提出创新性的解决方案还是很有意义的。最终,我们的工作成果在产品中是默认启用的,并且如今仍然有成千上万的客户在使用——这件事令我感到无比自豪。
在交付了第一批自动计算功能后,我们的团队被重新划分成多个团队,以帮助其他更紧迫的项目能顺利进展。这次重组,我加入了一个新团队,该团队正在研究将大型计算机上非常成功的技术——Db2 数据共享,引入 commodity hardware 的可行性。
1994 年,当 Db2 数据共享(以及大型计算机的 Parallel Sysplex)问世时,它允许将通常仅限于单机使用的数据库扩展到多台计算机上。 这使它成为分布式关系数据库的第一批代表之一。这极大地帮助了那些为满足工作量需求而努力扩展数据库的客户。
当 Oracle 如法炮制,在 2001 年将其应用到它们的 Real Application Clusters(RAC)时,IBM 开始面临将竞争技术引入非大型机市场的压力。
“我被任命领导事务管理团队。 我加入了一个由事务管理专家组成的团队。 尽管这可能令人望而生畏,但实际上这使我不必围绕技术进行日常决策,而是让我专注于领导(这恰好是团队需要)。 在这里,我提高了软件开发项目管理的技能……”
然而,将大型机技术引入到 commodity hardware 的问题在于,大型机相对于基于 UNIX 的服务器具有某些技术优势。例如,大型机既有高速互连,又有基于硬件的时钟同步,这两者都使多个服务器上的分布数据库更加可行。
对我们来说,幸运的是,当我们在 2006 年开始这项工作时,Infiniband 连接得到了广泛采用,并且与远程直接内存访问(RDMA)结合使用,让集群中的节点之间的交互延迟变得极低。RDMA 与 Lamport 时钟的内部实现相结合,使我们能向现有的非大型机客户提供大型机上已有的类似技术。
这个新职位是我第一次了解核心 DBMS 开发,也是我第一次了解 ARIES 之类的东西(幸运的是,我是从该论文的原作者那里了解到的)。第一年是一个艰难的旅程,因为有很多东西要学,但同时学习全新的东西也令人振奋,尤其是在深挖内存管理领域这么长时间后。在团队证明了原型(由于我还在学习,我对此只做出了很小的贡献)后,我们便“一路绿灯”,将其构建到我们的产品中,该产品最终被称为 Db2 pureScale。
那时,我们需要疯狂地扩张团队,并且由于我学习了几个月的技术细节,所以我被任命领导事务管理团队。这与我在自动计算领域(在这个团队中的每个人都是该领域的新手)的经历截然不同,因为我现在要加入一个由事务管理专家组成的团队。尽管这可能令人望而生畏,但实际上这使我不必围绕技术进行日常决策,而是让我专注于领导(这恰好是团队需要)。在这里,我提高了软件开发项目管理的技能,与此同时,我掌握了足够多的技术细节,能够做出重要贡献,尤其是在项目的最后阶段。
2009 年,在交付了 Db2 pureScale 后,我开始朝一个完全不同的方向前进,但也与两个老朋友在这个方向上”团聚“。我以前在自动计算部门时的经理(以及他的经理)在那时正在组建一个团队,来探索将列存储的最新研究纳入我们产品的可能性。
“这项任务中的困难正是吸引我的地方。并且它是一个完全未知的领域,这允许我既可以领导团队,又可以设计技术解决方案。同时做这两件事情并不总是那么容易,并且项目管理的要求又时常让我从我真正想做的事情(代码)中分心。“
自从关系数据库诞生,行需要连续存储在磁盘上以最大化性能就是流行的思想。对于事务性工作负载而言,这是有意义的,因为在这种情况下,一次插入一个行并进行更新(因此,将它们放在磁盘上的单个位置是最有效的),并且通常可以通过索引来加速查询。但是,对于分析型数据库,行通常会作为批处理作业的一部分进行修改,而且,通常都是只指定少数几列去查询非常大的表,在没有索引的情况下扫描表的大部分内容。
因此,将连续行的列值存储在一起会更有效,因为查询可以只读取查询请求的列值,并节省所有未读列所需的 I/O。列存储也很适合矢量处理,因为列值被连续存储在内存中,能进行批处理,而不是单独处理。
另外,列存储还有助于数据压缩,因为给定的数据页(甚至磁盘上的整个文件)将包含一个列,其值通常是从有限的一组可能性中得出的(例如州、地区代码、性别或年龄)。
在刚刚进入列存储领域时,我被问到是否要与 IBM Research 的一些人员一起加入一个团队,来看看我们是否可以快速构建一个原型以集成到 Db2 中。当我们与该原型的硬件部门合作时,我被要求承担将 SIMD 指令添加到我们新的矢量化处理引擎中的工作。这是我以前从未做过的工作,并且它深入到了机器指令水平,这既令人兴奋又令人生畏。
当我们成功完成原型并开始将其构建到产品中时,我游说并开始领导一个团队,该团队将构建列存储的插入/更新/删除功能。我们构建的初始原型仅支持插入操作(或许更诚实地说,仅支持批量加载),并且由于行被拆分为磁盘上的多个文件,确保我们能进行细粒度的数据修改绝非易事。 而且,我们被要求与现有的行存储的插入性能相匹配,至少在大批量插入和更新时,性能不输现有的行存储。
这项任务中的困难正是吸引我的地方。并且,它是一个完全未知的领域,这允许我既可以领导团队,又能设计技术解决方案。同时做这两件事情并不总是那么容易,并且项目管理的要求又时常让我从我真正想做的事情(也就是代码)中分心。
不论如何,让客户满意是我的最终目标,如果这意味着花在技术故障排除的时间比实际写代码的时间更多,我也很乐意。同时,我也很幸运,我所在的团队非常强大,也非常均衡。他们很高兴与彼此在一起工作,其中一些人至今仍然是关系要好的朋友。2013 年,我们交付了我们的解决方案(名为 BLU Acceleration),并发表了有关其创新设计的研究论文。
在我们交付 BLU Acceleration 之后,负责其前期工作的研究人员决定将注意力转向混合事务/分析处理(Hybrid Transaction/Analytical Processing,即 HTAP)。数据库工作负载大致分为两类:事务型和分析型。
HTAP 的目标是通过使用单个数据拷贝,构建针对事务处理和分析处理都进行优化的系统。 这并不是一件容易的事,因为如前所述,事务处理得益于将行一起存储在磁盘上,而使用列式组织存储通常能加速分析处理。
我作为独立的开发人员开始与 IBM Research 在 HTAP 方面进行合作。这项工作很有趣,并且我们取得了良好进展,但是最终,该公司当时对继续发展 HTAP 并不感兴趣(至少,对我们曾经追求的深度集成的方式不感兴趣)。
在任何情况下,都要讲究天时地利。虽然我当时尚不清楚深度集成的 HTAP 是否对我而言算是地利(它当然有其优势,但仍然很难保证合适),但我们肯定未占天时。当时,对数据库领域的最大影响是向云的转移,而仅 HTAP 并不能直接解决这种向云转移的趋势带来的挑战。
最终,尽管我们正在做的工作很有趣,并且很可能会取得成果,但这并不是组织当时最紧迫的挑战,这正是它失败的原因。
当 HTAP 的工作停止时,我提出了一个从头开始构建云原生分析数据库的建议。与事务型数据库一样,依据传统,分析型数据库被设计为在一台机器上运行。但是,在 80 年代和 90 年代,数据库设计人员意识到,将长时间运行的分析查询拆分在多台计算机上并行运行,可以更快地处理它们。这种“拆分”涉及对数据库进行分区,并使每台计算机拥有数据库的一部分。机器完全不会共享任何数据(每台机器将拥有数据库的不同部分),这使得此种方法被称为无共享架构。在接下来的几十年中,无共享架构主导了分析型数据库的发展。然后是向云的迁移,或更具体地说,是向云原生存储的迁移。
“这项工作也很振奋人心,因为我们不受改造现有系统的困难的束缚,而可以专注于创新。”
在云中,存储大型数据集(并且分析型数据库通常包含非常大的数据集)的最具成本效益的方法是凭借对象存储(比如 AWS S3、Azure Blob 存储等)。这不仅使存储成本大大降低,而且还将数据存储在集群中所有节点可见的存储中,从而开辟了大量新的可能性。
例如,使用共享存储上的数据,分区所有权几乎可以立即被重新分配给节点,而不必在磁盘上物理移动数据(传统的无共享部署就是这种情况)。即时分区重新分配不仅允许群集按每个查询进行扩展和收缩,而且还能大大简化高可用性,因为故障节点拥有的分区可以轻松地重新分配给尚存的节点。
当时,我意识到云存储之上的无共享架构是未来的潮流,于是我建议我们构建这样的系统,并首先关注物联网(IoT)工作负载。为此,组织要求我在数据库部门之外组建一个团队,以便我们可以不受限制地进行自由创新。这不仅令人耳目一新,而且充满挑战,因为多年来我们认为当时存在的所有基础架构都是理所当然的,而今却需要重新构建。幸运的是,这样我们就能够进行创新了,我们在很大程度上依靠了 Docker、Jenkins 和 Kubernetes 等较新的技术,这些技术当时在数据库部门还未使用过。
这项工作也很振奋人心,因为我们不受改造现有系统的困难的束缚,而可以专注于创新。但是不幸的是,团队性质要求我将大部分精力花在保持团队氛围上,而不是花在技术决策上。之所以如此,是因为我拥有一支强大的技术团队,我对此深信不疑。尽管通往成功的道路并非一帆风顺,但我们最终于 2017 年交付了针对 IoT 进行优化的云原生数据库(名为 Db2 Event Store),并于近期发表了有关其初始设计和演进的研究论文。
为了表示对我在 Db2 Event Store 上的工作的认可,我升职了。在新的职位上,我不再领导专门的技术团队,而是与执行团队就我们的部门战略进行了更紧密的合作。这包括与客户更长的时间合作,对几种大型且成功的产品进行架构监督,以及为我们的未来进行规划。
这项工作很有意义,我非常喜欢与其他高管(尤其是老板)一起工作,但它最终也使我离开了我非常喜欢的深度技术工作。当有人询问我是否考虑新的机会时,我就接受了,其中部分原因是我想念那种深度的技术工作。这最终导致我在今年早些时候离开 IBM 加入 Cockroach Labs。
成为领导者有许多地方让人很开心,其中之一就是你可以对他人的职业产生影响。很幸运的是,多年来我指导了很多人,并且经常被问到在我们这一行业中如何取得成功,尤其是数据库领域。如下是我对提问者的一些回答:
数据库领域在其广度和深度上都有着极大的技术挑战,这一点很是令人振奋。因此,大家可能在数据库领域研究得非常地广或非常地深。
有些人渐渐地会在一个领域(例如查询优化、开发人员接口或事务管理)越来越深入,并且公平地说,行业的发展和日益复杂的问题的解决需要人们在技术上非常深入。
但是,我发现,DBMS 开发人员在成就一番事业时,具有技术广度很有好处。具体来说,这使你可以识别系统中存在的问题,并更加整体全面地解决这些问题。当有人特别问到这一点时,我通常建议人们在职业生涯的早期学的越多越好,数据库的领域了解得越多越好。如果你采用这种方式,则可以不再受限于当前所关注的领域,发现之外的问题并提出解决方案,从而为整个组织带来更多价值。
刚进入这个行业的人们会追求工资最高的工作,这种情况经常发生。我能理解这种诱惑。当你在职业早期阶段时,有很多紧急的财务问题(例如买房、结婚、开始退休计划),按工资的高低对工作排序似乎是种正确方法。然而,问题在于,在许多情况下,在职业的早期追求最大回报会对职业的后期产生不利影响。
当刚开始工作时,你应该试图最大程度地增加学习的机会,即使这可能意味着薪水比较低。尽早成为一个“拼命的“学习者,将会保证你在收入最高的 40 到 50 多岁还能表现出最理想最具影响力的状态。
总而言之,如果你刚刚开始自己的职业生涯,找到能使你为公司做出最大贡献的机会,向周围的专家学习,在不同领域提升技能以成为一个全才。
任何事业成功的人(或者还包括事业不成功的人)都忽略提及运气在多大程度上发挥了作用。做个好好先生能对你的事业有很大的帮助,但运气的极大加持能将平庸的人和卓越的人区分开。人生的关键是在正确的时间处在正确的地点。
在很大程度上,运气是无法改变的。对于所出生在的家庭,成长过程中使用的语言或者童年时的地缘政治局势,你没有任何决定权。
话虽如此,随着年龄的增长,你开始有能力影响自己的运气,并且你应该利用这种能力。当我完成本科学位思考去哪里攻读研究生时,我有几个可以考虑的选项。其中有一个是迄今为止最赚钱的,但最后我决定去的是滑铁卢大学,因为我认为这样做可以使我在未来的事业中位于最佳处境。
两年后,当我从那里被招募加入 IBM 时,一部分原因正是运气(我在 IBM 招聘季的时候毕业了——这就是正确的时机),而且,IBM 的数据库团队在当时仅从滑铁卢大学招聘(这就是正确的地方)。如果我没有去滑铁卢大学,那我很可能永远都不会到 IBM 工作。
从那以后,我的好运就像雪球一般越滚越大。在 IBM,我有大量的机会向一部分数据库行业的创始人——构建 System R 的原始团队的成员,以及他们的后继者学习。他们所拥有的关于数据库系统的知识,至今仍令我敬佩。毫无疑问,我能被招募进这样一个强大的学习环境中是十分幸运的,但选择滑铁卢大学是我掌控的运气,所有的一切均源自于此。
当决定在哪里工作,成为哪个团队的一员或在工作之外做些什么时,请记住,我们有能力影响自己的运气,这能帮到你。尽管你无法总能掌控“正确的时间”,但你可能能够预见到哪里会是“正确的位置”。
当人们换工作的时候,尤其是在某家公司工作多年以后,背后的原因往往不止一个。在和朋友、家人和同事对这个改变进行过多次交流以后,对于为什么我对能加入 Cockroach Labs 如此激动,我总结了如下原因:
原文链接:
领取专属 10元无门槛券
私享最新 技术干货