如何将两个平台结合为一个平台而不冒犯用户。Yandex.Kew开发人员经验



去年,TheQuestion服务加入了Yandex。那时,已经有类似的问答服务-Yandex.Znatoki。鉴赏家听众很多,有很多有趣的问题,但是没有足够的专家可以为这些问题提供高质量的答案。相反,该问题拥有强大的专家群体,但缺少有趣的问题。合理的步骤是将两个服务组合在一起,以便从每个服务中获得最大收益。但是,如果每种服务都有自己的技术基础,内容和用户,该怎么办?

今天,我将从技术的角度谈谈我们的团队如何解决此问题。您会发现我们考虑过哪些选项,最后选择了哪种。我将向您介绍“交换API”,数据库迁移,池配置文件和后端测试。然而-在搬家之夜,没有犯错的权利。您将看到我们不必感到无聊。

将两个服务合并为一个的任务并不新鲜,但这并没有使它变得更容易。历史知道许多成功的(但并非如此)整合示例,但是不幸的是,没有“银弹”,也没有明确的指示“做到这一点,一切都会成功”。一切都很大程度上取决于要合并的服务的具体情况以及期望的结果。

在我们的案例中,目标是这样的:在每个站点上编写的所有内容都可以在统一服务上使用,并且其作者可以管理它。

那么,如何将这两个看上去很相似但本质上却有很大不同的问答服务组合在一起?将内容和用户从一项服务转移到另一项服务与从旧公寓转移到新公寓非常相似。

仅在我们的情况下,用户才能同时住在两间公寓(Connoisseurs和TheQuestion)中,并且您需要小心地将其运送到第三间。您需要将所有家具,植物,猫甚至墙纸移动到新公寓(即问题,答案,评论,喜欢),然后邀请他移动。

这个怎么做?立刻想到了几种选择。

选项1.非常糟糕,
我们只使用其中一项服务,将所有内容转移到另一项服务(尽管即使这不再容易),然后关闭原始服务。

从第一项服务的用户的角度来看,此选项非常糟糕。我们刚刚拆除了他的老房子,并强迫他搬到新房子。任何人都不会喜欢这种态度,他可以不走动,而只是日落。对我们而言,主要价值在于用户社区,因此我们不打算冒犯任何人。并大胆地切换到其他选项。

选项2。坏
让我们不要更改任何服务,而是启动一个新的,集成的服务,然后我们将定期将其他两个服务的内容添加到其中(例如,每天一次)。

在这种情况下,我们似乎并没有使用户变得更糟,但我们也没有做得更好。他的旧公寓保持不变,但没有必要搬到新公寓。所有邻居也都住在一栋老房子里,刚买的花一天后才会运到新公寓里。这样的统一服务没有机会成为新家。

选项3.很好,但是很困难
不要关闭任何服务,我们将立即复制集成服务上的内容和配置文件,随着时间的流逝,人们将不断迁移。

用户的所有邻居(甚至是猫)都同时在旧房子和新房子中居住。您刚买的花立即出现在新公寓里。确实需要什么!从用户的角度来看,此选项最为舒适。因此,我们选择了它。

开始行动


我们最终所做的可以用几句话来描述。我们完全重复了基于Connoisseurs后端的整个TheQuestion API后端,从而获得了一个可以同时处理两个(甚至三个)站点的后端。同时,TheQuestion前端几乎保持不变,这意味着从用户的角度来看,网站本身几乎没有变化。该项目已收到内部名称“交换API”。但是首先是第一件事。

我们在入口处拥有两个完全独立的站点。鉴赏家生活在Yandex的内部云层中。鉴赏家后端是用Python编写的。TheQuestion生活在Microsoft Azure的云中,TheQuestion后端是用Go编写的。服务在数据库中具有完全不同的数据存储方案。此外,TheQuestion有两个移动应用程序(适用于Android和iOS),也需要支持。通常,敌人不想联合这样的动物园。



阶段0。进入Yandex云


严格来说,“插件API”无需执行此步骤,但可以大大简化后续步骤。在这一阶段,我们完全放弃了外部存储和设施。TheQuestion开始使用Yandex DNS服务器。rentme服务已移至Yandex.Cloud。该数据库已转移到Yandex托管数据库。在迁移过程中,我们还能够找到并修复TheQuestion中的多个错误,例如,2015代码中与Redis的未关闭连接。作为奖励,我们还为TheQuestion获得了更多功能。

阶段1.数据迁移


无论您要组合服务的哪个选项,无论如何我们都必须组合数据。对于单个数据库,他们决定采用PostgreSQL-该DBMS已在Experts和TheQuestion中使用。为了不使该项目复杂化,他们没有开始为集成服务创建第三个基础,而是仅仅使用了Znatokov数据库并对其进行了扩展,以便可以接受所有TheQuestion数据。这是第一个主要的技术挑战。

TheQuestion数据库中每个表中的每个条目都必须转换并放入专家数据库。然后-从一个和另一个基础关联每个列。许多字段必须从一种格式转换为另一种格式。因此,一个单独的大子任务是将文本存储格式(问题或答案存储的实际格式)从QML(TheQuestion)转换为Markdown(Experts)。

我们建立了一个定期的(一天几次)将新数据从一个数据库传输到另一个数据库的过程,但是同时确保直到下一个阶段完成,TheQuestion的数据都不会显示在任何地方。因为“一天几次”远未“立即”承诺,并且数据可能与TheQuestion上的相同数据处于不一致状态,这会误导用户。那么,如果后端尚未准备好,为什么还要从数据迁移开始呢?

首先,通过这种方式我们稳定了过程。其次,他们减少了将来需要传输的新数据量,这一点很重要,因为所有导入的内容都必须通过标记来保证质量,不适当的内容,垃圾邮件,欺诈。



阶段2。“交换API”


因此,我们解决了第一个问题-我们学会了从TheQuestion数据库中获取内容,甚至根据需要显示内容。现在有必要使这些内容立即进入集成数据库,而不是每天几次。

为此,必须使用所有必要的逻辑重写整个TheQuestion后端。严格地说,项目名称“交换API”不能完全反映其实质。将其称为“交换后端”会更正确。事实是,除了直接实施TheQuestion前端功能所需的所有“笔”之外,还必须实现其他可能性。我们面临几个主要任务。

授权书Yandex具有集中的用户授权系统-Yandex.Passport。当然,鉴赏家也使用了护照。要登录,您必须在Yandex中拥有一个帐户。那就是问题所在。并非所有TheQuestion用户都通过Yandex登录到该站点(尽管有这样的机会)。许多用户根本没有Yandex登录,而是通过社交网络(VKontakte,Facebook ...)访问。自然,我们在移动时必须保留此功能。因此,我们实施了“非护照”授权。

网站搜索。TheQuestion对问题,答案,用户和主题进行了搜索。为了进行搜索,使用了第三方Sphinx解决方案。显然,如果我们在谈论单个服务,那么搜索应该是相同的,也就是说,它不能同时在两个系统上工作。因此,Sphinx被抛弃,取而代之的是内部搜索引擎,该引擎支持所有TheQuestion内容的必要功能和索引。

Zen和Turbo中的页面发货。在加入时,TheQuestion已经使用了Yandex技术。支持Turbo页面,有趣的内容落入Zen feed中。所有这些还必须在“替换API”中得到支持。

服务和应用程序中的通知,邮件列表。与通知用户有关的一切:订阅,具有有趣内容的新闻通讯,喜欢和评论推送等等。所有这些都必须仔细转移,不要忘记。

现场管理系统。本段涉及与服务的内部管理有关的所有内容:审核,分析等。

统一的用户评分系统。这项任务不是技术性的,而是合乎逻辑的。正式而言,没有必要为“交换API”开发统一的评分系统,但将来的集成服务仍需要此系统。在这两个站点上,都对用户对所创建内容的数量和质量进行了评估。等级的详细信息没有透露,但是您回答问题的频率越高越好,您的等级就越高。两种服务的评级原则相同,但公式本身和因素却大不相同。不仅需要正确诚实地比较Znatokov和TheQuestion的用户,而且还必须学习为那些同时撰写两项服务的专家考虑一个单一的评分。

并重写所有API。不管喜欢与否,这项任务是最重要和最困难的。服务的许多过程都是相似的,因此我们从鉴赏家那里获取它们,并且没有从头开始。但是,还有很多新事物,例如用户的直线或答案草案。结果,我们在“交换API”中重写了100多个“笔”,并实现了50多个REST资源。

在实现了上述所有功能之后,就可以开始移动了。但是在我们做一个把戏之前。

显然,在生产环境中切换和推出“交换API”之前,必须对其进行很好的测试。首先,有必要对其进行功能测试,即直接在新API上检查整个网站的性能。第二,压力很大。我们希望100%确保我们的设计不会“承受”负载。自然,我们定期进行“负载触发”,这表明我们具有良好的性能。但就服务性能而言,最好安全使用它。任何甚至最佳的综合负载测试都与生产负载有所不同。因此,我们决定在切换API之前,要填补我们展位上的生产负荷。

为此,在TheQuestion前端,我们一次将所有GET请求(意味着数据请求,而不是修改)复制到两个API:“旧API” TheQuestion(当时是主要API)和次要“交换API”。同时,前端不等待较小的API响应并且不处理错误,但是通过这种方式,我们能够在真实用户上测试后端。



第三阶段。然后我们想起了应用程序


当然,我们一直都没有想起它们,但是遇到了一个问题。那些使用移动应用程序的人知道,与移动应用程序相比,麻烦不仅仅在于网站。这主要是由于新版本的发行。

首先,您需要使用App Store和Google Play的外部服务,并等待新版本通过验证(有时验证可能会花费大量时间)。其次,即使您的应用程序已经通过测试并出现在商店中,这也不意味着用户会进行更新。

对于网站的前端,开发人员自己控制何时发布新版本,并且他们确定在此之后,所有用户都将收到该网站的更新版本。对于应用程序,没有这样的保证。为了获得这种保证,他们经常使用应用程序的“强制更新”。很少有人喜欢这种方法,当然,如果可能的话,总是会保持应用程序和后端之间的向后兼容性。因此,我们采取了在后端进行精确更改而在应用程序中对前端进行最小更改的方法。但是,正如经常发生的那样,该计划面临着严峻的现实。

在前端进行一些更改要比在后端进行更改容易得多,因此,在开发“插件API”的过程中,前端稍有改动,但有所变化。特别是,旧的TheQuestion数据库使用数字64位ID。鉴赏家数据库以及相应的组合数据库和TheQuestion的新API使用字符串128位ID。通常,对于用Node.js编写的前端,这种区别并不明显。但是对于强类型的应用程序,这是致命的。我们失去了向后兼容性,并且较旧的应用程序无法使用“插件API”。

在某个时候,甚至有一个名为“用于插件API的插件API”的项目,其实质是在新后端和应用程序之间编写一小层,以将所有数据转换为旧格式。但是,我们很快放弃了这个想法。这层将成为非常严格的“拐杖”,将来肯定会给我们带来很多问题。例如,您不能仅将128位ID转换为64位ID。我将不得不转换信息而损失信息,因此可能会因ID发生冲突,或者维护一个中间表,该表具有新旧ID的对应关系(适用于数据库的所有元素)。两者兼而有之-并非最佳的架构解决方案。

除了ID之外,还有许多其他更改,在前端和应用程序端也更容易支持。结果,我们决定在应用程序中进行更改,并且仍然使用强制更新。在很短的时间内,我们开发了与“交换API”兼容的应用程序的新版本,因为从前端开始并没有太多更改,而且它们并不是很严重。发送到App Store和Google Play,已成功审核并开始等待。

X阶段。走吧!


因此,所有代码均已编写。具有“替换API”的支架经过测试和烧制。该应用程序的新版本已在商店中进行了测试,并准备发布。现在,所有这些都必须推广到生产中。

由于将新数据从旧数据库复制到新数据库的过程是异步的,并且需要花费一些时间,因此您无法在工作站点上切换后端(及其下的数据库)。这可能会导致丢失或用户数据不一致。因此,我们选择了一个日期,警告用户,并准备了一个标牌“正在进行中的技术工作”。

然后是小时,或者更确切地说是晚上X。推出计划如下所示:

  1. 在TheQuestion网站上,我们挂了一个存根“工作正在进行中”。
  2. 我们将应用程序转移到只读模式。用户可以从旧数据库中读取内容,但不能创建新数据库。
  3. TheQuestion Readonly. : . , , .
  4. . , .
  5. .
  6. , , API.
  7. API . — , API .
  8. , , .
  9. « », API.
  10. .

好吧,这看起来并不那么可怕。实际上,一切都进行得很顺利。在我们遇到的惊喜中,在App Store中发布该应用程序可能只是太长时间了(该应用程序已经过预先检查,只是出现在商店中)。最后,花了几个小时,这就是为什么整个操作有些延迟的原因。

另外,在切换过程中,还有一个关键功能,使许多事情复杂化,并增加了责任感。事实是切换过程无法逆转。

尽管已经为我们设置了将数据从旧的TheQuestion数据库复制和转换到新的集成数据库的过程并进行了调试,但是没有反向复制过程(从新数据库到旧数据库)。这意味着,一旦我们在“交换API”上打开网站并启动用户访问量,所有新创建的问题,答案,评论和喜欢的对象就不再容易进入旧的TheQuestion数据库。例如,如果在打开后出现问题,则单个数据库无法应对负载,那么将不可能快速回滚所有内容。

实际上,我当然夸大了。无论如何,我们都不会丢失用户数据。我们有一个计划B和一种将数据从新数据库手动备份到旧数据库的方法。但是仍然需要一些时间,并且回滚对于用户而言不会十分痛苦。

幸运的是,计划A奏效了,不需要回滚任何事情。



最后阶段


因此,更改了后端,合并了数据库,并没有忘记移动应用程序。对于用户而言,什么都没有改变,因为原本应该合并两个站点数据的Yandex.Ku网站当时尚未启动。对于它的发布,我们需要解决另一个问题。

从一开始,我就写过,我们不仅必须将来自两个服务的问题和答案合并到一个新的用户中,而且还必须合并用户。用户不仅应该能够在Kew上看到其内容,而且还可以在Kew上对其进行管理。从技术上讲,合并数据和转让管理权并不困难。确保将权利转让给应转让权利的人要困难得多。

从Znatokov迁移到Kew时,一切都很简单:在两种情况下,都使用相同的Yandex帐户。但是TheQuestion有自己的帐户,无法在Kew上授权。幸运的是,我们事先考虑了这一点。在执行上述操作之前很久,我们就使TheQuestion用户能够链接其Yandex配置文件。到服务进行物理合并时,超过90%的活动用户已经做到了这一点。这使我们能够毫不费力地开始内容和用户的迁移。


迁移时,我们想保存每个用户,因此我们有意识地选择了最耗时,最冒险的平台组合方案。我们创建了一个统一的技术基础,学习了如何即时传输内容和配置文件。他们保留了旧服务的功能,推出了新服务并解释了其优势,而不是意外关闭和强制重新定位。去年,



我们推出了Yandex.Kew现在,TheQuestion和Znatokov的活跃作者中有80%以上是自愿搬到新家的。

All Articles