更多幹貨內容請關注微信公眾號“AI 前線”,(ID:ai-front)
按例先貼演講視訊:
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 年的時間,實屬不易。
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 年 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 上執行程式碼。
雖然克服了一些困難,但在 Facebook 擴大 Python 3 地盤的進展甚微或毫無進展。他加入了為 Facebook 新員工進行 Python 程式設計培訓的團隊。他希望相容程式碼僅用於遺留專案,而新專案應該用 Python 3 開發。
2015 年,他修改了新員工 Python 培訓內容,表示 Facebook 總有一天會轉向 Python 3,只編寫 Python 2 程式碼是沒有意義的,因為未來得重寫。他教導新員工,所有程式碼都應該與 Facebook 基礎架構和構建系統一致,如果不是,他們應該提交錯誤或嘗試自行修復。這樣,新的員工開始在工作中使用 Python 3,這就是進步的開始。“奇怪的是,事情就這麼發生了”。
2015 年 1 月,他終於交付了他的專案。他花了大半年的時間告訴人們它有多好,為什麼他們應該儘可能地使用 Python 3。一年來,很多在 Facebook 致力於推行 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 年初,Facebook 因為 Instagram 完成了 Python 3 遷移而感受到 Python 3 遷移帶來的榮光。Python 版本升級原來並不可怕,反而帶來了可用的新功能。Facebook 開發人員現在開始使用新的靜態型別或使用 asyncio 改造舊服務。“Python 在 Facebook 又開始變得很有趣了”。
現在的問題是,每個人都在問什麼時候可以停止支援 Python 2。當 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 說道。
Łukasz Langa 發推文,對 Python 3 低 CPU 佔用和執行速度提升表示讚賞。
演講接近尾聲,他對演講做了概述。總的來說,他的建議包括:
你要做的是創新,做出改變,結果自然會來;
你必須通過“親力親為讓人看到你想要的變化”來引導開發者;
你還應該尋求他人的幫助,不要單槍匹馬;
另外,培訓新員工去實現你未來的目標是很重要的。
收集需要的資料;
享受得到的成果,用 Python 3 寫一些“非常棒的東西”。
最後,他還回答了觀眾提出的一些問題。有人問,如何在傳統、等級分明的組織中實現演講中所說的目標。Fried 認為,實際上這可能會更容易一些,因為你不需要說服成千上萬的開發者,只需要讓管理層意識到這件事情的好處就可以了。如果在文化保守的組織中,這也可能很難,但專注於程式碼質量改進可能對此有所幫助。另一個問題是關於整體程式碼,而不是多個入口點,對於這個問題,Fried 建議看看 PyCon 2017 上的 Instagram 主題演講(見文章開頭)。
整個演講讓人受益匪淺,包括 Fried 強調的倡導者和領導者,以及堅持不懈的精神在一個專案中的的重要性。
原文連結:
https://lwn.net/SubscriberLink/758159/f1f631e1535ab9d6/