如何停止烦恼并开始生活





我们都喜欢故事。我们喜欢坐在火炉旁,谈论我们过去的胜利,战斗或我们的工作经历。



今天是这样的一天。即使您现在还不是火上浇油,但我们为您提供了一个故事。关于我们如何开始在Tarantool中进行存储的故事。



很久以前,在我们公司中存在着几个“整体”和一个“天花板”,这些整体正在缓慢而可靠地接近,这限制了我们公司的发展和发展。有一个明确的理解:有一天,我们将艰难地达到这个极限。



现在,我们被将一切(从设备到业务逻辑)划分为所有人的思想所主导。结果,例如,我们有两个DC在网络级别实际上是独立的。然后,一切都完全不同了。



如今,有大量工具和工具以CI / CD,K8S等形式进行更改。在“整体”时代,我们不需要那么多外来词。仅仅修复数据库中的“存储”就足够了。



但是时间越来越长,请求数量也随之增加,有时会触发RPS超出我们的能力范围。随着独联体国家的市场进入,第一个整体数据库服务器上的负载并没有下降到90%以下,RPS仍保持在2400的水平。这些不仅是小的选择器,而且还有大量的请求和大量的检查和JOIN可以几乎通过一半的数据位于大型IO的后台。



当黑色星期五的正式销售开始出现在舞台上-野莓开始成为俄罗斯首批销售之一时,情况变得完全悲痛。毕竟,这种日子的负担增加了两倍。

哦,这些“单身时代”!我确定您也遇到过类似的情况,但仍然无法理解这种情况可能会发生在您身上。



您能做什么-时尚是技术固有的。即使在5年前,我们也必须以.NET和MS SQL-server上现有站点的形式重新考虑这些mod之一,这些站点仔细地保留了站点本身的所有逻辑。他非常小心地进行切割,以至于切割出这样的整体是一种漫长而艰巨的乐趣。

一个小题外话。



在各种事件中,我说:“如果您没有看到整体,那么您就不会成长!” 我对您对此事的看法感兴趣,请在评论中写下。



雷声



让我们回到“篝火”。为了分配“单一”功能的负载,我们决定基于开源技术将系统划分为微服务。因为至少,它们的规模更便宜。而且,我们必须扩大规模(很多)的理解是100%。确实,当时已经证明它已进入邻国市场,注册数量以及订单数量开始增长。



在分析了第一个将整体程序留在微服务中的申请人之后,我们意识到其中有80%的人中有99%的人是从后台系统写入数据,而从前端系统中读取数据。首先,这关系到我们几个重要的子系统-用户数据和基于有关其他客户折扣和优惠券的信息来计算最终商品成本的系统。



缩进。现在令人难以置信,但是除了上述子系统之外,我们的整体产品中还包括产品目录,用户篮子,产品搜索系统,产品目录过滤系统和各种推荐系统。对于它们每个的操作,都有单独的一类窄化的系统,但是一次它们都生活在一个“小房子”中。



我们计划将有关客户的数据传输到分片系统。删除用于计算最终商品成本的功能需要在读取时具有良好的可伸缩性,因为它创建了最大的RPS负载,并且对于数据库而言是最难实现的(计算过程涉及很多数据)。



结果,我们有了一个可以与Tarantool一起使用的方案。



当时,为了运行微服务,选择了在虚拟机和硬件机上与多个数据中心一起工作的方案。如图所示,Tarantool复制选项同时应用于主-主模式和主-从模​​式。





建筑。选项1.用户服务



当前有24个分片,每个分片具有2个实例(每个DC一个),所有这些实例均处于master-master模式。



在数据库之上的是访问数据库副本的应用程序。应用程序通过我们的自定义库与Tarantool一起使用,该库实现了Tarantool Go驱动程序接口。她可以看到所有副本,并且可以与母版一起进行读写操作。实际上,它实现了副本集模型,该模型添加了用于选择副本,执行重试,断路器和速率限制的逻辑。



同时,可以配置在分片上下文中选择副本的策略。例如,roundrobin。





建筑。选项2.计算商品最终成本的服务



几个月前,大多数计算商品最终成本的请求都转到了一项新服务,该服务原则上不使用数据库,但不久前它是由Tarantool在后台进行100%处理的。



服务数据库是4个主数据库,同步器将数据收集到其中,每个复制主数据库将数据分发到只读副本。每个主站大约有15条这样的行。



在第一种和第二种方案中,如果一个DC不可用,则应用程序可以在第二种方案中接收数据。



应该注意的是,Tarantool中的复制在运行时非常灵活且可配置。在其他系统中,存在困难。例如,在PostgreSQL中更改max_wal_senders和max_replication_slots参数需要重新启动向导,这在某些情况下可能导致应用程序与DBMS之间断开连接。



寻求,你会发现!



为什么我们不像普通人那样做,却选择了一种非典型的方式?这取决于什么被认为是正常的。通常,许多人都从Mongo创建集群,并将其分布在三个地理分布的DC。



那时,我们已经在Redis上有两个项目。第一个是高速缓存,第二个是用于不太重要的数据的持久性存储。对他来说很难,部分是由于我们的错。有时,关键在于数量很大,而且该网站时常感到不舒服。我们在主从版本中使用了该系统。而且在许多情况下,母版发生故障,复制中断。



也就是说,Redis适用于无状态任务,而不是有状态任务。原则上,它可以解决大多数问题,但前提是这些是带有一对索引的键值解决方案。但是当时,Redis对持久性和复制感到非常难过。此外,还有关于演出的投诉。



考虑MySQL和PostgreSQL。但是第一个以某种方式并未扎根我们,第二个本身就是一个相当复杂的产品,因此不宜在其上构建简单的服务。

我们尝试了RIAK,Cassandra,甚至是图形数据库。所有这些都是非常合适的解决方案,不适合用于创建服务的通用工具的作用。



最终,我们选择了Tarantool。



当他使用1.6版时,我们与他联系。我们对键值共生和关系数据库的功能感兴趣。有二级索引,事务和空间,它们就像表一样,但并不简单,您可以在其中存储不同数量的列。但是,Tarantool的杀手级功能是结合了键值和事务性的二级索引。



反应迅速的俄语社区也扮演了角色,随时准备在聊天中提供帮助。我们积极地使用了它,并直接生活在聊天中。并且不要忘记没有明显的错误和干扰的持续性。如果您看一下我们使用Tarantool的历史,我们在复制方面会遇到很多麻烦和挫折,但是由于他的错,我们从未丢失任何数据!



实施开始艰难



当时,我们的主要开发堆栈是.NET,没有与Tarantool相连的连接器。我们立即开始在Go中做一些事情。 Lua也工作得很好。当时的主要问题是调试:在.NET中,所有功能都非常出色,此后,很难进入嵌入式Lua的世界,而除了日志之外,如果您没有调试,那将非常困难。此外,由于某种原因,复制会定期崩溃,因此我不得不深入研究Tarantool引擎的结构。聊天在较小程度上帮助了这一点-文档有时会查看代码。当时,文档还不错。



因此,在短短几个月内,我设法填补了难题,并在与Tarantool合作时获得了不错的成绩。我们在git中正式建立了参考开发,这有助于形成新的微服务。例如,当出现任务:创建另一个微服务时,开发人员查看了存储库中参考解决方案的源代码,并且花费了不到一周的时间来创建一个新的微服务。



这些是特殊的时期。按照惯例,可以在下表中向管理员询问:“给我一个虚拟机”。三十分钟后,您已经有车了。您自己进行了连接,安装了所有内容,并获得了访问量。



如今,它将不再那样工作:您需要结束监视,登录服务,通过测试涵盖功能,订购虚拟机或向Kuber供应等。总的来说,它会更好,尽管会更麻烦。



分而治之。那Lua呢?



这是一个严重的难题:有些团队无法通过大量Lua逻辑可靠地推出一项服务中的更改。这通常伴随着服务的不可操作性。



也就是说,开发人员正在准备某种更改。Tarantool开始迁移,副本仍然具有旧代码。一些DDL(通过其他方式到达)通过复制到达那里,而代码只是崩溃了,因为未将其考虑在内。结果,管理员的更新过程已安排在工作表A4上:停止复制,更新,启用复制,在此处关闭,在此处更新。恶梦!



结果,现在我们经常在Lua中什么也不做。只需使用iproto(用于与服务器通信的二进制协议)即可。也许这是开发人员缺乏的知识,但是从这个角度来看,系统很复杂。



我们并不总是盲目地遵循这种情况。今天我们没有黑白两色:要么一切都在Lua中,要么一切都在Go中。我们已经了解了如何将它们组合在一起,这样以后就不会遇到迁移问题。



Tarantool现在在哪里?

服务中使用Tarantool来计算商品的最终成本,同时考虑折扣优惠券(也称为“促销者”)。就像我之前说的那样,现在它已经退休了:它已经被具有预先计算价格的新目录服务所取代,但是六个月前,所有计算都在促销者中进行。以前,其逻辑的一半是用Lua编写的。两年前,通过该服务创建了一个存储,并将逻辑重写为Go,因为折扣的机制略有变化,并且该服务缺乏性能。



用户配置文件是最关键的服务之一。也就是说,所有Wildberries用户都存储在Tarantool中,其中大约有5000万用户,该系统由用户ID分片,分布在与Go服务连接的多个DC上。

根据RPS,“发起人”曾经是领导者,达到了6000个请求。一次,我们有50-60份。现在,RPS的领导者是用户配置文件,约有1.2万。该服务使用自定义分片,并按用户ID范围进行划分。该服务可为20台以上的计算机提供服务,但这太多了,我们计划减少分配的资源,因为4-5台计算机的容量就足够了。



会话服务是我们在vshard和Cartridge上的第一个服务。设置vshard和更新Cartridge需要我们做一些工作,但最终一切都完成了。



用于在网站和移动应用程序中显示不同横幅的服务是第一个直接在Tarantool上发布的服务。该服务值得注意的事实是它已经使用了6至7年,仍在使用中,并且从未重启过。我们使用了主-主复制。从来没有破坏任何东西。



有一个在仓库系统中使用Tarantool进行快速参考功能的示例,在某些情况下可以快速仔细检查信息。我们试图为此使用Redis,但是内存中的数据比Tarantool占用更多的空间。



等待名单服务,客户订阅,时尚故事和货架商品也可以与Tarantool一起使用。内存中的最后一个服务约为120 GB。这是以上最广泛的服务。



结论



二级索引结合了键值和事务属性,使得Tarantool非常适合微服务架构。但是,在Lua中使用很多逻辑将服务扩展到服务上时,我们遇到了困难-服务通常会停止工作。我们无法战胜这一点,随着时间的流逝,我们遇到了Lua和Go的不同组合:我们知道在哪里使用一种语言,在哪里使用另一种语言。



还有什么要阅读的话题






All Articles