“在隔离期间,负载增加了5倍,但我们已经做好了准备。” Lingualeo如何迁移到拥有2300万用户的PostgreSQL

图片



Lingualeo 项目已经有10年的历史了。来自俄罗斯,土耳其,西班牙和拉丁美洲的2300万人正在使用我们的服务学习英语。



LinguaLeo创建于2000年代末和10年代初,当时使用了先进的技术和方法。但是时间过去了,他们变得非常落伍。因此,我们认为是时候更新系统了。



我们请后端开发负责人Oleg Pravdin谈谈他和他的团队在支持主要产品的同时如何组装基于PostgreSQL的新模块化服务结构,将业务逻辑转移到数据库以及如何迁移数百万用户。



成熟的产品问题



“我于2018年8月来到Lingualeo,负责后端开发。当时,由8个开发人员和2个管理员组成的团队进行了支持,他们维护着100万行代码的整体,其中大部分都是PHP。实施一个小小的新功能花了2个月的时间。每10,000个活跃用户的基础结构成本每年超过1,000美元。



这怎么发生的?事实是,在过去的十年中,几个开发团队对该项目进行了更改。像我一样,新人们来了,他们以自己的方式添加了新的模块和功能。团队发生了变化,新来者并不总是了解系统的旧部分是如何工作的,结果,Lingualeo代码逐渐变成了黑匣子:后端的逻辑不透明,前端不堪重负,拐杖过多,文档中存在大量空白。



我们总共有20名开发人员,但是开发该产品是不可能的:如果添加了某些内容,则会出现意想不到的问题。团队花了2-3个星期来解决所有问题。开发人员一直在维护2013年以来的代码,并且没有资源来更新功能。



这些是十年前开发采用技术编写的成熟IT产品的众多公司所面临的挑战。趋势在变化,但是由于旧体系结构,并非所有新项目都可以使用。



该产品不断发展壮大,但功能却泛滥成灾,但是他们没有时间详细记录它们。这些问题可以通过不同的方式解决,但我们是这样决定的:您需要从头开始构建新系统并保持最大的产品逻辑,以使Lingualeo的用户体验保持不变。



步骤1.组装新架构的原型



我们必须弄清楚如何更新服务的技术组件以及如何使用现代技术重建Lingualeo。我建议管理层完全改变后端的理念:将业务逻辑转移到数据库,并用PostgreSQL替换MySQL数据库。



我从纸上的原型开始:我绘制了一个新架构,解释了如何提高性能以及准备所需的资源。保护该项目很困难,因为手头没有明确的成功案例:没有人写过如何在不停止业务的情况下向2000万用户迁移服务。但是Lingualeo决定冒险并批准了变更计划。



迁移前架构图



图片



PHP, , MySQL . JSON







图片



SQL PostgreSQL, JSON. -, , JSON



2.



当我们与开发人员共享计划时,很明显团队尚未准备好进行更改。大多数人都离开了公司:只有那些最近才来的人留下了。为了进行迁移,我们决定重新组建开发团队。



我们一直在寻找雄心勃勃的,为变革准备的,专业且负责任的。我们试图不仅关注代码的质量,而且关注软件的技巧。我们正在重建服务的体系结构,因此我们需要不怕复杂项目并且准备解决他们以前从未遇到过的问题的人员。



例如,有人偶然发现了像我这样的人:我在飞机上遇到了Lingualeo Vladimir Sirotinsky的首席执行官。弗拉基米尔(Vladimir)与另一家初创公司进行了磋商,会见了未来的前端领导人。但是我们从市场上招募了大多数新开发人员。为了填补8个职位空缺,我们研究了1,118份申请并进行了124次面试:



图片

Lingualeo的新开发人员职位候选人漏斗。



步骤3.简化组织结构



我们有三个开发领域:Web,后端和移动应用程序,我们还有一个测试人员部门。在短时间内很难找到一个同时了解所有行业的人。因此,我们决定放弃技术总监,并使新团队的组织结构尽可能平坦。公司仅剩一个管理级别-每个方向只有一位领导者。



我们定期召开会议并直接进行沟通,因此发展变得更加可预测,时间框架也缩短了。 CTO可能会做出不合理的决定,例如团队之间错误分配职责。在牵头沟通而无需额外管理者的系统中,不合理决策的可能性降低了:我们总是可以在个人对话中讨论任何问题。



例如,如果我理解在数据库的新结构中而不是在前端的新结构中实现功能会更合乎逻辑,那么我会写信给聊天并与前端负责人讨论这个想法。无需与CTO预约或准备演示文稿来支持您的想法。



图片



变更前后的组织结构:我们取消了开发中的CTO,并简化了产品部门的结构。如今,产品设计师无需与两个级别的经理交谈就可以将想法摆在最前面。



步骤4.将业务逻辑转移到数据库



以前,Lingualeo的业务逻辑位于前台和应用程序中。产品功能由非旨在处理数据的系统处理,例如JavaScript或PHP代码。因此,我们已将Lingualeo业务逻辑移植到PostgreSQL数据库。



丛林



Lingualeo服务的四个主要部分之一是Jungle。这是一组外文材料,包括文本,音频和视频,您可以在其中识别任何单词的翻译。也就是说,用户以英语学习真实的内容,如果不清楚,可以单击文本或字幕中的单词以观看视频,并查看翻译。



丛林中的文本丛林中的



图片



视频



图片



为了使单击时的单词翻译功能起作用,文本必须分为单词,表达和短语。然后-参考字典,并在文本上方的新窗口中向用户显示翻译。将文本分解以进行翻译是相当困难的:存在固定的表达和短语动词,将其分为两个词是没有意义的。例如,起飞和起飞是内容的不同单位,尽管它们包含相同的词。



该函数的所有逻辑,以及异常和复杂的文本划分规则,以前都是用JavaScript编写的。该功能非常麻烦,翻译可能需要很长时间。



我们已经在数据库中实现了此功能。后台将现成的JSON发送到前端,其中的文本已被拆分为单词和表达式。数据库中的每个单词和表达式都分配有一个ID,这使查找翻译变得容易。JSON还考虑了用户在词典中有哪些单词,哪些还没有。在最前面,剩下的就是显示信息并突出显示带有某些符号的单词。



辞典



我们对“字典” 部分进行了相同的操作:所有工作现在都在数据库中进行。我们的用户词典中包含超过100,000个单词和表达式。在字典中,您需要提供方便的搜索,将单词分为几组,并为用户提供广泛的过滤器。



以前,词典的逻辑位于前端或PHP层中,但现在系统在前端和后端之间具有完整的API。您可以将具有大量参数的一个请求发送到数据库,然后将有一个现成的JSON从那里发送:



图片



字典过滤器:按单词搜索,按训练类型选择单词,按单词和短语选择单词,按学过的单词和新单词过滤



培训班



将业务逻辑转移到数据库可以大大减少代码量并加速服务。例如,“课程”页面的后端代码在迁移后已更改注册用户可以看到它,并且系统根据十个标准选择课程。以前,这样的页面形成了600毫秒,并向数据库发送了12个请求,现在只有一个:



图片

图片



步骤5.考虑发布后的用户反馈



开发大约花了六个月的时间:我们于2018年底开始更新,发布于2019年5月进行。大多数用户认为该服务开始变得更快。以前,Lingualeo可以同时培训不超过2,000人,而不会损失速度,但是现在该系统可以承受超过100,000个用户的高峰。



有些人还注意到负面后果。使用黑匣子迁移时,很难确保100%的数据的安全性,因此有些丢失了词典中的单词,有些错误地显示了课程进度。



逐步地,我和我的团队解决了所有问题。更改的主要结果是,现在我们不是在使用黑匣子,而是在使用简单透明的系统,因此更容易确定反馈。



Lingualeo



到2020年4月,在自我隔离期间,Lingualeo的工作量是去年同期的五倍。这没有引起问题:服务的速度没有下降,用户没有注意到任何东西。我敢肯定,如果我们不更新系统,该服务将完全失败。



该产品不仅为用户带来了更快的速度,而且使用起来也变得更加容易:现在,团队可以更轻松地引入和测试新功能。我们整理了文档,代码已缩小了大约40倍,因此新开发人员可以轻松地弄清楚该服务的工作方式。



该产品已经变得更便宜,因此您需要为它租用更少的计算能力。 Lingualeo中每位活跃用户的成本已降低了50倍以上,尽管更新后活跃用户的数量已增加了一倍。



最后,产品更安全。以前,当所有业务逻辑都在PHP层中时,从那里通过不同的功能向数据库发送请求。对SQL查询开放的数据库是一个问题:您可以进行SQL注入并强制其执行危险的代码,例如删除数据。现在,没有一个SQL查询来自外部,因为我们已经将所有逻辑移到了内部。”



我们希望继续定期发布有关更新的Lingualeo中开发工作方式的博客。在评论中写下首先要讨论的内容:我们的团队已经改变,管理结构和技术也已改变。我们很乐意回答您的所有问题。



All Articles