【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

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

  • 2018-08-02
  • 本文字数:6125 字

    阅读完需:约 20 分钟

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

 (Jason Fried)

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

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

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

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

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

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

新项目

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



培训

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



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

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

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



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

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

2017 年(Instagram 迁移)



好事情发生

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

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

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



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



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



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

  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/

感谢无明对本文的审校。

2018-08-02 19:003057
用户头像

发布了 42 篇内容, 共 13.5 次阅读, 收获喜欢 53 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

【Java从0到架构师】JDBC,Java多态实现原理解析

Java 程序员 后端

自定义注解实现方式全解析

小鲍侃java

11月日更

【Java程序员必知必会的90个细节】1,隔壁都馋哭了

Java 程序员 后端

「JVM 系列」- JVM的类加载机制,java常用面试题和答案

Java 程序员 后端

【C语言】指针总结,Java程序员如何有效提升学习效率

Java 程序员 后端

【DM】达梦数据库中的物理备份与还原,java程序设计项目教程眭碧霞第四章答案

Java 程序员 后端

【Java知识点详解 8】Java反射机制,java项目经验面试题

Java 程序员 后端

【DM】教你用JDBC连接达梦数据库并进行增删改查,java项目百度网盘

Java 程序员 后端

【Docker 1】入门,nginx架构移植

Java 程序员 后端

【Java 异常】try-catch,mysql菜鸟入门系列

Java 程序员 后端

【MyBatis-plus】条件构造器详解,mysql索引原理及btree

Java 程序员 后端

等保测评机构每年都需要年审吗?年审时候需提供哪些资料?

行云管家

网络安全 等级保护 等保测评 等保办

【Spring Boot 25】JdbcTemplate配置类 (1),鬼知道我经历了啥

Java 程序员 后端

【Java从0到架构师】Spring - 整合 MyBatis,大厂Mysql高频面试题

Java 程序员 后端

【Quarkus 技术系列】,Java高级工程师面试答案大全

Java 程序员 后端

【C语言基础系列】C语言分支结构,java反射原理面试

Java 程序员 后端

【Java从0到架构师】Spring - 复杂对象,java的多线程的底层原理

Java 程序员 后端

【Java从0到架构师】Spring - 生命周期,mysql教程入门到精通pdf

Java 程序员 后端

【Java后端】2020年最新阿里,java中级面试题库weixin

Java 程序员 后端

【JVM系列5】深入分析Java垃圾收集算法和常用垃圾收集器

Java 程序员 后端

【MyBatis 2】MyBatis-Plus,java分布式框架技术方案

Java 程序员 后端

《零基础》MySQL 连接的使用(二十),springcloud开发教程

Java 程序员 后端

【Spring Boot 23】MyBatis事务管理,java基础知识点思维导图

Java 程序员 后端

【C语言】动态内存分配,nginx调优与监控

Java 程序员 后端

【Java并发实战】偏向锁-轻量级锁-重量级锁,掌握这些知识点再也不怕面试通不过

Java 程序员 后端

【Redis实战】集合类型,unixlinux编程实践教程

Java 程序员 后端

《零基础》MySQL 安装(二),java高级程序设计作业系统

Java 程序员 后端

【DM】DMSQL程序的基本操作,下载量瞬秒百万

Java 程序员 后端

【DM】达梦DEM WEB管理器的搭建,mybatis基本工作原理

Java 程序员 后端

一文带你理解TDengine中的缓存技术

TDengine

数据库 tdengine 后端

前端组件化工程实践

循环智能

AI 组件化 智能化

从无人问津到占主导,脸书如何从Python 2迁移到Python 3_Python_陈利鑫_InfoQ精选文章