用例-为HA环境编写性能用户插件
文摘:
Daryl Spartz / Yahoo, 2016年5月:在需要移除大量工件的大型安装中,工件清理插件的执行可能会因磁盘活动过载而产生不利影响。这个演示将描述我们对插件的修改,使我们能够成功地删除超过13TB的数据,而不影响系统或响应时间损失。
讨论转录:
我叫达里尔·斯巴茨。我在雅虎工作。我是Artifactory的新手。我想我是去年十月开始的。
我的第一个任务是清理藏物。每个人都可能处在这样的情况下,你只是不断地成长,成长,成长,我可能会在后面重复这个,但是我们,我们有太多的神器,我们已经很满了。我们已经分配了一个27tb的文件卷。我们大概有23% - 23tb满了,所以。我们过去曾试图清理这个问题,但我们遇到了问题。所以,我的任务是在不造成干扰的情况下完成。这就是这个演讲的由来。我们处于一个高可用性环境中,因此我们有两个相互之间快照镜像的文件。我会更深入地讲。
那么,性能是什么意思呢?我们将简要讨论一下。它围绕一个使用Artifactory Cleanup插件的案例研究展开。我将只讨论我们的高可用性架构。顺便说一句,当我把这些都搞定之后,我们从Artifactory 3.9迁移到了4.7。虽然我们用了一些Chef,但我们把很多东西都换成了Chef。我会复习一下烹饪书和一些我以前做这个的食谱,以及它是如何工作的。如果我们有问答环节,希望你们有时间。
性能是什么意思呢?就像任何软件一样。如果做得不对。它是在Artifactory的上下文中运行的,所以你可能会影响Artifactory本身,至少线程在运行。你知道,就CPU使用而言,你正在消耗的内存数量,在我谈论清理的这个特殊情况下,你通过删除工件来打击I/O系统。
所以,作为一个插件,你所能控制的东西是有限的。您正在使用Artifactory中的函数或API调用。你不能真正控制它,但你能控制的是你调用一个特定API的次数,以及频率。如果你有一个长期运行的东西,你知道,你会消耗很多资源,所以你可能想要以不同的方式处理它,或者以某种方式控制自己。2022世界杯阿根廷预选赛赛程我会讲到的。
因此,在这个特殊的情况下,我从Artifactory Cleanup插件开始。它在GitHub上的JFrog组织下可用,它的目的是删除基本上不被使用的工件。因此,我从最初的脚本开始,脚本执行一个API调用,以获得特定年龄的所有工件的列表,这些工件在特定的时间内没有被下载。然后脚本对找到的每一个都进行循环并删除它。
这成了我们的一个问题。同样,我们有23tb的空间。到它结束的时候,我们清理了大约9tb的数据。所以我们有很多很多东西。每次我们删除一些东西时,所有的活动都在文件中如果我们放任不管,就会占用我们的数据库。所以我们打开了一些锁。长时间运行的锁。这给我们带来了问题,我们最终不得不打电话给JFrog支持,来弄清楚我们是否可以终止正在进行的事务。
所以我从这个开始。同样,在高可用性集群上使用NSF挂载点。当我们全力运行它时,我们确实注意到我们正在影响文件器上的服务,因为所有的I/ o都在进行。我们不是文件上唯一的租户,所以我们对系统的其他用户来说不是一个好公民。当我们运行这个时,我们从一个特定的主机上运行它,在那个特定的Artifactory实例上的CPU负载,我不记得它是否是备用的,但是,CPU仍然激增,我们的监控开始提醒我们有这么多CPU在运行,诸如此类。这并不一定是灾难性事件,但如果它是您正在攻击的负载平衡集群的一部分,则可能会影响定向到该特定主机的用户,因此。同样,您希望成为一个好公民,不要通过给它额外的负载来影响您的服务水平协议。
这就是我们发现的。当我们运行它时,我们得到了一个锁等待超时。最初运行它。我们必须处理好它。当我开始深入研究这个问题时,我发现,插件,你可能知道,插件是在启动时加载的。它从插件目录中读取并加载它们,然后在JVM中加载类。然后您可以在类中定义多个端点来调用不同的函数。
一旦我发现这些是很重要的一点因为我想做的是能够控制插件。不是让它完全运行,不是硬代码,而是特定的节流机制。但是我想控制它,也许我想暂停它,也许我想停止它,或者其他什么,所以。知道。
这是我们HA集群的一个快速图。所以我们有一个c名,所有用户或应用程序都可以使用。然后在这两条边之间旋转,标记为GQ1和BF1。我忘了换了。但是,这是我们的共址的名称。BF1就像我们的灾难恢复,所以在这个特殊情况下,没有流量真正进入BF1。因此,当涉及到GQ1端时,我们有一个负载平衡VIP,它将流量引导到三个独立的实例。一个是主服务器,另外两个是从服务器。数据库也落后了。我们在两个colo之间有一个双主数据库,在主数据库和从数据库之间有一个从复制。 And this is I believe the way JFrog helped us architect the BCP. Our disaster recovery mechanism.
因此,我最终所做的是,我采用了原始的Artifactory Groovy插件,并对其进行了增强。我添加了一个可选的节奏参数,您可以在REST API调用中添加到它,或者实际上甚至作为预定的作业,我们将在一分钟内看到。这样你就不会跑得太快。你可以让它慢下来这样它就不会冲击磁盘驱动器,网络活动就会是NSF。我使它动态可调,所以如果我被认为花费了太长时间而没有影响,我可以减少节流时间,这样它可以运行得更快一点,我们可以观察我们的监控指标,看看我们是否影响了任何服务。
我添加了暂停、恢复和停止控件。如果我们认为我们影响了某些地方的性能,我可以暂停它。然后它的状态,它要删除的文件数量将保持在那里,我可以稍后恢复它。可能是下班时间吧。或者如果我不想调整暂停时间。
我添加了一些我认为非常重要或有用的日志消息。它会告诉我我在这个过程中处于什么位置。如果我们有,在一种情况下我们有几百万。我说到哪里了?我是在第一万人中还是在最后。我很好奇有多少空间被移走了,所以我也记录了下来。
我添加的另一件事是增强功能。最初的插件使用一个属性文件来定义策略。这是一个单一的政策。你可以列出你想要多少回购,但这是相同的政策。所以如果你想回顾三个月前。这款游戏已经上线3个月了,但已经有3个月没有被下载了。所以我改变了,所以你可以有一个或多个回购每个政策或任何你想做的。
所以我把它贡献给开源,你可以下载它。这是最新的版本。有一点是,Groovy需要最新的4点X来支持对配置slurper进程的处理。您还需要这样做,因为在以前的Groovy支持中,无论如何都存在一个漏洞,因此。
这是一些你可以做的旋度请求以及你如何指定它。不幸的是,它强调了这一点。但基本上是相同的调用,但我添加了几个选项,你可以指定月份,回购名称或名称列表,我还添加了一个演练选项。所以。如果你想检查一下,确保它不会搞砸任何东西,它基本上只是告诉你我要做这个,它不做那个。然后是节奏参数。单位是毫秒。在这种情况下,基本上,每删除一次需要2秒。然后其他命令是stop、pause和resume,就像我提到的那样。这些都在GitHub上。 You can download this and use it.
下面是一个使用我添加的日志的运行示例。当它开始时,我有两个回购。它叫做Mobile和Fastbreak。然后我回顾的月数必须大于3个月。我设置了每次删除一秒的速度。一秒可能是非常保守的,但你知道,可能半秒或更短。我可以动态调整。当它开始时,它告诉你参数,然后开始删除。如果你注意到最后几行,它会告诉你它删除了多少文件。是25.7万人中的两个人。 And the total bytes so far are returned. I believe that’s like 10 — 10 megabytes. Or am I off? That’s a gigabyte. So, anyway, so that information goes out there. It’s all logged at the info level so that’s, of course, adjusted — can be adjusted, well it’s adjusted through the log back dot xml of Artifactory.
这是政策。单项政策在底部。这就是旧的配置属性文件。上面这个,Groovy的config slurper也很好地支持了这一点,所以你可以有很多策略,然后在每个策略中,你定义repo或repos,然后你可以选择把这些其他的值放在那里。你是否需要一个起搏参数或者你是否需要一个演练。如此,如此。这就是现在的运作方式。
这就是它的作用。这实际上,就像我说的,清理了,大约9tb的数据。我记得我们一开始设定的时间是两秒。我把时间缩短到一秒了。我们花了一周的时间才完成,不过这是免费的,你知道,让它运行也无妨,除非你的空间真的很紧张。
是吗?
[观众]几个问题。你是在运行前打碎了快照镜像,还是刚刚得到备份,还是使用了[…]实例?因为我认为如果你删除了master来[…]
是的。
(观众)
不,不是我们打碎的,是我们放它走的。我们做快照,所以如果我需要恢复任何东西,有每小时,每周快照。因此,即使在运行这个之后,我们也没有看到一个空间返回给我们,直到快照结束滚动。
(观众)你删掉了快照。
是的。
[观众]我的第二个问题是[…]Docker图像是你们[…]的一部分?
问题是我是否删除任何Docker。在这一点上,没有。移动版和快攻版——我不确定快攻版到底是什么,但移动版是iOS和Android版的图片。至于快攻,我不太确定它到底是什么,但肯定不是Docker。在这一点上,我们没有为Docker使用Artifactory。
还有问题吗?是的。
[观众]那么,你在使用GUI脚本。但是[…]您是否也可以使用CLI[…]。
问题是,通过CLI编写脚本是否更好。说实话,在这个特定的情况下我没有使用CLI。但我只打了一个电话,就得到了所有要删除的工件的列表。我不知道如何在CLI中返回。我猜是某种物体。我猜,你也会这么做。你想要有节奏。这是内置的节奏。如果你想要控制它,你必须用CLI编写脚本。但我认为,本质上是一样的。
插件的唯一优点是,在这种特殊情况下,它们有一个在Groovy脚本中定义的计划作业。所以,我相信它会在周日早上5点左右运行,所以这是经常发生的事情。如果你想,你也可以设置一个crom来运行CLI,但这似乎更容易一些。它是可编程的。我想要的回购只是更新属性文件。同样,您可以用CLI完成同样的事情。您可以设置一个属性文件。所以我不知道它是否有什么真正的优势。它只是这样包装的。它已经在那里等你了。
还有问题吗?是吗?
[观众]那么你是否也必须进行[…]清理,因为有时工件不是[…]?
是的。还有另一个插件,删除什么的,我不记得名字了。但是,是的,我们确实这么做了,现在这是一个手动步骤来启动它。我相信我们也能找到一种自动化的方法。
还有问题吗?
(观众)
我很抱歉?
(观众)
是的。我们基本上与组织合作,让我们知道什么样的政策对他们是正确的。我们选择了三个最大的空间使用者作为起点。我们还没有超出这个范围。我们已经讨论过有一种方法来标记特定的工件,然后我们清理那些标记了或没有标记的工件,诸如此类的事情。因为这是,任何三个月没有被下载的东西,这并不意味着它没有投入生产。对吧?你最终可以摆脱生产中的某些东西,而你不想这样做。所以这不是理想的情况。这就是使用CLI的脚本思想。 You can do it that way and have a different means of tagging and checking the tags or maybe even enhancing this plugin to optionally look for certain tags to identify it but yeah, it’s something that we negotiated with the groups.
还有问题吗?很难看到。这是更好的。
接下来我要讲的是因为这是我做的第一件事就是清理。接下来我们想从Artifactory 3.9转移到4.7。我们用Chef做了一些东西。辅助的东西。但主要的东西是我们自己专有的包装和配置。对于Artifactory本身,我们完全转移到了Chef。因此,从安装到配置Artifactory的所有事情,无论是独立配置还是HA配置。是通过Chef食谱完成的。然后是Artifactory的启动和停止函数。希望在某个时候——我看了看Chef市场。 I didn’t find anything that did exactly and everything that I wanted so hopefully my stuff will go out there at some point.
所以,我处理这个问题的方法是,我希望它是数据驱动的。所以我所做的一切都是数据驱动的。把版本Artifactory拉下来,它是一个属性——Chef属性。它在食谱中有定义但它可以在不同的环境中被重写。因此,我们有一个测试环境、一个登台环境和一个生产环境。我们可以覆盖那个属性,并有不同的版本,如果我们想测试它。特定的包名,下载的位置。所以我们建立了一个远程缓存镜像到JFrog,所以当我们第一次运行这个时,我们得到了我们想要的最新版本的Artifactory,然后我们缓存它。如果我在测试环境中这样做,当我进入登台时,我不需要回到JFrog。现在它被缓存了。 And same with production.
但所有这些都是数据驱动的。一切都准备好了。就像在HA环境中,卷名的归档器,实际的主机拥有卷。这些都是属性。它们都可以在环境或角色属性设置中进行配置。因此,当你分配一个节点,例如环境,登台意味着某些事情,然后我可以为登台、生产或其他任何事情设置不同的文件卷。所以。
所以很多资源都是标准资源。2022世界杯阿根廷预选赛赛程使用yum存储库指向我们的缓存镜像。包定义企业版本名,然后定义版本号。现在如果我想升级到4.8,我在cookbook的默认属性中修改一行,提交,我们的管道会部署它。很简单。我们使用的所有实例都必须有许可。我把它们放在Chef保险库中,就像在任何其他机制中一样。所以现在,当一个特定的部署在一个特定的主机上进行时,它会进入Chef保险库,并获得它的特定许可,我使用文件资源将它放在Artifactory配置中针对该特定主机的正确位置。
为一些项目使用模板。特别是存储属性。试着记住里面到底有什么但那只是个模板。系统属性,然后是集群属性。它们都是模板。一切都来自属性。所有食谱里都没有硬编码。然后,这些都是可以变化的。因此,我有一个属性来定义这个安装是独立的还是高可用性的,然后这些文件的位置根据不同而不同。脚本或食谱会处理这些。
有很多地方我们有xml文件需要修改,即使我们不拥有它。我不想把整个文件放到一个模板下。特别是,我们的实例是为SSL设置的,因此我需要修改server . xml。所以我用了一本在市场上找到的厨师食谱。它叫做xml下划线文件。我在一些事情上发现了它,但我需要更多。所以我扩展了它,并把它回馈给了包的所有者。他采取了一套改变,第二套我还没有收到他的回复。但它基本上允许我修改现有的xml文件。例如,我可以用SSL连接器替换连接器,我们使用APR Tomcat本机库来实现更快的连接。 So I have to replace, delete the ones that come with Artifactory, and replace it with our specific xml segments.
对于插件,我们再次选择插件。我们现在只有少量的开源软件。但我希望能够打开日志记录,我不想手动编辑,所以我使用相同的xml文件,添加日志记录器条目,用于返回日志,例如,对于这个特定的插件,我想在调试或信息或警告级别进行日志记录。
它运行得很好,在后面几张幻灯片中,它是属性文件的一部分。您现在在其中定义的日志级别。您可以将其默认为零。因此没有为它创建日志记录项。这就是删除空文件夹部分的情况但对于清理,我想看,我想知道有多少文件,多少字节被保存了。我在属性中设置了info当检测到时,这个xml文件将会输出并添加一个logger条目。如果该条目不存在,则添加该条目。如果我想要改变它,xml文件会明智地不添加另一个条目,这样我就不必指向旧的条目。它只会找到那段并更新那段。这很有用。
对于HA,同样使用一堆节点属性模板。用于创建集群主目录的目录,其中有[…]目录、数据目录和备份目录。我使用资源挂载来挂载NSF的东西。因此,您可以将主机、卷名和挂载上的任何选项定义为属性。所以你有两组。HA配置有主服务器和备用服务器。然后这是在位置级别上完成的,作为你在Chef中找到的滚动的一部分。所以,在另一边,你只是把它翻转过来或者利用它们的体积然后它们指向彼此。所以效果很好。使用link进行从Artifactory主路径到文件卷的符号链接。
然后我创建了开始和停止。它们只是作为烹饪书的一部分的函数或者库函数用于启动和停止。开始时,我添加了重试功能,因为我注意到,当我们从three-nine迁移到four。x时,我们到了一个Artifactory没有出现的点。它基本上会发出一个日志信息,说这是一个问题,但请重新启动它。结果重新启动就出现了,所以我添加了重试逻辑,所以我等了一段时间。如果我没有检测到它是向上的,我通过对应用程序进行旋曲来检测它。因为如果你去系统,Java进程还在那里,只是它没有对端口做出响应。如果旋度有效,就没问题。如果它不等待一点,然后尝试重试。它只是节省了一点提醒和处理它的时间。
我花时间做的另一件事是创造厨房环境。这非常非常有用因为我可以测试所有的配置选项。对于厨房环境,我可以再次覆盖烹饪书中定义的属性。我可以说这是一个独立的,我想给主机这个名字。我可以在Vagrant上设置这些,在我的笔记本电脑上,我可以安装Artifactory实例,启动并运行,使用,测试SSL能力等等。我可以在厨房里把它改成HA。我并没有创建两个不同的Vagrant vm。我没有那样做。但是对于其中一个,我从我的笔记本电脑中导出了一些NSF,这样Vagrant就可以挂载它们,这样我就可以测试挂载方面。诸如此类的事情。 And it was really, really useful. I can do all this without committing code and watching our pipeline fail somewhere down the road. So it was very, very useful.
我想就是这样了。所以我想感谢JFrog给我这个机会和你们交谈,感谢你们来听我的演讲。如果我有一些。插件的名称。在这里可以找到工件清理。就是我犯的错误。然后是xml文件。我指着我的回购,因为他还没有接受我最新的更改。事实证明,你可以有一个部分的xml更新,但你只能有一个,我扩展了它,所以你可以有多个。我不知道为什么他没有回应,你知道,积极的或消极的,但我可能会再试着联系他。
所以,问题吗?有人有问题吗?
