Facebook如何在4年間全面轉(zhuǎn)向Python3?
策劃編輯 Natalie
作者 Jake Edge
編譯 Debra
編輯 Vincent
過去幾年,Python 3 的采用量明顯增加,但它仍有很長(zhǎng)的路要走。采用 Python 的大型公司傾向于在其基礎(chǔ)架構(gòu)上運(yùn)行大量的 Python 2.7 代碼,F(xiàn)acebook 也不例外。在今年的 PyCon 2018 會(huì)議上,F(xiàn)acebook 產(chǎn)品工程師 Jason Fried 講述了該公司在過去四年時(shí)間里,Python 3 從幾乎無(wú)人問津到成為該公司主流 Python 版本的全過程,也展示出 Fried 作為一名工程師的堅(jiān)持。
視頻地址:https://v.qq.com/x/page/r07069violt.html
Jason Fried 現(xiàn)任 Facebook 的產(chǎn)品工程師,在幫助公司實(shí)現(xiàn)這一目標(biāo)方面發(fā)揮了重要作用,他在演講中討論了關(guān)于如何解決 Python 版本遷移的一些想法。
Fried 在 2011 年進(jìn)入 Facebook 工作,很快,他就發(fā)現(xiàn)需要自學(xué) Python,因?yàn)樵?Facebook,Python 代碼更容易通過代碼評(píng)審。后來,他發(fā)現(xiàn)自己成為推動(dòng) Facebook 采用 Python 3 的主要?jiǎng)恿?。他表示從未特地進(jìn)行過計(jì)劃,只是 Python 用得多了,自然而然產(chǎn)生的結(jié)果。
(Jason Fried)
Jason Fried 最初因在 Python 內(nèi)部社區(qū)中非?;钴S而展露頭角,他經(jīng)常是***個(gè)站出來回答問題的人。隨后,他在 Facebook 作為 Python 的支持者而漸漸成名(或者說”臭名昭著“),因?yàn)楫?dāng)他看到 Python 代碼中出現(xiàn)問題時(shí),他會(huì)未經(jīng)許可就直接上手修改。這在 Facebook 行之有效,因?yàn)檫@里并沒有真正意義上的自上而下的控制機(jī)制,每個(gè)人都有權(quán)利對(duì)一個(gè)代碼變更做出修改,就像你有權(quán)利做出代碼變更一樣。隨著時(shí)間推移,他在 Facebook 的內(nèi)部 Python 社區(qū)內(nèi)建立起了威信,這對(duì)他日后在 Facebook 順利主導(dǎo) Python 版本遷移起到了很大的推動(dòng)作用。
這是 Fried 演講中提到的關(guān)于 Python 3 在 Facebook 從無(wú)人問津到占主導(dǎo)地位的完整時(shí)間線,可以看到,這個(gè)過程花了將近 5 年的時(shí)間,實(shí)屬不易。
2013 年(基本支持→負(fù)面情緒→希望乍現(xiàn))
Python 3 永遠(yuǎn)不可能出現(xiàn)在 Facebook
Python 3 在 Facebook 的落地過程非常艱難,一開始遭到內(nèi)部的否定,甚至讓 Fried 一度認(rèn)為它不可能出現(xiàn)在 Facebook,直到目前超過 55% 的采用率,整個(gè)過程非??部?。
他說,要在“Facebook 規(guī)模”上改變 Python 版本這類東西需要花費(fèi)相當(dāng)多的時(shí)間,并需要使用很多“外交“手段。他講述了他和幾個(gè)工程師是如何利用空閑時(shí)間,在沒有任何權(quán)力的情況下讓 Python 3 成為 Facebook 主要版本的。
2013 年,F(xiàn)acebook 打算開始初步支持 Python 3,因?yàn)樗麄冃枰驑?gòu)建系統(tǒng)中添加 Python 3 支持。但因?yàn)?Facebook 庫(kù)不支持 Python 3,所以無(wú)法向構(gòu)建系統(tǒng)添加 Python3。而如果構(gòu)建系統(tǒng)不支持 Python 3,F(xiàn)acebook 庫(kù)就不可能支持 Python 3。這就像《第二十二條軍規(guī)》里描述的矛盾軍規(guī)一樣,Python 3 雖然“可用”,但在 Facebook 環(huán)境中得不到任何支持。
另外,在 2013 年,F(xiàn)acebook 內(nèi)部對(duì) Python 3 抱有很大的消極情緒??傮w來說,他們認(rèn)為公司的編程語(yǔ)言將永遠(yuǎn)停留在 Python 2.7 版本。還有人建議完全換成另一種語(yǔ)言。Fried 也曾表示(在內(nèi)部社區(qū)中)Python 3 永遠(yuǎn)不會(huì)出現(xiàn)在 Facebook。只有一個(gè)人向他提出質(zhì)疑,并建議他做些事情來改變這種情況,雖然當(dāng)時(shí)他忽略了這個(gè)建議,但這個(gè)想法卻留在了他的腦海里。
希望乍現(xiàn)
2013 年,事情出現(xiàn)了轉(zhuǎn)機(jī)。當(dāng)年一月,當(dāng)時(shí) Facebook 正在使用的“linter”工具需要從 future 導(dǎo)入 print_function、division、absolute_imports 和 unicode_literals,以延長(zhǎng) Python 2 代碼庫(kù)的使用壽命。他們?cè)谌魏?linter 提示的地方導(dǎo)入這些包,這樣可以更容易將模塊轉(zhuǎn)為 Python 3。
用于序列化和遠(yuǎn)程過程調(diào)用的 Apache Thrift 框架在 Facebook“無(wú)處不在”。由于它僅支持 Python 2,所以成為***的障礙。但是,由 Facebook Thrift 團(tuán)隊(duì)發(fā)起的一個(gè)有關(guān) Thrift 新特性的問卷調(diào)查顯示,開發(fā)者普遍希望能夠添加 Python 3 支持。Fried 投了贊成票,但并不是跟風(fēng),他認(rèn)為 Python 2 接口需要重構(gòu),因?yàn)樗雌饋砗孟?Java。
當(dāng)他看到 Guido van Rossum 在舊金山的 Yelp 談?wù)撘粋€(gè)叫做“Tulip”(最終成為了 asyncio 模塊)的東西時(shí),他的想法開始轉(zhuǎn)變。他一直是 Python 異步編程愛好者,但因?yàn)榭蚣埽ɡ?Twisted、gevent)之間的差異而變得碎片化。而 Tulip 讓異步 I/O 操作之間可以互操作。在那次演講結(jié)束之前,他與 Facebook Thrift 團(tuán)隊(duì)溝通,表示 Thrift 應(yīng)該直接支持 Tulip,而不是等 Twisted、gevent 和其他框架遷移到 Python 3。幾天后,Thrift 團(tuán)隊(duì)發(fā)布了一個(gè)路線圖,其中就有對(duì) Python 3 和 Tulip 的支持。
Thrift 團(tuán)隊(duì)在 2014 年初推出了這兩項(xiàng)新特性,但此后六個(gè)月并沒有什么動(dòng)靜。用戶并沒有對(duì)此作出反應(yīng),實(shí)際上他們不關(guān)心,甚至根本不知道已經(jīng)發(fā)生了這些變更。Fried 還順便引用了中國(guó)蓋了房子卻沒人住的例子來說明這種情況,真是讓人哭笑不得。
2014 年(改變文化→從頭開始→強(qiáng)制推行)
新項(xiàng)目
2014 年 8 月,他開始重寫一個(gè)服務(wù),并計(jì)劃使用 gevent 和 Python 2,但他后來才意識(shí)到,如果這么做的話,在完成這個(gè)項(xiàng)目時(shí)它就過時(shí)了。為了有所改變,需要有人成為***個(gè)做出改變的人。要在 Facebook 推動(dòng)使用 Python 3,那個(gè)人非 Fried 莫屬。
于是他使用 Python 3 開始他的項(xiàng)目,可想而知,他面對(duì)的是一個(gè)”一塌糊涂“的局面。當(dāng)時(shí) Facebook 沒有人用 Python 3,構(gòu)建系統(tǒng)不支持他的代碼,而且所有第三方包僅適用于 Python 2。在他修復(fù)了所有問題,讓代碼通過編譯后,又在運(yùn)行時(shí)出了問題。
為了讓代碼能夠正常運(yùn)行,他必須修復(fù)所有問題。他重新構(gòu)建了數(shù)百個(gè)第三方包,這樣它們就可以同時(shí)支持兩個(gè)版本的 Python,而且他必須讓所有內(nèi)部庫(kù)可以兼容 Python 2 和 Python 3。但是,每天都有人會(huì)將 Python 2 變更提交到他的依賴項(xiàng)中。他需要不停地修復(fù)問題,并對(duì)此感到厭倦。一種解決方案是在組織內(nèi)部強(qiáng)制進(jìn)行 Python 3 合規(guī),但這在 Facebook 根本不可能。但是,如果你表現(xiàn)得好像有某種權(quán)力時(shí),人們會(huì)漸漸相信你真的有這種權(quán)力。
他動(dòng)用了很多關(guān)系把 Pyflakes(一個(gè) lint 工具)添加到構(gòu)建過程中。他能夠證明添加它是有道理的,因?yàn)殡m然已經(jīng)有了 PEP 8,但 Pyflakes 可以解決其他額外的代碼質(zhì)量問題。此外,Pyflakes 幾乎沒有誤報(bào),所以它不會(huì)惹火開發(fā)人員。他做了一些設(shè)置,讓 Pyflakes 能夠掃描所有需要審查的代碼,先是 Python 2,然后是 Python 3。這有助于將 Python 3 兼容性擴(kuò)展至所有開發(fā)人員,而不僅僅是他自己,這讓他的項(xiàng)目取得了進(jìn)展。
在剛開始,他必須花費(fèi)大量的時(shí)間向人們解釋“linter 是沒有錯(cuò)的”,并且讓代碼能夠在 Python 3 上運(yùn)行是有價(jià)值的。如果開發(fā)人員開始覺得遷移到 Python 3 是件困難的事,他們就會(huì)回到“讓我們永遠(yuǎn)留在 Python 2”的心態(tài)。他要盡量保證開發(fā)人員能夠順利在 Python 3 上運(yùn)行代碼。
2015 年(培訓(xùn))
培訓(xùn)
雖然克服了一些困難,但在 Facebook 擴(kuò)大 Python 3 地盤的進(jìn)展甚微或毫無(wú)進(jìn)展。他加入了為 Facebook 新員工進(jìn)行 Python 編程培訓(xùn)的團(tuán)隊(duì)。他希望兼容代碼僅用于遺留項(xiàng)目,而新項(xiàng)目應(yīng)該用 Python 3 開發(fā)。
2015 年,他修改了新員工 Python 培訓(xùn)內(nèi)容,表示 Facebook 總有一天會(huì)轉(zhuǎn)向 Python 3,只編寫 Python 2 代碼是沒有意義的,因?yàn)槲磥淼弥貙憽K虒?dǎo)新員工,所有代碼都應(yīng)該與 Facebook 基礎(chǔ)架構(gòu)和構(gòu)建系統(tǒng)一致,如果不是,他們應(yīng)該提交錯(cuò)誤或嘗試自行修復(fù)。這樣,新的員工開始在工作中使用 Python 3,這就是進(jìn)步的開始。“奇怪的是,事情就這么發(fā)生了”。
2015 年 1 月,他終于交付了他的項(xiàng)目。他花了大半年的時(shí)間告訴人們它有多好,為什么他們應(yīng)該盡可能地使用 Python 3。一年來,很多在 Facebook 致力于推行 Python 3 的盟友在公司中出了名。
2016 年(Python 3 成為默認(rèn)編程語(yǔ)言)
其中一位盟友是Łukasz Langa,他“說服了 Instagram 轉(zhuǎn)向 Python 3”。 2016 年,F(xiàn)ried 和 Langa 在 Facebook 組建了一支全新的團(tuán)隊(duì),在公司內(nèi)部培訓(xùn) Python,他們稱之為“滑稽漫步團(tuán)”(The Ministry of Silly Walks)。雖然只有兩個(gè)人,但畢竟是一個(gè)“Python 團(tuán)隊(duì)”,于是他之前提到的“權(quán)威”開始起作用了:人們認(rèn)為他們可以在 Facebook 做出有關(guān) Python 的決策。
2016 年,他發(fā)現(xiàn) Python 3 的采用量增長(zhǎng)雖然緩慢,但還是有穩(wěn)步的增長(zhǎng)。人們?cè)跁?huì)議上提到它,他還經(jīng)常聽到有新項(xiàng)目在使用它。即使 Python 3 不是默認(rèn)設(shè)置,項(xiàng)目也會(huì)選擇使用它,F(xiàn)acebook 此時(shí)對(duì) Python 3 的看法已經(jīng)發(fā)生了變化。2016 年 5 月,F(xiàn)ried 表示打算將構(gòu)建系統(tǒng)切換到默認(rèn)使用 Python 3,他的這一提議幾乎得到了絕對(duì)支持。幾天之后,他完成了切換,切換之后并沒有帶來任何不良影響。
Fried 表示,2016 年,在 Facebook 中推動(dòng) Python 3 項(xiàng)目的只有十個(gè)人,其中三個(gè)是主要推動(dòng)者,而且人事流動(dòng)不斷,做這個(gè)項(xiàng)目的很多人都是兼職。
2016 年底,有一個(gè)項(xiàng)目團(tuán)隊(duì)發(fā)表了一篇文章,其中介紹了切換到 Python 3 的結(jié)果。開發(fā)人員從 Python 2 換到 Python 3 時(shí)只需做出一些修復(fù),運(yùn)行代碼的速度就提高了 40%,并僅使用了一半的內(nèi)存。這打破了 Fried 之前聽到的一個(gè)傳言:Python 3 比 Python 2 慢。早期版本的 Python 3 可能是這樣,但現(xiàn)在肯定不是,他說道。
2017 年(Instagram 遷移)
好事情發(fā)生
2017 年初,F(xiàn)acebook 因?yàn)?Instagram 完成了 Python 3 遷移而感受到 Python 3 遷移帶來的榮光。Python 版本升級(jí)原來并不可怕,反而帶來了可用的新功能。Facebook 開發(fā)人員現(xiàn)在開始使用新的靜態(tài)類型或使用 asyncio 改造舊服務(wù)。“Python 在 Facebook 又開始變得很有趣了”。
現(xiàn)在的問題是,每個(gè)人都在問什么時(shí)候可以停止支持 Python 2。當(dāng) Python 2 支持庫(kù)或模塊出現(xiàn)回歸時(shí),通常會(huì)聽到開發(fā)人員詢問是否可以直接升級(jí)到 Python 3。而幾年前,情況是完全相反的。“哦,世界真美好?。?rdquo;
2018 年(Python 3 占比超過 55%)
他展示了一張 Facebook 的 Python 服務(wù)入口端點(diǎn)隨時(shí)間變化的圖表,從 2015 年第三季度開始,那個(gè)時(shí)候只有四個(gè) Python 3 服務(wù)入口端點(diǎn)。截至 2016 年年中,當(dāng)切換到默認(rèn)使用 Python 3 時(shí),F(xiàn)acebook 已經(jīng)有 4% 的服務(wù)入口端點(diǎn)使用了 Python 3。2018 年 3 月,這一比例超過 50%。5 月中旬,當(dāng)他發(fā)表演講時(shí),運(yùn)行 Python 3 的 Facebook 服務(wù)入口端點(diǎn)比例已達(dá) 55%。在 Facebook,只能在 Python 2 上運(yùn)行的代碼現(xiàn)在處于尷尬的境地,F(xiàn)ried 說道。
Łukasz Langa 發(fā)推文,對(duì) Python 3 低 CPU 占用和運(yùn)行速度提升表示贊賞。
演講接近尾聲,他對(duì)演講做了概述??偟膩碚f,他的建議包括:
-
你要做的是創(chuàng)新,做出改變,結(jié)果自然會(huì)來;
-
你必須通過“親力親為讓人看到你想要的變化”來引導(dǎo)開發(fā)者;
-
你還應(yīng)該尋求他人的幫助,不要單槍匹馬;
-
另外,培訓(xùn)新員工去實(shí)現(xiàn)你未來的目標(biāo)是很重要的。
-
收集需要的數(shù)據(jù);
-
享受得到的成果,用 Python 3 寫一些“非常棒的東西”。
***,他還回答了觀眾提出的一些問題。有人問,如何在傳統(tǒng)、等級(jí)分明的組織中實(shí)現(xiàn)演講中所說的目標(biāo)。Fried 認(rèn)為,實(shí)際上這可能會(huì)更容易一些,因?yàn)槟悴恍枰f服成千上萬(wàn)的開發(fā)者,只需要讓管理層意識(shí)到這件事情的好處就可以了。如果在文化保守的組織中,這也可能很難,但專注于代碼質(zhì)量改進(jìn)可能對(duì)此有所幫助。另一個(gè)問題是關(guān)于整體代碼,而不是多個(gè)入口點(diǎn),對(duì)于這個(gè)問題,F(xiàn)ried 建議看看 PyCon 2017 上的 Instagram 主題演講(見文章開頭)。
整個(gè)演講讓人受益匪淺,包括 Fried 強(qiáng)調(diào)的倡導(dǎo)者和***,以及堅(jiān)持不懈的精神在一個(gè)項(xiàng)目中的的重要性。
原文鏈接: