从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

过去几年,Python 3的采用量明显增加,但它仍有很长的路要走。采用Python的大型公司倾向于在其基础架构上运行大量的Python 2.7代码,Facebook也不例外。在今年的PyCon 2018会议上,Facebook产品工程师Jason Fried讲述了该公司在过去四年时间里,Python 3从几乎无人问津到成为该公司主流Python版本的全过程,也展示出Fried作为一名工程师的坚持。

演讲视频:https://www.youtube.com/watch?v=H4SS9yVWJYA

Jason Fried现任Facebook的产品工程师,在帮助公司实现这一目标方面发挥了重要作用,他在演讲中讨论了关于如何解决Python版本迁移的一些想法。

Fried在2011年进入Facebook工作,很快,他就发现需要自学Python,因为在Facebook,Python代码更容易通过代码评审。后来,他发现自己成为推动Facebook采用Python 3的主要动力。他表示从未特地进行过计划,只是Python用得多了,自然而然产生的结果。

图0:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

(Jason Fried)

Jason Fried最初因在Python内部社区中非常活跃而展露头角,他经常是第一个站出来回答问题的人。随后,他在Facebook作为Python的支持者而渐渐成名(或者说”臭名昭著“),因为当他看到Python代码中出现问题时,他会未经许可就直接上手修改。这在Facebook行之有效,因为这里并没有真正意义上的自上而下的控制机制,每个人都有权利对一个代码变更做出修改,就像你有权利做出代码变更一样。随着时间推移,他在Facebook的内部Python社区内建立起了威信,这对他日后在Facebook顺利主导Python版本迁移起到了很大的推动作用。

图1:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

这是Fried演讲中提到的关于Python 3在Facebook从无人问津到占主导地位的完整时间线,可以看到,这个过程花了将近5年的时间,实属不易。

2013年(基本支持→负面情绪→希望乍现)

图2:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

Python 3永远不可能出现在Facebook

Python 3在Facebook的落地过程非常艰难,一开始遭到内部的否定,甚至让Fried一度认为它不可能出现在Facebook,直到目前超过55%的采用率,整个过程非常坎坷。

他说,要在“Facebook规模”上改变Python版本这类东西需要花费相当多的时间,并需要使用很多“外交“手段。他讲述了他和几个工程师是如何利用空闲时间,在没有任何权力的情况下让Python 3成为Facebook主要版本的。

2013年,Facebook打算开始初步支持Python 3,因为他们需要向构建系统中添加Python 3支持。但因为Facebook库不支持Python 3,所以无法向构建系统添加Python3。而如果构建系统不支持Python 3,Facebook库就不可能支持Python 3。这就像《第二十二条军规》里描述的矛盾军规一样,Python 3虽然“可用”,但在Facebook环境中得不到任何支持。

图3:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

另外,在2013年,Facebook内部对Python 3抱有很大的消极情绪。总体来说,他们认为公司的编程语言将永远停留在Python 2.7版本。还有人建议完全换成另一种语言。Fried也曾表示(在内部社区中)Python 3永远不会出现在Facebook。只有一个人向他提出质疑,并建议他做些事情来改变这种情况,虽然当时他忽略了这个建议,但这个想法却留在了他的脑海里。

希望乍现

2013年,事情出现了转机。当年一月,当时Facebook正在使用的“linter”工具需要从__future__导入print_function、division、absolute_imports和unicode_literals,以延长Python 2代码库的使用寿命。他们在任何linter提示的地方导入这些包,这样可以更容易将模块转为Python 3。

用于序列化和远程过程调用的Apache Thrift框架在Facebook“无处不在”。由于它仅支持Python 2,所以成为最大的障碍。但是,由Facebook Thrift团队发起的一个有关Thrift新特性的问卷调查显示,开发者普遍希望能够添加Python 3支持。Fried投了赞成票,但并不是跟风,他认为Python 2接口需要重构,因为它看起来好像Java。

图4:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

当他看到Guido van Rossum在旧金山的Yelp谈论一个叫做“Tulip”(最终成为了asyncio模块)的东西时,他的想法开始转变。他一直是Python异步编程爱好者,但因为框架(例如Twisted、gevent)之间的差异而变得碎片化。而Tulip让异步I/O操作之间可以互操作。在那次演讲结束之前,他与Facebook Thrift团队沟通,表示Thrift应该直接支持Tulip,而不是等Twisted、gevent和其他框架迁移到Python 3。几天后,Thrift团队发布了一个路线图,其中就有对Python 3和Tulip的支持。

Thrift团队在2014年初推出了这两项新特性,但此后六个月并没有什么动静。用户并没有对此作出反应,实际上他们不关心,甚至根本不知道已经发生了这些变更。Fried还顺便引用了中国盖了房子却没人住的例子来说明这种情况,真是让人哭笑不得。

2014年(改变文化→从头开始→强制推行)

图5:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

新项目

2014年8月,他开始重写一个服务,并计划使用gevent和Python 2,但他后来才意识到,如果这么做的话,在完成这个项目时它就过时了。为了有所改变,需要有人成为第一个做出改变的人。要在Facebook推动使用Python 3,那个人非Fried莫属。

于是他使用Python 3开始他的项目,可想而知,他面对的是一个”一塌糊涂“的局面。当时Facebook没有人用Python 3,构建系统不支持他的代码,而且所有第三方包仅适用于Python 2。在他修复了所有问题,让代码通过编译后,又在运行时出了问题。

为了让代码能够正常运行,他必须修复所有问题。他重新构建了数百个第三方包,这样它们就可以同时支持两个版本的Python,而且他必须让所有内部库可以兼容Python 2和Python 3。但是,每天都有人会将Python 2变更提交到他的依赖项中。他需要不停地修复问题,并对此感到厌倦。一种解决方案是在组织内部强制进行Python 3合规,但这在Facebook根本不可能。但是,如果你表现得好像有某种权力时,人们会渐渐相信你真的有这种权力。

他动用了很多关系把Pyflakes(一个lint工具)添加到构建过程中。他能够证明添加它是有道理的,因为虽然已经有了PEP 8,但Pyflakes可以解决其他额外的代码质量问题。此外,Pyflakes几乎没有误报,所以它不会惹火开发人员。他做了一些设置,让Pyflakes能够扫描所有需要审查的代码,先是Python 2,然后是Python 3。这有助于将Python 3兼容性扩展至所有开发人员,而不仅仅是他自己,这让他的项目取得了进展。

在刚开始,他必须花费大量的时间向人们解释“linter是没有错的”,并且让代码能够在Python 3上运行是有价值的。如果开发人员开始觉得迁移到Python 3是件困难的事,他们就会回到“让我们永远留在Python 2”的心态。他要尽量保证开发人员能够顺利在Python 3上运行代码。

2015年(培训)

图6:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

培训

虽然克服了一些困难,但在Facebook扩大Python 3地盘的进展甚微或毫无进展。他加入了为Facebook新员工进行Python编程培训的团队。他希望兼容代码仅用于遗留项目,而新项目应该用Python 3开发。

图7:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

2015年,他修改了新员工Python培训内容,表示Facebook总有一天会转向Python 3,只编写Python 2代码是没有意义的,因为未来得重写。他教导新员工,所有代码都应该与Facebook基础架构和构建系统一致,如果不是,他们应该提交错误或尝试自行修复。这样,新的员工开始在工作中使用 Python 3,这就是进步的开始。“奇怪的是,事情就这么发生了”。

2015年1月,他终于交付了他的项目。他花了大半年的时间告诉人们它有多好,为什么他们应该尽可能地使用Python 3。一年来,很多在Facebook致力于推行Python 3的盟友在公司中出了名。

2016年(Python 3成为默认编程语言)

图8:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

其中一位盟友是Łukasz Langa,他“说服了Instagram转向Python 3”。 2016年,Fried和Langa在Facebook组建了一支全新的团队,在公司内部培训Python,他们称之为“滑稽漫步团”(The Ministry of Silly Walks)。虽然只有两个人,但毕竟是一个“Python团队”,于是他之前提到的“权威”开始起作用了:人们认为他们可以在Facebook做出有关Python的决策。

2016年,他发现Python 3的采用量增长虽然缓慢,但还是有稳步的增长。人们在会议上提到它,他还经常听到有新项目在使用它。即使Python 3不是默认设置,项目也会选择使用它,Facebook此时对Python 3的看法已经发生了变化。2016年5月,Fried表示打算将构建系统切换到默认使用Python 3,他的这一提议几乎得到了绝对支持。几天之后,他完成了切换,切换之后并没有带来任何不良影响。

图9:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

Fried表示,2016年,在Facebook中推动Python 3项目的只有十个人,其中三个是主要推动者,而且人事流动不断,做这个项目的很多人都是兼职。

2016年底,有一个项目团队发表了一篇文章,其中介绍了切换到Python 3的结果。开发人员从Python 2换到Python 3时只需做出一些修复,运行代码的速度就提高了40%,并仅使用了一半的内存。这打破了Fried之前听到的一个传言:Python 3比Python 2慢。早期版本的Python 3可能是这样,但现在肯定不是,他说道。

2017年(Instagram迁移)

图10:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

好事情发生

2017年初,Facebook因为Instagram完成了Python 3迁移而感受到Python 3迁移带来的荣光。Python版本升级原来并不可怕,反而带来了可用的新功能。Facebook开发人员现在开始使用新的静态类型或使用asyncio改造旧服务。“Python在Facebook又开始变得很有趣了”。

现在的问题是,每个人都在问什么时候可以停止支持Python 2。当Python 2支持库或模块出现回归时,通常会听到开发人员询问是否可以直接升级到Python 3。而几年前,情况是完全相反的。“哦,世界真美好啊!”

2018年(Python 3占比超过55%)

图11:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

他展示了一张Facebook的Python服务入口端点随时间变化的图表,从2015年第三季度开始,那个时候只有四个Python 3服务入口端点。截至2016年年中,当切换到默认使用Python 3时,Facebook已经有4%的服务入口端点使用了Python 3。2018年3月,这一比例超过50%。5月中旬,当他发表演讲时,运行Python 3的Facebook服务入口端点比例已达55%。在Facebook,只能在Python 2上运行的代码现在处于尴尬的境地,Fried说道。

图12:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

图13:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

Łukasz Langa发推文,对Python 3低CPU占用和运行速度提升表示赞赏。

图14:从无人问津到占主导,Facebook如何从Python 2迁移到Python 3

演讲接近尾声,他对演讲做了概述。总的来说,他的建议包括:

  1. 你要做的是创新,做出改变,结果自然会来;
  2. 你必须通过“亲力亲为让人看到你想要的变化”来引导开发者;
  3. 你还应该寻求他人的帮助,不要单枪匹马;
  4. 另外,培训新员工去实现你未来的目标是很重要的。
  5. 收集需要的数据;
  6. 享受得到的成果,用Python 3写一些“非常棒的东西”。

最后,他还回答了观众提出的一些问题。有人问,如何在传统、等级分明的组织中实现演讲中所说的目标。Fried认为,实际上这可能会更容易一些,因为你不需要说服成千上万的开发者,只需要让管理层意识到这件事情的好处就可以了。如果在文化保守的组织中,这也可能很难,但专注于代码质量改进可能对此有所帮助。另一个问题是关于整体代码,而不是多个入口点,对于这个问题,Fried建议看看PyCon 2017上的Instagram主题演讲[YouTube视频 https://www.youtube.com/watch?v=66XoCk79kjM]。

整个演讲让人受益匪浅,包括Fried强调的倡导者和领导者,以及坚持不懈的精神在一个项目中的的重要性。

查看英文原文:https://lwn.net/SubscriberLink/758159/f1f631e1535ab9d6/

本文文字及图片出自 InfoQ

余下全文(1/3)
分享这篇文章:

请关注我们:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注