亲爱的谷歌云:您的弃用政策正在杀死您

2020-08-15 11:52:14

该死的,我不想再写博客了。我有很多事情要做。写博客需要我可以好好利用的时间、精力和创造力:我的小说、我的音乐、我的游戏等等。但你让我够生气了,我还得写博客。

我将从我在谷歌早期的一个很小但相当整洁的故事开始。郑重声明,我知道我最近说了一些关于谷歌的坏话,因为当你的公司母校经常做出无能的商业决策时,这是令人沮丧的。但谷歌的内部基础设施确实相当出色,你可能会说,今天还没有比这更好的了。建造谷歌的人比我永远都是更好的工程师,这件轶事应该足以说明这一点。

首先是一点背景知识:谷歌有一项名为Bigtable的存储技术。Bigtable是一项了不起的技术成就,它是第一批(如果不是第一批)“无限可伸缩的”键值存储之一:基本上是NoSQL的开始。这些天,Bigtable仍然在相当拥挤的K/V商店中保持良好的地位,但回到那一天(2005年),它是令人叹为观止的酷。

关于Bigtable的一个有趣的琐事是,他们有这些内部控制平面实体(作为实现的一部分),称为Tablet服务器,它们有很大的索引,在某种程度上,它们成为了扩展瓶颈。因此,Bigtable的工程师们绞尽脑汁想如何让它变得可扩展,并意识到他们可以用Bigtable取代平板电脑服务器来解除扩展障碍。因此,Bigtable是其自身实现的一部分。从下到下都是大块头。

另一个很酷的琐事是,有一段时间,Bigtables在谷歌内部变得流行和无处不在,他们的狗每个人都有一个。因此,在一个周五的TGIF全体员工大会上,拉里·佩奇(Larry Page)不经意地问道:“为什么我们有不止一个Bigtable?为什么不只有一个呢?“。因为从理论上讲,一个Bigtable应该就足以满足Google的所有存储需求。当然,由于实际的软件工程原因(例如,爆炸半径),它们从未迁移到只有一个,但理论很有趣。整个宇宙的一个数据库。(附注:有人知道塞布尔在亚马逊做这件事吗?)。

有一天,我在谷歌工作了两年多一点后,收到了Bigtable工程团队发来的一封电子邮件。它说了一些大致的话:

来自Bigtable团队的问候。我们想让您知道,您在[某个数据中心名称]数据中心运行的是一个非常非常旧的Bigtable二进制文件。不再支持该版本,我们愿意与您合作,帮助您升级到最新版本。

如果您能安排一些时间与我们合作,请让我们知道。

正如你可以想象的那样,你在谷歌收到了很多电子邮件,当我瞥了一眼这封邮件时,我第一次感觉到它是这样说的:

来自某个团队的问候。我们想让你知道胡说八道。废话,废话,马上废话。

请让我们知道你是否可以安排一些宝贵的时间来废话废话。

我几乎当场就把它删除了,但有一种挥之不去的、纠结的感觉,那就是它感觉不太像是套用信函,尽管它显然不是给我的,因为我没有Bigtable。

在这一天剩下的时间里,当我在工作和决定下一步在迷你厨房尝试哪种鲨鱼软糖时(其中至少有三种离我足够近,可以从我的座位上用一块瞄准得很好的饼干击中),我带着越来越轻微的焦虑感思考着那封电子邮件。

他们特别提到了我的名字。而且电子邮件已经发送到我的电子邮件地址,而不是其他人的电子邮件地址,并且不是由cc:或bcc:发送的。语气非常个人化和尖锐。也许这是某种误会?

好奇心终于战胜了我,我去他们在电子邮件中提到的数据中心看了看我的博格控制台。

果然,我在那里经营着一家Bigtable。怎么了?我看了看里面的东西,瞧!这是我在成为Noogler的第一周,也就是2005年6月,从Bigtable代码实验室运行回来的。Codelab让您启动一个Bigtable,这样您就可以通过编程向其中写入一些值,而我显然从未在之后关闭过它。两年多后,它还在那里运行。

这个故事有几个值得注意的方面。其一是运行Bigtable与谷歌的规模无关紧要,以至于人们花了两年时间才注意到它,而且即便是那样,也只是因为版本太旧了。作为比较,我考虑在我的在线游戏中使用Google Cloud Bigtable,但在GCP上使用一个空的Bigtable估计要花费16000美元/年。我不是说他们在骗你,但在我个人看来,对于一个他妈的空数据库来说,这感觉是一大笔钱。

另一个值得注意的方面是,它在两年后仍然在运行。见鬼?数据中心来来去去;他们经历了停机,他们经历了例行维护,他们一直在变化。硬件升级,网络交换机更换,一切都在不断改进。面对所有这些变化,他们怎么能让我的软件运行两年呢?在2020年,这可能感觉是一个平凡的成就,但在2005-2007年间,它是相当令人印象深刻的。

在我看来,最值得注意的是,另一个州的一个无关的工程团队正在联系我,我是一个小的、几乎是空的Bigtable实例的所有者,这个实例在过去两年里没有任何流量,问他们是否可以帮助我升级。

我感谢他们,然后关闭了它,生活还在继续。但13年后的今天,我仍然会想起那封信。因为我有时会从谷歌云平台收到类似的信件。它们看起来是这样的:

我们在此提醒您,我们将于2020年8月起停止[您正在使用的重要服务],之后您将无法对您的实例进行任何更新或升级。我们鼓励您升级到最新版本,该版本是Beta版,没有文档,没有迁移路径,我们事先已经建议您不要使用该版本。

我们致力于确保Google Cloud平台的所有开发人员都能最大限度地减少这一变化的影响。

去他妈的Yoooouuuuuuu。去你妈的,去你妈的,去你妈的。放下你正在做的任何事情,因为它不重要。重要的是我们的时间。养活我们的狗屎耗费了我们的时间和金钱,我们已经厌倦了,所以我们不会再支持它了。所以放下你的计划,开始挖掘我们糟糕的文档,在论坛上乞讨垃圾,哦,顺便说一句,我们的新狗屎与旧的狗屎完全不同,因为我们把那个设计搞砸了,呵呵,但嘿,那是你的问题,不是我们的问题。

我们将一如既往地致力于确保您所写的所有内容在1年内都无法使用。

事情是这样的,我大约一个月收到一次。它发生得如此频繁,如此可靠,以至于我被无情地从GCP推向云不可知论。我不再依赖他们的专有服务产品,因为与试图跟上谷歌的弃用跑步机相比,平均而言,DevOps支持在裸VM上运行的开源系统所做的工作实际上要少得多。

在我回到Google Cloud平台上之前,因为我还远未完成,所以让我们先来看看软件工程在其他领域是如何工作的。谷歌工程师以他们的软件工程纪律为荣,这实际上是让他们陷入麻烦的原因。骄傲是粗心大意的人的陷阱,它诱使许多谷歌团队认为他们的决定总是正确的,正确(根据某种模糊的定义)比关注客户更重要。

我将从其他大型软件系统中挑选一些有点武断的示例,但希望您能够开始发现到处都存在的模式;该模式是:向后兼容使系统在几十年内保持活力和相关性。

向后兼容性是所有为开放使用而设计的成功系统的设计目标;也就是说,作为开放源码实现,和/或由开放标准指导。我觉得我在说一些显而易见的事情,我们都应该感到尴尬,但事实并非如此。这是一个政治问题,所以我需要一些例子。

我要选择的第一个系统是最古老的:GNU Emacs,它是Windows记事本(一个单片内核操作系统)和国际空间站(International Space Station)的混合体。这有点难以解释,但简而言之,Emacs是一个编写于1976年(是的,几乎是半个世纪前)的平台,用于编写软件以提高您的工作效率,伪装成文本编辑器。

我每天都用Emacs。是的,我也每天都在使用IntelliJ,而IntelliJ本身已经成长为一个强大的工具平台。但是,与为Emacs编写扩展相比,为IntelliJ编写软件扩展是一项更雄心勃勃、更复杂的任务。更重要的是,Emacs上的东西是永恒的。

我仍然在使用1995年为Emacs编写的软件。我敢肯定,如果不是更早,也有一些人仍然在使用他们从80年代中期为Emacs编写的软件。每隔一段时间,它可能需要做一些小调整,但这真的很少见。我没有意识到我曾经为Emacs编写过任何被迫重新架构的东西(而且我写了很多)。

Emacs确实有一个称为make-obsolete的弃用工具。Emacs对基本软件工程概念(比如什么是“窗口”)的术语通常不同于行业惯例,因为Emacs在很久很久以前就发明了它们。走在你们的时代之前的危险:你们的名字都是错的。但Emacs确实有不受欢迎的说法,在他们的行话中被称为过时。

然而,Emacs的人员似乎有不同的工作定义。一种不同的基本哲学,如果你愿意的话。

在Emacs领域(以及在许多其他领域,我们将在下面讨论其中一些领域),当他们使API过时时,他们基本上是在说:“您真的不应该使用这种方法,因为即使它有效,它也存在各种缺陷,我们在这里列举了这些缺陷。但最终还是由你说了算。“。

而在谷歌的世界里,贬低意味着:“我们违背了对你们的承诺。”确实如此。这就是它最终的意思。这意味着他们会强迫你做一些工作,可能是大量的返工,作为对他们最初告诉你做的事情的惩罚-作为对听了他们网站上光鲜的营销的惩罚:更好的软件。再快点!你做了他们告诉你做的一切,你启动了你的应用程序或服务,然后,砰地一到两年后,它就崩溃了。

这就像卖给你一辆他们知道不到1000英里就会抛锚的二手车。

这是两种截然不同的哲学定义。谷歌的定义散发着计划淘汰的恶臭。我不认为这实际上是有计划的淘汰,比如苹果实施的那种意义上的淘汰。但谷歌肯定计划以一种迂回的方式打破你的东西。我知道,因为我在那里当了12年以上的软件工程师。对于在服务中加入多少向后兼容性,他们有松散的内部指导方针,但最终取决于每个单独的团队或服务。没有公司级或工程级的指导方针,任何人有勇气推荐的最长时间,就弃用周期而言,是“试着给你的客户6-12个月的时间来升级,然后再把他们盖在桶上。”

这对他们的伤害比他们意识到的要大得多,而且在未来的几年里还会继续伤害他们,因为关心客户不是他们DNA的一部分。下面是关于这一点的更多信息。

目前,我将大胆断言,Emacs之所以成功,在很大程度上,甚至可能在很大程度上是因为它们非常认真地对待向后兼容性。事实上,这就是本文的主题。成功的长寿命开放系统的成功归功于围绕扩展/插件(也称为市场)构建了长达数十年的微型社区。我以前也谈过平台,它们有多重要,谷歌在整个公司历史上从来没有真正理解过要打造一个成功的开放平台需要做些什么,更不用说Android或Chrome了。

实际上,我应该简短地谈谈Android,因为您可能会想,嘿,Android怎么样?

首先,Android不是谷歌。他们几乎没有任何关系。Android是一家在2005年7月被谷歌收购的公司,该公司被允许或多或少地自主运营,事实上,在其间的几年里,该公司基本上保持了完好无损。Android是一个臭名昭著的多毛技术堆栈,也是一个臭名昭著的多刺组织。正如一位谷歌员工所说,“人不能简单地走进Android。”

我对Android早期的一些设计决策有多糟糕大加抱怨。见鬼,当我大喊大叫的时候,他们正忙着推出像即时应用程序这样的狗屎,这现在(令人惊讶!)。如果你笨到听他们的话,当他们告诉你把你所有的东西都移植到即时应用程序上时,你会被他们抛弃的,如果你真的傻到听了他们的话,那你就该哈哈了。

但这里有一个区别,一个实质性的区别,那就是Android人员确实理解平台有多重要,他们会不遗余力地防止破解你的旧Android代码。事实上,他们保持向后兼容性的努力是如此极端,以至于就连我几年前在Android系统短暂停留期间,也发现自己在试图说服他们放弃对一些最古老的设备和API的支持。(我错了,因为我在过去和现在的许多其他事情上都是这样的。抱歉,Android的朋友们!现在我访问了印度尼西亚,我明白我们为什么需要它们了。)。

Android的人们将向后兼容性推向了几乎难以想象的极端,这在他们的系统和工具链中堆积了大量遗留的技术债务。哦,天哪,你应该看看他们在构建系统中不得不做的一些疯狂的事情,所有这些都是以兼容性的名义进行的。

为此,我授予Android“梦寐以求的你不是谷歌”奖。你真的不想成为谷歌。他们不知道如何构建能够持久的平台,而Android知道如何做到这一点。因此,谷歌在一个方面非常明智:让Android员工按自己的方式做事。

不过,即时应用程序是一个相当愚蠢的想法。你知道为什么吗?因为它需要您重写和重新架构您的应用程序!就好像人们只是要启动并重写200万个应用程序一样。我猜Instant Apps可能是谷歌人的主意。

但是你可以看到这里的不同之处。向后兼容带来了高昂的成本,Android选择了承担这一成本的负担,而谷歌则坚持让你作为付费客户来承担这一负担。

你可以在他们的API中看到Android对向后兼容的承诺。这是一个明确的迹象,当有四到五个不同的共存子系统在做完全相同的事情时,所有这一切的基础都是对向后兼容性的承诺。在平台界,这是对您的客户和您的市场的承诺的同义词。

谷歌对其软件工程卫生的自豪感让他们在这里陷入了麻烦。他们不喜欢有很多不同的方法来做同样的事情,旧的、不太可取的方法与新的、花哨的方法并驾齐驱。它增加了系统新手的学习曲线,增加了支持遗留API的负担,减缓了新功能的速度,最糟糕的是:它很难看。谷歌就像蒂姆·伯顿的“爱丽丝梦游仙境”中的阿斯科特夫人:

为了探索丑陋与实用之间的权衡,让我们来看看第三个成功的平台(在Emacs和Android之后),看看它的表现如何:Java本身。

Java有大量不推荐使用的API。弃用在Java程序员中非常流行,比大多数编程语言更受欢迎。Java本身是核心语言和库,一直不推荐使用API。

仅举数千个例子中的一个,杀死线程是不受欢迎的。从1998年12月发布的Java1.2开始,它就被弃用了。他们已经反对它22年了。

我的实时生产代码仍然每天杀死线程。这是好事吗?绝对一点儿没错!。我的意思是,很明显,如果我今天重写代码,我会用不同的方式。但我的游戏代码在过去的20年里已经能够让数十万人感到快乐,它是为了杀死耗时太长的工作线程而编写的,我从来没有更改过它。我最了解我的系统,我在生产中运行它确实有25年的经验,我可以告诉您:在我的用例中,杀死这些特定的工作线程是无害的。把我的时间和精力集中在重写代码上是不值得的,应该赞扬Larry Ellison(我想),因为Oracle从来没有让我重写过它。

您可以通过Java的核心API看到所有的证据,就像峡谷中的冰川线一样。在Java Swing中很容易就有五六个不同的键盘焦点管理器。事实上,很难找到没有被弃用的Java API。但它们都还能用!我认为Java核心团队真正删除API的唯一情况是它造成了明显的安全问题。

各位,事情是这样的:我们这些软件开发人员都非常忙碌,而且我们在每个软件领域都面临着竞争对手的选择。在任何给定的时间,使用X语言的程序员都在将Y语言视为可能的替代品。哦,你不相信我?那斯威夫特呢?每个人都在迁移到斯威夫特,而不是离开它,对吗?哦,你知道的太少了。企业开始用雇佣兵的方式来解释他们的双重移动团队(iOS和Android),并开始意识到,那些听起来像是狗狗和小马表演的跨平台开发系统,比如Ffltter和Reaction Native,是真正的牙齿,使用它们可以将他们的移动团队规模削减一半,或者让他们的工作效率翻一番。这里有真正的钱岌岌可危。是的,这是有权衡的,但另一方面,也有些微不足道。

假设苹果愚蠢到使用Guido van Rossum,并宣布Swift 6.0向后兼容Swift 5.0,就像Python3与Python2不兼容一样。

我可能在10年前就讲过这个故事,但大约15年前,我和吉多在奥莱利的Foo Camp,和保罗·格雷厄姆(Paul Graham)以及其他一群当时的垃圾坐在帐篷里,等待拉里·佩奇(Larry Page)乘坐他的私人直升机飞出去,吉多在酷热中沉闷地喋喋不休地谈论“Python 3000”,他给这个名字是为了纪念每个人迁移到它需要多少年的时间。我们一直问他为什么要破坏兼容性,他回答说,“Unicode”。我们会问他,嘿,如果我们必须重写我们的代码,那么我们还会看到什么好处呢?他会回答说,“你好啊,好啊,你好啊,好啊。”

如果您安装了Google Cloud Platform“gcloud”SDK,您会收到这样的通知:

我们想提醒您,对Python2的支持已弃用,所以Fuuuuuck yoooooooooooooouuuu。

但问题是,每个开发者都有自己的选择。如果你让他们重写代码的次数足够多,其他一些选择就会开始看起来很有吸引力。他们不是你的人质,正如你所希望的那样。他们是你们的客人。可以肯定的是,Python仍然是一种非常流行的编程语言,但幸运的是,Python3(000)确实给他们自己、他们的社区和他们社区的软件的用户造成了巨大的混乱-这是一个15年来一直在发展中的火车残骸,至今仍在继续。

.