当前位置: 首页 > 知识库问答 >
问题:

mongock会正确使用kubernetes副本吗?

车诚
2023-03-14

Mongock看起来很有希望。我们希望在具有多个并行运行的副本的kubernetes服务中使用它。

我们希望在部署我们的服务时,第一个副本将获得mongockLock,并且它的所有ChangeLogs/ChangeSets将在其他副本尝试运行它们之前完成。

我们在kubernetes环境中运行一个mongodb实例,我们希望mongock变更日志/变更集只执行一次。

mongockLock是否保证只有一个副本将运行ChangeLogs/ChangeSets到完成?

还是我需要启用事务(或其他一些配置)?

共有2个答案

左翰海
2023-03-14

只是为了跟进。。。Mongock的锁定机制可以很好地处理副本。为了解决“长时间运行的脚本”问题,我们将从Kubernetes运行Mongock脚本。K8s将等待初始化容器完成,然后启动pod的主服务容器。对于事务,我们将遵循上面的建议,使脚本幂等。

裴永年
2023-03-14

我将首先提供简短的答案,然后是长答案。我建议你也读一读长的,以便正确理解它。

默认情况下,Mongock保证变更日志/变更集一次只能由一个pod运行。锁的主人。

幕后真正发生的事情(如果没有进行其他配置)是,当一个pod获取锁时,其他pod也会尝试获取它,但他们不能,因此他们被迫等待一段时间(可配置,但默认为4分钟),等待次数与配置锁的次数相同(默认为3次)。在此之后,如果我无法获取它,并且仍有待应用的更改,Mongock将抛出MongockException,这应该意味着JVM启动失败(默认情况下在Spring会发生这种情况)。

这在Kubernetes中很好,因为它可以确保重启吊舱。所以现在,假设POD再次启动并且已经应用了变更日志/变更集,POD启动成功,因为它们甚至不需要获取锁,因为没有待应用的更改。

现在,假设锁和互斥是明确的,我想指出一个需要通过变更日志/变更集设计来缓解的潜在问题。

如果您在Kubernetes这样的环境中,具有pod初始化时间,则此问题适用,您的迁移需要比该初始化时间更长的时间,并且在pod准备就绪/运行正常之前执行Mongock进程(这是它的一个条件)。最后一个条件非常理想,因为它可以确保应用程序使用正确的数据版本运行。

在这种情况下,想象一下Pod启动了Mongock进程。在库伯内特斯初始化时间之后,该进程仍然没有完成,但是库伯内特斯突然停止了JVM。这意味着一些change eSet被成功执行,一些其他的甚至没有启动(没有问题,它们将在下一次尝试中处理),但是一个change eSet被部分执行并标记为未完成。这是潜在的问题。下一次Mongock运行时,它会看到change eSet处于挂起状态,它会从头开始执行它。如果您没有相应地设计变更日志/变更集,您可能会遇到一些意想不到的结果,因为该变更集涵盖的数据过程的某些部分已经发生,并且还会再次发生。

这需要某种程度的缓解。要么借助于诸如事务之类的机制,要么采用考虑到这一点的变更日志/变更集设计,要么两者兼而有之。

Mongock目前提供“要么全部,要么什么都不提供”的事务,但它并没有真正起到多大作用,因为它会从头开始每次重试,并且可能会以无限循环结束。下一个版本5将提供每个变更日志和变更集的事务,再加上良好的组织,这是正确的解决方案。

同时,可以通过遵循此设计建议来解决此问题。

 类似资料:
  • 我是Spring的新手。在@Bean方法中注入Bean的这两种方法有什么区别?我应该使用哪个,为什么? 而且

  • 我使用以下参数运行java应用程序: null 按照我的理解,我需要查看参数。但在本例中,它大大超过。在本例中,预计将发生。我做错了什么?如何为容器限制java应用程序的内存?我是否错误地查看了使用的进程内存? 我想最小化使用的RAM。OS-CentOS 7

  • 未捕获的mysqli_sql_exception:您的SQL语法中有一个错误;请检查与您的MariaDB服务器版本相对应的手册,以获得在“near”中使用的正确语法?在第2行按'score'desc'排序。.. 我已经研究了在‘?’附近使用的正确语法。但我认为我的问题不同。

  • 我有如下Spring Boot配置: 我的理解是,只有以app或rest开头的请求才会被我的自定义过滤器截获,但结果是请求到根(

  • 如何正确执行collect以获取作为键并将Ethernet对象作为每个流元素的值?

  • 我在使用org.apache.commons.io.FileUtils从img目录删除文件时遇到问题。我正在使用以下代码: 实际上,该代码是用来替换img目录中已有的图像文件。我需要删除所有以前存在的文件,名称是n.*,与新文件,例如n.png。如果我试图删除图像文件,我会得到变量成功的false值,并且文件不会被删除。但不包括图像文件,例如*.abc;*.ACD;*.ACDC等被成功删除。这个问