当前位置: 首页 > 科技观察

在正确的时间采用革命性的技术,Slack技术进化模式

时间:2023-03-18 02:38:59 科技观察

科技中的大多数新事物都只是时尚:说话和做事的模式来来去去,没有留下任何永久的印记。微内核、IA-64架构、对象请求代理、1990年代的神经网络,这些东西已经过去了,不会再回来了。时间已经证明哪些事情是短暂的,为了证明我们必须回溯很久。我们今天很难想象这些技术在全盛时期有多流行。他们有许多有魅力、真诚和聪明的拥护者,这些拥护者得到看似合理的基本论据的支持,这些论据证明了他们所选择的技术不可避免的胜利。这些趋势催生了运动、宣言、会议和公司。但请不要将这些趋势与故意欺诈相混淆,这种情况并不常见。推动这些技术趋势的动机是真诚的,无论以何种方式出现,两者的结果都是截然不同的。另一方面,一些重要的新技术是革命性的:它们强大而持久的变化为技术的采用者带来了长期优势。面向对象编程、硬件虚拟化、万维网、公共云、CI/CD和1990年代的神经网络(深度学习的重生)现在是计算世界的永久组成部分,它们曾经“混合在一起”,难以区分。我们被技术浪潮所包围,在它们出现之前,我们不知道如何利用它们来取得成功。与其他科技公司一样,Slack希望在合适的时间采用革命性的技术,避免浪费太多精力追逐潮流。Slack采用什么策略来确保这一点?这篇文章描述了Slack用来解决这个问题的方法。1.区分时尚和革命我们不能依靠个别领导人的直觉来判断谁是赢家。相反,我们必须积极探索新事物,尽管我们也知道这些尝试中的大多数不会有任何回报。但是为了让我们的投资偏向于有用的新事物,避免踩太多时髦的坑,我们应该在前期狠狠的杀掉那些毫无价值的实验。我们想尝试一切,这意味着我们仍然必须顺应潮流。我们希望最终能渡过难关,而我们与之合作的经验继续为我们提供积极的回报。2.技术采用曲线我们创建了一个描述性的新技术采用曲线模型。这是一个典型的S曲线,描述了随着时间的推移技术的采用情况。S形反映了技术采用的变化。一开始只有几个实验者在做实验,我们只好慢慢来。以后情况明朗了,就会有更多的人参与进来,我们会在中间陡峭的上坡上,迅速将新技术应用到生产中去。当大多数富有成果的实验都圆满完成时,剩下的难点就很少了。然后,在周期结束时,采用率再次放缓。我们画出这三个阶段:我们不是第一批发现技术采用遵循这条S曲线的人。EverettRogers于1962年在他的书《创新扩散理论》(创新扩散)中提出了这个模型。不过,Rogers没有提到Erlang或MongoDB,因为他是一位研究农业技术采用模式的农村社会学家。但事实证明,计算领域与人类活动的其他领域并没有太大区别。为了使这种抽象更加具体,我们将举例说明一些在Slack经历了探索、扩展和迁移阶段的技术。3、自2015年发布第一个稳定版React以来,React席卷了前端开发领域。虚拟DOM和单向数据绑定使其成为开发Slack桌面用户界面的一项引人注目的技术。2016年,React在Slack还是一个前端开发的陌生技术。在第一阶段,对React感兴趣的工程师开始试验它,在试点项目中使用它。当他们确信React可以为Slack带来巨大价值时,他们开发了一个令人信服的演示项目,该项目使用React重建了Slack的表情符号选择器。这个React开发的SlackUI(在感觉迟钝之前)比以前表现得更好。原型比理论证明或白板草图更容易被开发人员采用。当我们的团队意识到React将对我们的代码库产生重大影响时,不可能通过小手术让React的性能优势显现出来。但也不可能进行大规模重写,因为风险回报率不允许我们这样做。当React进入阶段2时,一个真正的迁移项目开始了。该项目有一个计划,并配备了大量的开发人员。随着项目的进展,许多团队也选择了新的视图样式。但在这个中间阶段,许多旧观点仍然存在,需要维护。在第三阶段,我们清理了客户端代码库中的遗留视图。我们终于在2019年7月发布了Slack的React-only桌面版本。4.Hack在服务器端,我们从2016年开始从PHP迁移到Hack。这次迁移的一个关键部分是在我们的PHP代码中逐渐引入类型:2017年我们进入了第一阶段,一些类型爱好者开始使用简单代码库中的类型。有些人发现这些类型可以在代码投入生产之前捕获错误,并且也开始使用类型。这无意中将Hack的类型系统推入了第二阶段(其他用户也受到影响)。但是,新的类型注解也带来了一些问题,于是我们开始讨论标准的静态类型和动态类型。通过讨论和经验积累,我们达成了普遍共识,即增加类型使用规模利大于弊,大多数团队选择使用类型。在第二阶段,我们做了更大的努力来迁移代码,以便新添加的代码可以使用静态类型。困难的部分留给第三阶段。合理化Slack自身的内部对象变量和转换一些复杂的核心模块非常耗时。5.VitessVitess是一个用于MySQL水平扩展的集群系统。我们在数据分片策略的演进过程中选择了它。在第一阶段开始时,我们对Vitess的能力进行了严格的审查。我们花了很多时间手动管理自己的分片解决方案,而Vitess的自动化功能解决了我们的大部分痛点。Vitess团队最终确信该技术值得采用。一些低风险的工作负载,比如RSSfeeds,从第2阶段开始迁移到Vitess。第2阶段早期不需要Vitess团队外部的太多参与,但由于它是一个新的数据存储系统,仍然需要运营支持.随着越来越多的表迁移到Vitess,我们逐渐降低风险,让Vitess满足我们应用场景的需求。我们开发了回填的工具,建立了一些在迁移过程中使用的术语(例如,复制数据称为“暗读”),并总结了可能出现的各种问题。我们已经迁移了数百张表,总计超过50%的查询工作量,但在第三阶段仍然有一些“困难”和“长尾表”需要处理。一些关键表具有复杂的依赖关系和查询模式,难度更大处理比第二阶段迁移的表。另外,我们有一些“长尾表”,不值得一个一个手动迁移,所以我们正在开发批量迁移的工具。6.LibSlack与上述经历了不同采用阶段的技术相比,我们的跨平台C++客户端库没有进入第3阶段并最终停止。在第一阶段,LibSlack工程师验证了用于业务逻辑和数据缓存的共享客户端库的概念,并深入研究了跨平台库的编译和交付。然而,该项目在第二阶段没有取得进展。图书馆和我们的桌面客户端之间的技术和战略不兼容变得显而易见。事实证明,在我们的iOS和Android客户端中使用LibSlack库重新实现现有逻辑和缓存会很麻烦。然而,由于WindowsPhone的停产,Slack需要维护的客户端代码库少了一个。我们最终没有进行完整的迁移。我们以各种方式将从LibSlack中学到的知识应用到我们的移动和桌面客户端开发工作中。代码工件并没有被采用很长时间,但该项目教会了我们如何构建客户以及如何组织我们的工程团队。7.曲线分析需要注意的是,这个模型是描述性的,而不是说明性的。我们并没有试图强迫人们进入这个S曲线,即使我们想要这样做。其实,这是一个自然的过程。探索的早期阶段无法像中期阶段那样快速推进,最终阶段也无法像中期阶段那样快速实现全面采用。这三个阶段不是任何里程碑、过程、工具或Slack工程人员角色的结果。它们是技术变革的一部分,无论我们是否注意到它们,它们都会存在。既然我们已经注意到它们,我们就可以利用它们来使我们的努力更有效。每个阶段的战术和策略都不同。8.第一阶段:探索第一阶段是无门槛进入。当工程师第一次开始研究他们感兴趣的技术时,不需要许可过程或仪式。在Slack,这种情况每天会发生几十次:有人发现了一项新技术,或者发明了一些新东西,然后开始研究它。他们可能已经阅读了有关Elixir、Cassandra、WebAssembly或TCR的博客文章,或者下载了一些软件,对其进行了编译,四处查看,浏览了一些介绍性材料,并可能尝试将其应用到他们的日常工作中。大多数勘探工作都发生在这个阶段。在这个阶段,为了避免在不必要的事情上花费过多的精力,我们必须懂得放弃一些东西。尽管如此,有些东西确实进入了实际的工作流程和代码库。有时,工程师可以直接应用某些解决方案,因为他们解决了一些局部问题。有时会出现更令人兴奋的结果:一些解决方案还解决了其他团队面临的问题。这个阶段的工程师相信他们知道一些其他人不知道的事情:有些事情可以用更好的方式来完成。一旦他们的工作开始影响其他人,我们就进入第二阶段。9.第二阶段:资料片进入第二阶段,工程师有点可怜!因为他们现在正试图改变其他工程师的行为,这将涉及沟通、说服,如果一切顺利,他们将进行大量技术工作。对于大多数项目,第2阶段是最困难、最耗时且最令人沮丧的阶段。这是技术周期中的“产品-市场契合”阶段,很多进入这个阶段的项目都未能顺利度过。在Slack中,用户团队可以自由选择是否依赖你的系统,几乎没有例外。如果你习惯了“基础设施驱动”的公司,那么我们的情况可能会让你大吃一惊。在其他公司,领导层会在第2阶段产品与市场匹配结束之前挑选赢家和输家。他们这样做是为了提供清晰度(比如未来会怎样,我们应该采用哪种系统)并降低成本,因为现阶段需要支持更多的做事方式。虽然这些都是合理的目标,但Slack选择不这样做。我们的首要任务是适应趋势的能力,而不是适应的速度。因此,我们(有意)将促进其他团队采用新技术的主要负担放在一小群人身上。虽然这可能会让这些人感到沮丧,但我们知道没有其他办法。为了消除这个障碍,我们不得不选择一种更有效的方法。如果新技术像我们希望的那样好,它们应该可以帮助依赖它们的团队完成工作。反过来,这一结果促使他们采用并扩大这些新技术。第二阶段的一些工作更像是产品工作而不是工程工作。您需要研究用户以确定哪些问题很重要。您需要以用户期望的方式将您的解决方案的价值与以前的实践联系起来。您需要找到弥合当前实践与您所做的更改之间的差距的方法,以使它们更容易被用户接受。第二阶段的成功最终会导致一些自发的采用,用户可以自由选择是否采用新技术。当新系统成为事实上的标准时,第二阶段结束。偶然遇到这种采用是不寻常的,因为它真的很难,而且并不是每个工程师都具备相关技能。10.第3阶段:迁移自发采用最终会逐渐减少,留下一些顽固的人似乎抵制新的做事方式。一些在后台运行的系统尤其没有动力进行更改,因为它们没有被积极开发。在某些情况下,我们在后期发现旧系统的某些方面以旧方式运行得更好。最后,总会有一些顽固的用户坚持旧的方式。虽然我们一直在谈论“技术采用曲线”,但实际上在第三阶段有一个分叉。即使非常成功的项目也不能采用全新的技术。例如,在Slack,我们广泛采用gRPC作为我们的内部API技术。但是,我们不太可能构建一个全新的基于gRPC的memcached。memcached的自定义协议很好,并得到客户的大力支持。此异常并不意味着采用gRPC是失败的。对于其他情况,采用多种技术的成本(工程师的认知负担、运行遗留系统的负担)太高,因此我们需要完全采用新技术。对于这样的项目,我们需要有一个应对顽固分子的计划,不同的情况需要不同的策略。长期没有改动的系统可能需要使用代理,逐步迁移。如果因为新系统缺乏必要的功能而存在顽固分子,那么就需要对新系统进行增强,或者封装来模拟旧系统的功能。对于已经对旧系统产生情感依恋的情况,进行面对面的交流通常比高风险的公开辩论更有效。温柔一点,如果你的新系统足够成功,总有一天它也会变成旧系统。11.技术人员的期望作为Slack的工程师和工程主管,我们对彼此有什么期望?首先,我们要做一些探索性的工作。外面的世界很大,我们不得不偶尔抬头看看外面发生了什么。但是没有人可以探索一切,也没有人可以一直探索新事物。我们有外部承诺和内部路线图,这些事情仍然是重中之重。不过,我们还是要留出一些精力去探索新事物。当我们是其他团队技术产品的用户时,我们需要讲道理。提供底层技术支持的团队需要推动他们的系统向前发展,有时,这会给上层用户带来成本。如果此成本不合理,或者当它与您的团队需要的方向相反时,您需要以他们可以理解的方式与他们沟通。有时,我们需要避免依赖不满足我们需求的底层技术。在设定团队的技术方向时需要牢记这一点。然而,这并不意味着他们一定做错了,我们需要以成熟和专业的方式处理这种依赖分离。当我们试图推动其他人做出改变时,我们对试图理解和使用新系统的团队采取以用户为中心的方法。他们的快乐是你成功的唯一晴雨表,包括沟通、需求收集、反馈、迭代、有目的的培训和技能分享。如有疑问,请记住:您对技术采用的成功负责,从长远来看,决定它的是您产品的用户。