专栏名称: 聊聊架构
在这里煮酒聊架构。
目录
相关文章推荐
51好读  ›  专栏  ›  聊聊架构

Python向来以慢著称,为啥Instagram却唯独钟爱它?

聊聊架构  · 公众号  · 架构  · 2017-06-02 11:50

正文

请到「今天看啥」查看全文


在相当长的一段时间,Instagram 都跑在 Python 2.7 + Django 1.3 的组合之上。在这个已经落后社区很多年的环境上,他们的工程师们还打了非常非常多的小 patch。难道他们要被永远卡在这个版本上吗?

所以,在经过一系列的讨论后,他们最终做出一个重大的决定:升级到 Python 3!!

事实上,Instagram 目前已经完成了将运行环境迁移到 Python 3 的工作 - 他们的整套服务已经在 Python 3 上跑了好几个月了。那么他们是怎么做到的呢?接下来便是由 Instagram 工程师 Lisa guo 带来的 Instagram 如何迁移到 Python 3 的故事。

对于 Instagram 来说,下面这些因素是推动他们将运行环境迁移到 Python 3 的主要原因:

1. 新特性:类型注解 Type Annotations

看看下面这段代码:

def compose_from_max_id(max_id):
    '''@param str max_id'''

图中函数的 max_id 参数究竟是什么类型呢?int?tuple?或是 list? 等等,函数文档里面说它是 str 类型。

但随着时间推移,万一这个参数的类型发生变化了呢?如果某位粗心的工程师修改代码的同时忘了更新文档,那就会给函数的使用者带来很大麻烦,最终还不如没有注释呢。

2. 性能

Instagram 的整个 Django Stack 都跑在 uwsgi 之上,全部使用了同步的网络 IO。这意味着同一个 uwsgi 进程在同一时间只能接收并处理一个请求。这让如何调优每台机器上应该运行的 uwsgi 进程数成了一个麻烦事:

为了更好利用 CPU,使用更多的进程数?但那样会消耗大量的内存。而过少的进程数量又会导致 CPU 不能被充分利用。

为此,他们决定跳过 Python 2 中哪些蹩脚的异步 IO 实现 (可怜的 gevent、tornado、twisted 众),直接升级到 Python 3,去探索标准库中的 asyncio 模块所能带来的可能性。

3. 社区

因为 Python 社区已经停止了对 Python 2 的支持。如果把整个运行环境升级到 Python 3,Instagram 的工程师们就能和 Python 社区走的更近,可以更好的把他们的工作回馈给社区。

迁移方案

在 Instagram,进行 Python 3 的迁移需要必须满足两个前提条件:

  1. 不停机,不能有任何的服务因此不可用

  2. 不能影响产品新特性的开发

但是,在 Instagram 的开发环境中,要满足上面这两点来完成迁移到 Python 3.6 这种庞大的工程是非常困难的。

基于主分支的开发流程

即便使用了以多分支功能著称的 git,Instagram 所有的开发工作都是主要在 master 分支上进行的,Instagram 所奉行的开发哲学是:『不管是多大的新特性或代码重构,都应该拆解成较小的 Commit 来进行。』

那些被合并进 master 分支的代码,都将在一个小时内被发布到线上环境。而这样的发布过程每天将会发生上百次。在这么频繁的发布频率下,如何在满足之前的那两个前提下来完成迁移变得尤其困难。

被弃用的迁移方案
创建一个新分支

很多人在处理这类问题时,第一个蹦进脑子的想法就是: 『让我们创建一个分支,当我们开发完后,再把分支合并进来』。但在 Instagram 这么高的迭代频率上,使用一个独立分支并不是好主意:

  • Instagram 的 Codebase 每天都在频繁更新,在开发 Python 3 分支的过程中,让新分支与现有 master 分支保持同步开销极大,同时极易出错

  • 最终将 Python 3 分支这个改动非常多的分支合并回 Master 拥有非常高的风险

  • 只有少数几个工程师在 Python 3 分支上专职负责升级工作,其他想帮助迁移工作的工程师无法参与进来

挨个替换接口

还有一个方案就是,挨个替换 Instagram 的 API 接口。但是 Instagram 的不同接口共享着很多通用模块。这个方案要实施起来也非常困难。







请到「今天看啥」查看全文