我们如何提高我们的DB同步性能| JFrog x射线

博士TL;
我们都想把所有东西开发得超级快。因此,当一个“简单”的数据库同步过程需要花费很长时间时,我们需要跳出思维定式。以下是我们在JFrog Xray中实现的解决方案,以提高我们的DB性能,将同步时间从16小时减少到2小时!
什么是JFrog x射线
首先,在深入讨论挑战和解决方案之前,让我们回顾一下什么是问题JFrog x光.JFrog Xray是一个工具DevSecOps团队,用于深入了解软件应用程序中的开源组件。通过对存储在JFrog Artifactory存储库中的工件的深度递归扫描,Xray可以识别安全漏洞并帮助确保许可遵从性使用为组织定义的策略。
x射线现在是如何工作的
为了扫描漏洞并验证许可证遵从性,Xray使用了一个包含许多公共组件、漏洞和许可证的大型数据库。当安装x光第一次,有一个初始DB同步,它下载和存储所有已知的公共数据Xray,这是公共信息的中心知识库。
现在,这个数据库的压缩大小大约是6GB,并且每天都在增长。为了提取下载的数据,在保存到Xray数据库时需要45GB的磁盘空间。为了将这些数据存储到Postgres数据库中,Xray提取100MB的zip文件,并分析zip文件中的json文件中的2000个对象。这以前要花近15个小时!具有最低的系统要求。
*图像信用
可能的解决方案
为了应对这一挑战,Xray团队考虑了几种具有相似行为的不同解决方案。第一种解决方案是将已经存在的数据分发为数据库表,而不是在用户端重新创建数据。在这种情况下,我们最终会有更多的数据作为我们软件的一部分来分发。另一种选择是使用在线服务器获取组件和漏洞的信息,这可能需要很多时间。第三个方案是混合方案,即为使用较少的组件建立一个中央数据库,并分发通用组件。因此,我们决定将这三种解决方案结合起来。
从调查步骤开始
为了调查当前状态,我们使用pprof工具.pprof是CPU分析器的一部分吗gperftools由谷歌开发,用于分析多线程应用程序。Pprof具有生成程序调用图的graphviz可视化的能力。结果表明,Xray在数据库操作上花费了大量的时间。下面是一个pprof图的示例:

pprof示例图
我们发现许多单条目插入,而不是批量插入,例如:
INSERT INTO table VALUES (a,b,c)
我们可以在哪里使用:
插入表值(a, b, c), d, e, f, g, h,我)…
改善# 1最大的挑战是将这种改进整合到我们的代码中,所以我们创建了一个小队列来处理特定的持续时间或大小。
聚合
我们内部聚合了go通道中的对象,并每500毫秒或100个对象耗尽它们。
这是我们所做的主要改进之一。包括之前的所有更改和这个更改,我们测量到与最初的时间相比,性能提高了大约60%。
初始DB同步vs每日DB同步
改善初始数据库同步非常重要。最初,DB是空的,我们知道99%的对象被添加而没有更新。因此……
改善# 2:我们选择了一种乐观的方法,尝试插入数据,而不是选择对象并相应地工作。这有助于通过减少几个小时来提高性能。
然而,每天的同步是另一回事,因为我们已经有了一个包含组件和漏洞信息的数据库(这不是我们第一次运行它),我们希望确保这个数据库自动或手动更新任何新的漏洞。
我们爱的工人
今天,XraY使用不同的工作者,如下三种:
- Zip文件的工人
- Json文件的工人
- 组件/漏洞工作者(json文件中的实体)
改善# 3: Xray使用worker并行读取原始文件,而不是并行读取一个文件上的组件,这有助于我们保持服务器的工作。zip文件包括100MB,其中包含有2000个实体的json文件。
来帮助我们减少索引
因为我们插入了大量的数据,并且很乐观(记住,我们只在初始DB同步时添加了它),所以我们在进程结束时对最大的表应用了以下方法。改善# 4:填充最大的表,通过创建表的数据的批量负载,使用复制,然后我们创建表所需的索引。你们可能知道创建已存在数据的索引比在加载每行时增量更新它更快。

JFrog x射线性能改进总结
总结
希望这些改进能帮助您解决您可能正在经历的类似行为。敬请期待更多x射线改进。
想了解更多关于数据库改进的信息吗?在swamp上观看我们的演讲,DevOps用户会议>
