我们如何改进我们的x射线数据库同步过程

Batel Zohar |开发者倡导者和Noam Shemesh |软件架构师

您可能听说过液态软件的概念,作为DevOps和开发人员,我们希望能够超级快速地配置和开发所有东西。

因此,当像Xray的DB同步这样“简单”的过程出现时,我们需要跳出常规思维,找到有趣和创新的解决方案,将所需时间从16小时减少到2小时。

视频记录

大家好,欢迎来到沼泽。今天我们将讨论出色的DB同步过程改进。我们将解释什么是x射线,x射线中的DB同步过程是什么以及我们需要改进什么。和我一起工作的是Batel Zohar,她在JFrog工作了四年,她是一名开发者倡导者,在此之前她在支持团队工作。这意味着她与客户和开发人员一起工作,所以她熟悉客户的环境和代码本身。诺姆·谢梅什是我今天的好搭档,他也在JFrog工作了四年。

他是CTO团队的一员,从前端网站到ED方面,他都有惊人的知识。他还写了一些代码。谢谢大家。诺姆,谢谢你巴特尔,我们开始吧。首先,什么是JFrog XRay?

XRay是一个用于开发人员的工具,它为您提供有关组织内的漏洞、遵从性和许可的信息。工件存储在Artifactory中,它们是JFrog平台的一部分,因此我们有完整的解决方案来保护我们的二进制文件和工件。那么我们如何安装JFrog XRay呢?JFrog XRay支持不同的安装类型,如RPM, Docker, Kubernetes,我们可能会在未来添加更多。我们还有两个不同版本的本地和SaaS解决方案,它们以不同的方式处理DB同步过程。记住这一点,我们将在下一张幻灯片中讨论这一点以及它们的区别。那么什么是XRay DBC呢?

为了扫描漏洞和验证许可证合规性,XRay使用了一个包含许多公共组件漏洞和许可证的大数据库。当第一次安装XRay时,在下载中有一个初始DBC,它存储了所有要到XRay的公共数据,这是一种公共信息的中心知识。是的,今天数据库的压缩站点大约有6-7千兆字节,我们的数据分析师正在非常非常努力地寻找越来越多的漏洞和组件,以确保我们有更多的数据可以找到,以防我们有任何安全漏洞,所以它每天都在增长。

是的,在我们取出6gb的压缩数据之后我们需要打开它来提取它我们找到了45gb的数据我们需要插入到数据库中。这些数据以100mb的压缩文件的形式进入到每个安装中。每个zip文件都有JSON文件,数目不是恒定的,我们一会儿会看到原因。

当对象是组件或漏洞时,每个JSON文件有2000个对象。对象的大小不是固定的这就是JSON文件大小不同的原因也不是固定的,压缩文件可以是一个JSON文件也可以是150个JSON文件两种情况都有。在我们做任何改进之前,最低要求是需要15个小时来处理完整的数据库同步过程,这是很多,很多时间,我们不能让客户这么做。这需要很多时间来消化。所以我们试着思考如何解决这个问题,我们有几个解决方案,像下面这样:第一个解决方案是将已经存在的数据库作为数据库分发给[听不清],而不是在用户端免费创建它。

是的,但如果我们这样做,我们可能需要不同版本的数据集哪个数据集将与我们支持的繁荣版本相匹配有很多版本,因为我们不…我们只是告诉客户,他们需要安装,例如,9.6版本的繁荣和进一步的,因此,这意味着,对于每个版本的繁荣,我们需要有一个不同的数据中心,这可能是很多,因为我们不知道是什么版本的客户。

当然,我们可以将版本限制为PR支持,但我们不想这么做,至少一开始不想。是的,而且它还会使装置更大,对吗?它会更重,而且……

是的,安装将会更大,因为我们不知道它将是什么版本,我们可能需要在此之后确定版本,并准备好二进制文件供客户下载,就像DB同步一样,但我们仍然需要添加许多映像。

好吧,也许我们可以使用一个在线服务器来获取组件、漏洞和DB同步所需的所有信息?是的,这是一个很好的解决方案。实际上,这就是我们在云端所做的。这是一个很好的解决方案。但对于内部客户来说,这将是棘手的,因为我们需要非常低的延迟的信息在公共组件和公众的漏洞,如果我们需要低延迟,这意味着我们需要服务器都提供相同的信息,实际上建造SCDN为了只是提供这虽然有其他选择,但这并不意味着我们没有我们不会这样,但我们要尽可能避免这种情况,我们可以发现别的东西,所以我们最后避免了这个。

好吧,所以也许一个[听不清]数据库用于那些使用较少的组件而不是分发常见组件,一种混合。没错,这是一种中间地带因为我们可以取公约数组件并将它们放在本地,然后只有1g的数据或类似的东西,所有其他更奇特的组件都可以根据请求下载。所以我们可以这样走。但如果我们这样做,就意味着支持离线本地安装将变得更加困难,这也是我们支持的,因为我们不能告诉客户,只需安装XRay,然后用另一个命令下载文件,然后用另一个命令将数据安装到数据库中。和你可以在两个不同的服务器这意味着你没有连接到互联网,我们可以说,好吧,我们保持相同的过程,我们已经为这种类型的客户现在有15个小时的时间来处理数据库同步,但我们也发现一种更好的方式,因为我们找到了一种方法来解决客户的问题,在做离线同步,现在我们要讨论这个。

最终,我们选择了增量,我们将在这个演示中看到我们如何改进数据库同步,所以让我们来谈谈它。所以我们开始研究第一个叫做Pprof的工具。Pprof是由Google开发的一个CPU执行器,用于分析多线程应用程序。Pprof具有在图形上生成问题可视化的能力。

结果表明,X-Ray在数据库操作上花费了大量时间。这是Pprof图的一个例子,它是什么样子的。是的,这是一个很好的例子,因为我们经常使用它来发现数据库同步过程中的问题。

这是火焰图,你可能可以在其他语言中找到它,你只需要找到合适的工具,还有Pprof还有其他的特性,所以一定要去看看。你可以在这里看到,例如,两个ad用户问题对数据库进行了三次调用。

一,二,三。正因为如此,我们不确定这就是我们想要的,因为也许我们需要对数据库进行三次调用但也许我们只是想添加一个用户问题,为什么要进行这么多次调用呢?所以我们需要检查一下。

我们不知道那里是否有问题,但我们需要检查一下。你还可以在右边看到,对于添加许可证问题,我们有更多的电话,我们有8或9个电话来自另一个广告。可能有一个问题,我们想检查一下。我们是这样开始的,我们看到有一些东西做了很多工作,在我们发现它之后,我们去了电话,并试图思考是否所有的电话都是必要的。

当然,这是一个例子,我们发现的一件事是我们在数据库中插入了很多单行。虽然我们可以对数据库进行许多批处理插入。例如,如果我们有组件,我们可以插入一个组件,但我们不能合并很多组件,并将它们插入到一个批次中。

为了做到这一点,我们添加了一个通道,它从很多地方获取很多组件,而它们具有相似的上下文,这意味着它不是真正的全局上下文,因为我们有几个通道获取信息并并行处理,例如,我们可以为一个文件创建一个通道,为另一个文件创建另一个通道。我们取这个通道,并在半秒后或100个条目准备插入数据库时耗尽它这工作得很好,因为它确保了数据仍然有效,因为我们经常这样做。同时,一次推送很多数据,这样我们就减少了到数据库的往返。所以这是第一个改进,但我们不能在没有做一件非常重要的事情的情况下进行改进,我们必须分离数据库同步的类型。

我们开始之前我们之前开始改进过程是一个数据库同步,我们没有分离每日DB数据库同步和初始同步因此意味着我们做了很多的改进数据数据库同步,因为这是我们每天都做,我们没有那么多时间投资在最初的数据库同步,因为它甚至没有分离,我们没有我们做不到具体的改进,只有最初的数据库同步首先是分开。然后我们可以做第一个改进,即分离插入,现在我们可以做另一个改进,即乐观插入,而不是仅仅选择和检查我们是否需要安装或更新一个组件,我们可以尝试插入,如果我们有问题,我们将回到更新。

但是我们也可以在每日数据库同步中这样做但是在每日数据库同步中,我们更新的可能性要高得多,这可能需要更多的时间。我们这样做是因为这会花更多时间因为我们需要插入,然后选择,然后更新而不仅仅是选择和更新。

但是如果我们知道数据库是空的,我们可以做插入,并且是99%甚至更多,它肯定会成功,除非有一个错误与数据的存在无关。这是第二个改进,第三个改进是增加了更多类型的工人工人是一种获取数据并并行处理的东西。

我们在数据库中添加了实体工作者和实体工作者,它们接受数据并通过单个插入将其推送到数据库中,就像第一个改进一样。我们想要添加更多的工作线程,因为我们看到CPU的图形时,我们看到它是一种窦状图,在开始时工作非常努力,然后当它到达JSON文件的末尾时,它停止工作,因为它只处理一个条目。

一个组件。因为它只处理一个条目,所以它不使用CPU,它不像我们希望的那样利用CPU。因此,这里的一个改进是添加JSON文件工作器。然后我们可以并行地取很多json并在这些json中添加并行实体。但是我们有另一个问题,如果你还记得我们在一开始说,一个zip文件可以包含一个JSON,或它可以包含150个JSON所以很好,我们有JSON文件的工人,但这还不够,因为zip文件工人可以帮助我们做许多并行拉链和我们有不同的问题,因为我们不知道处理的时候,如果我们能做并行的zip文件的工人,如果我们能够并行运行它们因为日常数据库同步,zip文件必须同步,它们必须我们必须在插入当前数据之前插入前一天的数据。

我们可不想丢失数据什么的,对吧?我们要确保我们有所有的安装。-是的。

昨天的举个例子,如果我们有一个实体,例如,如果我更新实体如果我插入,所以实体的前一天,今天我要做的另一个变化对实体将会发生什么如果我要处理现在的前一天前一天是我今天要插入新数据,然后处理之前的数据和更新新的数据所以它意味着我结束的所有数据数据库,尽管我不应该因此,对于每日DB同步,我们只使用一个worker来处理zip文件,而对于初始DB同步,我们可以使用更多worker,使用两个或更多worker。这是我们做的一个很大的改变我们可以看到当我们做的时候我们可以看到CPU图形是一条直线,这意味着CPU一直在工作,以处理DB同步,它工作得很好,所以…

让我们来看看。实际上下一个改进是两个改进。

我们把它们放在一张幻灯片里,因为这是某些东西的后处理,但它们之间没有关系,所以一个后处理是DB同步本身的后处理当我们做DB同步的后处理时,我们想要创建索引,而不是在安装过程中创建索引。这是我们可以做的另一件事,只是因为我们分离了每日数据库同步和初始数据库同步。

我的意思是,如果你去看一下如何快速将大量数据插入数据库的过程备忘表,你会发现其中一个建议是在最后创建索引,而不是在插入过程中创建索引,因为当你完成数据插入时,索引的构建要快得多。另一件相关的事情是,我们想要并行创建索引,这是我们看到的一个很大的改进,但它只支持更新的进程,我想是版本11。做完这些之后,我们需要检查数据库的版本这意味着我们要为不同的版本做不同的工作,所以我们有其他我们这样做的地方,但这意味着DB同步将更快的新版本的繁荣。另一种类型的后处理与第一个无关,当我们插入一个组件或一个漏洞时,当我们为每日数据库同步做这个时,我们将做一个反向查找,看看我们是否有一个漏洞。如果我们需要根据新的漏洞或更新的漏洞更新一些东西,对组件也是如此。如果我们需要这样做,我们需要运行另一个东西但是我们需要检查我们是否需要这样做这个检查对我们很多人来说都很有用,但是我们知道数据库是空的所以没有理由做这个检查。这是我们做的另一个很大的改进,因为我们把每日DB同步和初始DB同步分开了。

我们的图像是这样的。首先,我们必须迁移到繁荣因为在那之前我们使用的是不同的数据库,对吧?我们有昂戈尔或类似的东西。然后我们改进查询来重用[听不清]对象,你可以很容易地看到,图表只是减少了一点。然后我们还添加了子组件稳定/插入作为我们在开始时谈到的第一个改进,所以我们只是使用批处理,逐个插入。然后减少到10小时。这很好,但还不够好。然后我们在更新之前使用乐观的插入,我们还添加了组件和漏洞隔离,只花了4个小时就获得了完整的DB同步,这是16个小时的巨大改进,几乎是16个小时。然后我们也有JSON和zip文件工作器,这工作得很好,它帮助我们处理CPU,就像诺亚提到的。我们还在初始DB同步之前删除了一些索引,所以现在我们只花了两个小时就得到了一个完整的数据库同步,所以我们添加了提取索引的后处理和使用组件时的后处理,你可以看到,我们只花了56分钟就得到了一个完整的数据库同步,这是一个惊人的改进,之前需要15个小时。不仅如此,当我们使用一个更好的(听不清),我们存档9 k AI行动和读写速度,所以我们会得到更好的解决方案,需要我们只有36分钟得到一个完整的数据库同步是一个了不起的进步,你可以看到它不是相关软件只对(听不清),然后我们会得到一个更好的解决方案,数据库同步,超级快,我想我们都很高兴,我们有了更安全的环境,我认为现在是提问的好时机,非常感谢大家。

谢谢,谢谢大家的参与。

你可以在Twitter上找到我们,也可以在LinkedIn上找到我们,随时联系我们,问我们任何问题,留下任何评论。

没错,我们是为你们而来的,非常非常感谢你们的加入。

请随时联系我。

谢谢你!

要么释放,要么死亡