36

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

 5 years ago
source link: http://www.infoq.com/cn/news/2018/08/facebook-python2-to-3?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

过去几年,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用得多了,自然而然产生的结果。

1651-1533197160491.jpg

 (Jason Fried)

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

5672-1533197304000.png

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

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

4563-1533198430756.png

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环境中得不到任何支持。

3894-1533198431035.png

另外,在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。

3235-1533198433114.png

当他看到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年(改变文化→从头开始→强制推行)

2866-1533198432488.png

新项目

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年(培训)

 2387-1533198434151.png 

培训

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

 1958-1533198429356.png 

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

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

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

 1769-1533198433428.png 

其中一位盟友是Ł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 ,他的这一提议几乎得到了绝对支持。几天之后,他完成了切换,切换之后并没有带来任何不良影响。

 12010-1533198957281.png 

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

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

2017年(Instagram迁移)

 11711-1533198957573.png 

好事情发生

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

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

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

 12312-1533198955532.png 

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

11013-1533198955906.png

 8514-1533198957003.png

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

 7115-1533198956460.png 

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

  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/

感谢无明对本文的审校。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK