用例-实用的可伸缩性:在人工HA的框架下

文摘:

Viktor Gamov / Hazelcast, 2016年5月:应用程序的可扩展性很难。应用程序的可伸缩性做得好就更难了。
虽然有些人可能会尝试从头开始编写分布式集群框架,但从另一方面来说,务实的开发人员很可能会利用成熟的开源框架,如Hazelcast,它会解决所有的麻烦。在本小节中,您将了解JFrog的实用开发人员如何在构建人工高可用性特性时,从使用Hazelcast经过实战测试的集群功能中获益。

讨论转录:

我叫Viktor Gamov,是Hazelcast的解决方案架构师。本质上,解决方案架构师所做的就是解决问题。而且,你知道,我想你从那位先生那里得到了推荐他也解决了你所有的问题。

今天,我们将讨论人工HA,以及开发人员为了使这种解决方案解决他们的问题所做的选择。

所以本质上,人工H - HA有一个简单的想法。不惜任何代价交付二进制文件。这就是Artifactory有多个实例的原因。很多东西会被复制,因为在现实世界中,一切都可能会崩溃。这就是为什么产品的高可用性对于开发人员的基础设施至关重要,这是JFrog作为该产品开发人员的一个非常非常大的目标。

我今天要讲的很多东西,都可以在人工智能中找到。因此,从本质上讲,作为一个分布式系统或高可用性系统,人工HA需要解决多个问题。

首先,这张图解释了人工高可用性的基本架构。正如您所看到的,作为后端,Artifactory可以在多个数据源中存储数据,包括在完全缓存模式下的数据库。因此,还将二进制文件包含在数据库中。二进制文件也可以存储在网络附加存储器上。为什么是网络附加存储?因为多个实例可以,需要访问它。使用网络附加存储或任何可用于多节点访问的网络附加存储是一个非常合理的选择。此外,还有一些即将进入Artifactory链的东西,例如与Amazon S3的集成。所以在这种情况下,你可以克服这个NSF的怪物和[…]事情,使用正确的和可扩展的解决方案。从非常好[…]。

所以Artifactory集群的一些信息Artifactory成员需要交换关于缓存的信息,关于方法数据中存储的一些东西的信息,加上对源的并发控制,因为你可以看到,在这里的FAS或数据库中是共享资源所以我们需要对访问进行某种控制,就像对并发访问一样。

所以。有几个,你甚至可以说这是一个问题,但我想把它看作是挑战。有几个挑战。它是对二进制文件的并发和分布式访问。正如你从图中看到的那样,NSF就像一个中央存储,尽管它在硬件层面上有一些备份和一些弹性,但从Artifactory的角度来看,它仍然是一个单一的来源。因此,为了提供对这些资源的访问,这种访问可以,也应该受到控制2022世界杯阿根廷预选赛赛程。因为这个访问应该控制在哪个节点会做什么。例如,有一个主节点将在您的Artifactories上运行垃圾收集,或者在您上传新jar并需要解析Maven或其他repo -其他工件的元数据时运行某些节点可以运行索引。

所以这种挑战是,因为有多个实例,它们需要有相同的世界图景,相同的谁在某一时刻拥有特定二进制数据的图景。Artifactory成员需要访问的一些信息是关于存储库的信息元数据,关于哪个文件属于哪个存储库,等等。因此存储库缓存是Artifactory HA开发人员面临的另一个挑战[…]。

正如我已经提到的,有些任务是在后台运行的,比如,当你运行索引或者当你在垃圾收集中运行一些校验和检查时所以这个任务需要巩固系统的不同组成部分任务已经完成或正在进行中,还有很多其他的事情。所以本质上,关于工作进度的识别是另一件事,我们要讨论的另一件事是它是如何在人工链中工作的。由于一个你们可能都理解的原因,连接性对于分布式系统是必不可少的。对吧?所以在这种情况下,Artifactory链更多的是受网络约束的系统,而不是受I/O约束的系统。对吧?在这种情况下,网络的速度很重要,此外,发现集群中的其他成员何时加入也很重要。在一个节点无法执行作业的情况下,需要存储此信息以进行故障转移,因此如果该节点不可用,我们需要将作业发送到另一个节点。

我刚刚解释的一些东西我只关注四个方面因为它们很容易理解。很容易记住,因为我想——你们在这次演讲后会记得一些事情,即使昨天很美好。有几件事很容易记住,人们通常能记住的三、四件事。

这是我要关注的几件事。特别是特定的api,我们称之为Artifactory HA开发人员在产品中采用的拼图游戏的一部分。因此,我们将讨论分布式锁,它提供了对共享资源的并发访问。2022世界杯阿根廷预选赛赛程共享资源,如二2022世界杯阿根廷预选赛赛程进制文件。我们将讨论一个分布式映射,它为Artifactory HA中的一些元数据信息提供分布式缓存。一个分布式主题,它提供了执行分布式通知的框架——通知不同的组件。成员侦听器允许在成员加入或成员离开或有关成员的某些信息发生更改时获取信息。另外,我还将讨论一种叫做Discovery SPI的东西。

那么为什么是Hazelcast呢?Hazelcast的本质是什么?所以Hazelcast本质上也解决了三个简单的可分布问题但是没有简单的问题。您希望解决的这个问题是分布式存储、分布式消息传递和分布式计算。今天我们将重点讨论分布式存储和分布式消息传递。也许明年我会谈论分布式计算[…]。

对于Java开发人员来说,Hazelcast看起来像是Java集合的分布式版本。基本上就是这样了。这就是为什么Hazelcast很容易与任何产品集成。我们来看看第一个问题,第一个问题是分布式并发控制。

做分布式并发控制可能很容易,在座有多少开发人员,你们中有多少人至少做过一次分布式锁实现。是的。我们这里有人知道怎么做。你可以接受这个,但是支持它很痛苦,使用起来也很痛苦,例如,我在我的[…]中使用数据库作为分布式锁的存储。因此,一个节点将锁放入表到数据库中,另一个节点将从数据库中读取。正如你从这幅图中看到的,你会到达那里的。你知道,你会从你想去的地方出发,但这取决于,你想要一个平稳的旅程,或者你想要一个痛苦的旅程,你想要享受这段旅程。

这就是为什么我们要讨论称为ILock或分布式锁的组件。正如我已经说过的,Hazelcast提供了分布式版本的Java集合,这就是为什么开始使用它非常容易。在这个例子中,illock是扩展Java,也就是并发锁。它遵循类似的范式。它是重入的,所以如果成员获得了一次锁,再次获得相同的锁,就不会出现死锁的情况。这样你就能拿到锁了。如果其他成员试图获取这个锁,什么也不会发生。如果成员下降,锁将被释放。还有其他释放的语义,比如,强制释放可用的锁。并且锁将被第一个试图获得的成员获得。 And there is a condition. There’s additionally […] same thing with Java which is concurrent lock. There’s a condition that can be used from the other member that will be condition for releasing this lock.

本质上它是这样的,它是这样的。所以Hazelcast实例。这将启动Hazelcast流程。在这种情况下,它将是嵌入式进程。现在我们锁定了。这段代码可以在应用程序的多个实例中执行,所以这个锁是分布式的,任何成员都可以访问它。对吧?本质上,有几件事要记住。我们需要获得锁,不要忘记释放它因为在这种情况下,除非你强制解锁,否则其他人无法访问。

让我们快速看一下。这个东西在现实生活中是如何工作的,从实际应用的角度来看它是怎样的。稍等一下。我的电脑在换屏幕。好吧。好吧。我的终点站在哪里?你们看得清楚吗?我把它画大一点。这是我之前没有检查过的东西。 Shame on me. All right.

我这里有一个简单的应用控制台。从本质上讲,它已经嵌入了Hazelcast,我们将讨论Hazelcast支持的不同拓扑,但是把它看作是我可以在Hazelcast中做的一些事情的在线接口。我可以做一些帮助,看看他们可以运行的不同命令。在这个特殊的例子中,我感兴趣的是在特定的地图上使用log,在这个例子中。首先我要做的是,一个成员可以对key 1执行lock操作。在这种情况下,键是被获取的当我试图通过键1对数据做一些事情时从另一个成员这家伙,就像这里的这个家伙,这是一个不同的过程。这是一个不同的进程,不同的JVM。所以我要做的是。M点。首先,我可以得到一些东西。 Some data, right. I can try to get, and I’ll get the result now because nothing is there yet. But when I’m trying to m dot put and I’ll do dice like test one. You see, this process stuck because there is right now another process that holds this lock.

所以这个从另一部分你可以做什么,你可以做测试,测试2没有任何问题。如果result为空,返回之前的结果。如果我像这样运行它,它会返回之前的结果,那是一个测试2。本质上与map。put在Java集合中提供的语义相同。那么这个人能做什么呢?所以在这种情况下,它只是坐在那里等待。现在我需要解锁。如我们所见,成功解锁,写入数据,并返回由该进程写入的最后一个值。对吧?这有意义吗? I hope it does.

很多不同的API都支持它。所以我可以看到这里。如果我在这里。说地图。我可以试着锁上一段时间。如果我没有得到锁,你知道,我可以等待,锁将不可用,我不会得到它,会失败。还有很多其他的东西我们稍后会讲到。

好吧。现在我回到幻灯片上。

所以。所以第一个用例是分布式并发控制。所以本质上,如果人工HA需要在某个特定的二进制文件中做一些重要的事情,某个特定的工件,它可以获得锁。可以为路径获取一个锁,所以在这个例子中path是键因为路径是唯一的。我们没有这个问题因为我们没有键的唯一性问题。

下一个是分布式缓存。所以分布式缓存本质上是一个应用程序,一个软件,它允许很多进程,很多jvm,访问相同的数据。缓存数据。由于数据在内存中,与直接调用API相比,缓存提供了更快的访问。或者在[…]数据库,续集脚本中。或者尝试运行一些计算。本质上,缓存是一种提供快速访问的临时存储。

丫缓存。缓存,是我们用来加速的东西。但是当我们谈到缓存时,我们通常会想到memcache。但是有些东西我们不能从memcache中得到。对吧?在这种情况下,Artifactory HA是一个产品。它需要是独立的。所以开发者可以向客户提出这个要求,说如果你使用缓存,你需要另一个基础设施,等等,等等或者你想做,比如,可扩展的缓存,你需要另一个基础设施在这种情况下,将与这个软件一起工作但我们试图避免,他们试图避免。在我开始讨论分布式缓存之前,我想谈谈为什么memcache实际上可能不是那么糟糕,也许是更好的解决方案,关于分布式系统和分布式缓存中的数据分布。

我有个问题要问你。你在这张照片中看到了什么?记住,我们讨论的是数据分布。不,你安静点。安静的坐着。

(观众)克隆

好了,我们看到了克隆体。正确的。我们在这里看到了什么?

(观众)这个问题很难回答。克隆很容易…

谁知道我为什么会看到这里的一切。实际上我给了你们一个小提示。两幅图上都有一艘船。

(观众)的肉。

或羊肉。

(观众)条纹。

条纹。好吧。还有什么?我要找的另一个名字是什么?

(观众)

好吧。

(观众)

更好。

(观众)

[观众]给你。这就是为什么你要用首席架构师。

是的,我们看到了碎片。这就是为什么我喜欢用这张图来说明分布式系统中数据分布的两个基本概念。这是一个复制和分片。也称为分区。那么它们之间有什么区别呢?当我们进行复制时,我们基本上在每个节点上存储相同的数据。因此,在这种情况下,这种方法可能无法实现超大规模的扩展,因为当您尝试复制时,它将受到集群中最小成员的容量的限制。同样的数据,你需要确保数据是一致的。这就是为什么分片被认为是分布式数据的事实上的方法。

所以切分本质上给你提供了一个视图,给你提供了数据如何分布的方式,在这种情况下,引入更多的机器来扩展共享数据的存储。当我们谈到部署选项时,有些部署选项对于某些产品来说可能是很自然的在Artifactory HA的情况下,它是嵌入式模式。hth华体会最新官方网站这就是为什么我说像memcache这样的东西可能不合适。因为在这种情况下,你需要引入另一个基础设施,memcache是用c++写的,你需要一些驱动程序,你可以访问memcache系统,在其他网络调用,等等。

当你在应用程序中嵌入分布式缓存时,你不会有很大的希望因为大多数时候,就像我们是Java开发人员,我想,我们大多数Java开发人员。而且,至少是用Java编写的Artifactory HA。因此使用Hazelcast具有嵌入式库。本质上只是一个放到web[…]lib目录中的分片。

但是,它仍然没有限制你的选择。并且Hazelcast还提供了经典的集群客户端道歉,您猜想集群可以单独部署。它允许对扩展应用程序和扩展数据存储的关注点进行管理或分离。对于需要使用集群功能的应用程序来说,嵌入式选择是非常自然的。

当我说到数据时,数据总是在内存中。但它如何安全且有弹性地保存数据呢?我将把备份存储在内存中。这对在座的人来说是不是很好?听起来确实不错。我会解释为什么。

对于开发人员来说,开发人员使用一个简单的缓存或映射抽象。在这个例子中,不管数据实际存储在哪里,它总是有简单的put和get API。但是在内部,它是由Hazelcast处理的,数据是分布式的。现在,如果我们有四个人工智能HA节点,这个人工智能HA存储的数据将分布在多个节点上,所以你可以看到,我们这里有一整块数据,但这些数据将被存储,这些数据将被存储在节点1和节点0上,这些数据的备份将存储在另一个节点上。在这种情况下,如果这个节点宕机,或者这个节点宕机,数据会从备份中恢复这个分区的备份数据在主分区中仍然可用。

这是关于分片或分区的简单观点。有不同的配置选项可用,例如复制因子或备份计数。我们称之为备份计数。人们喜欢称之为复制因子。同一数据可能有多个备份。所以在这种情况下,你可以-你想尝试并在多次失败中幸存下来。您可以同时承受两个节点的故障。当节点宕机时,Hazelcast负责重新平衡数据。重新分区和从备份中恢复数据。

让我们快速了解一下它在实际应用程序中的工作方式。所以当我的电脑切换到控制台屏幕时,我试着——我会解释你的前提。我将使用与处理日志相同的控制台应用程序。因为它本质上代表了我刚才要解释的东西。我已经在这里运行了。我来做一下。我可以使用其中一个命令来填充数据,我只需要一些数据就可以进行故障转移。

有一个命令叫,where is it?把许多。我将把前10万个1千字节大小的元素中的一些放到这个内存中。它吸收这些的方式就是管理中心控制台。这是一个允许我查看集群状态的web应用程序。或者使用嵌入式Hazelcast的应用程序。这里有两个节点。通过这个管理控制台,我还可以看到这些数据是如何分布在多个节点上的。我不知道你们是否看到了我没有这个花哨的东西-不,我有。类似于响应式设计。 Right? Not super responsive, though.

正如你在这里看到的,数据是跨节点分布的我的数据大概是节点1,备份到节点2。所以我要做的是,我要到这里来,把这个节点删掉。如你所见,二号成员意识到了失败。它只是重新平衡了集群,如果我切换回管理控制台,错了,是的,这个,数据还在。数据不会丢失。虽然我只是,你知道,从插座上取下了插头。是的。正如您在这里看到的,当您只有一个节点时,备份并不意味着什么。因此,在这种情况下,如果只在一个节点上运行,则不需要备份。正如您从控制台看到的那样,这个特定的内存消耗开始增长,因为最初存储在两个节点中的数据现在需要放在一个节点中。

另一件简单的事情是我们如何修复它我只需要引入另一个节点,另一个节点。他们马上就来。它们建立了连接,现在我可以继续在这里做实验数据会被重新平衡,各个节点上的总体数据消耗会下降。因此,在这种情况下,添加更多节点将有助于在应用程序中使用另一个存储。从管理中心我还能看到一些其他的东西。过几秒钟我会回到这个问题上。当我们讨论一些东西的时候,它是如何在Artifactory中实现的。但本质上你可以看到不同的数据结构可以在这里看到。

好吧。到目前为止,观众有什么问题吗?我不知道为什么我的电源开关很慢。我想打破这尴尬的沉默。带着一些尴尬的

(观众)做点什么吧。

好吧。开始吧。所以我不能。

好吧。第三件事是系统不同组件之间的消息传递和通知。再说一次,你需要记住我们在哪里。我们已经在Java端,我们在人工HA端,不同的组件需要获得通知。对吧?所以你能做的是,有一些工作可以听这个话题。如果有一个新的通知,这个工作需要做一些事情。

它在Hazelcast中的工作方式,它提供- Hazelcast提供分布式队列如果你需要一个发布者,一个订阅者类型的访问。此外,还有一个主题允许有一个发布者,许多订阅者。因此,不同的组件可以将数据发送到Topic Bus。

这个主题总线本质上是分布式的,这意味着这个主题,对这个主题的访问,可以被系统中的任何组件访问。所以如果你考虑这个客户端但本质上只是一个不同的组件。一个组件可以发布。另一个组件可以侦听。例如,这是一个出版商。有一些主要的成员会发送这个信息,因为,例如,如果有一个垃圾收集过程正在发生,或者索引过程,当它完成时需要通知其他组件。

下一个。连接和发现。因此,为了获取关于集群的一些信息并以某种方式存储这些信息以便Hazelcast, Artifactory HA使用了称为成员侦听器的组件。当它们是两个端口时通常在配置人工HA时进行配置。您可以仅为HTTP配置典型端口。您的构建脚本和构建基础结构将会在哪里得到工件,并且有一个成员端口。因此,本质上,您需要提供其他成员用于加入集群的端口。通过会员侦听器,可以获得其他会员的一些信息。当新成员加入集群时,我们会得到成员事件我们可以得到完整的信息,比如IP地址,IP地址,端口,实例名,等等。同样的,当成员被移除时。 If someone reboot of the member is changed, this listener will also will be triggered and the member attribute event will be — will be placed.

所以,在过去的一段时间里,我想,大概有两年吧。我们收到了大量支持不同发现选项的请求。因为Hazelcast,非常类似于Artifactory HA,我们试图成为自包含的,我们不想强迫开发人员使用任何特定的技术,所以这就是为什么所有的Discovery都是开箱使用的。我们不使用任何外部依赖,我们不使用JGroups,它是由我们限制的。这就是为什么它只是一个罐子,里面有一个7兆的罐子,里面有你需要的所有东西。但我们所挣扎的是什么,我们想要得到社区的答案,最后我们有了这个答案,叫做Discovery SPI的技术。

去年,有一段时间,几个月的时间,我们实际上和社区成员一起工作,包括在我之后在这个房间里发言的先生,Ray Tsang。他是谷歌云平台的传播者。他实际上贡献了很多,比如为Hazelcast集成Kubernetes,就是他贡献的。此外,在我们设计API时,他也提供了很多反馈。

所以,在探索方面。现在,如果您想使用TCP/IP发现,这很好,您可以将其放在配置文件中。有时或大多数时候,当我们在集群中运行时,我们不知道IP地址或我们不知道主机。因此,在微服务世界中,像Hazelcast和Artifactory HA这样的组件可以成为大型基础设施的一部分,在这种情况下,使用Discovery SPI,这个项目可以从控制台或Zookeeper获取这些信息。或者,现在,我们也提供与其他云提供商的集成,包括Azure。亚马逊。人们希望在容器中运行人工HA或Hazelcast,我们还提供了使用Docker网络使用Discover的能力。另外,在Mesos集群配置系统中运行Hazelcast集群。而过去的支持也是必不可少的。

所以我们为探索频道做了一些事情。Zookeeper、Kubernetes、Eureka,它们在Cloud Foundry和Spring Cloud(…)stack中工作。

好,让我们看看这实际上是什么样子当我们使用Artifactory时这些东西是如何完成的。我将使用你们今天看到的工具。我将使用管理中心来演示您可能在人工HA中看到的一些东西。我将使用管理中心。哦,按钮错了。也会发生。好吧。好的,现在我们可以连接到正在运行的Artifactory HA。让我回到控制台,给你们看一些东西。

所以我现在有两个进程在运行人工HA。我想把这个放大,这样你就能看到我实际上在运行Artifactory。是的,有这个。Artifactory公顷。这是非常好的ASCII - ASCII图形。HA节点标识符。这是因为这是它开始的第一个节点,我可以看到消息。因为在第一个节点上没有,所以没有其他HA成员,这就像master。我可以在数据库中查看信息我可以看到集群中有一个主节点和一个成员。所以我实际上,我正在寻找Oracle数据库和Artifactory的信息。 If I’m to […] the same — the same info in other member, okay. Oops. It should be — it should be one member. Anyways. Happens. All right. So. And I have the Artifactory HA running two members. And I’m not particularly interested in here to look inside, you know, the […] build script, I wanna show you how and what pieces of Hazelcast is used here.

首先,我们在这里可以看到,不同的主题产生了组件的通知。如果一个作业,计算一些Debian方法数据将粘贴信息,将打印这些信息到这个主题。

不同的配置变化。如果有人更改了人工HA的Hazelcast的配置,Hazelcast主题将继续提供需要在成员端执行的操作的信息。另外,这里的映射用作远程存储库的缓存。这是我能看到的信息。像Hazelcast这样的工具可以提供的另一个非常有用的洞察力是JMax控制台。有了JMax控制台,我们也——如果你想把我们的企业库存系统和JMax连接起来,看看集群的状态。我们可以从JMax上得到这些信息。例如,我可以看到这里的符号,这是另一个分布式并发控制原语,我可以看到这里有一个符号,它将被获取,如果索引是由主成员运行的。我可以看到主题的状态,例如,计算Debian在哪里。因为我没有在我的机器上运行任何Debian,所以没有数据,但是密封的数据是可用的。

一次又一次。好吧。这就是从人工HA的角度看它的样子。我会有几张幻灯片,上面有一些重要的内容,我可以回答一些问题。但是,我们今天所看到的。一些有趣的事情。这是我的清单,我通常在会议结束后做的事情。是的。不过我们没看猫的视频。我们看到了一些奇怪的东西。

好吧。现在。我们怎样才能让事情变得更好呢?分布式执行器服务用于分配作业。所以现在,人工HA依赖于成员。在主成员上做家务,比如运行索引,运行垃圾收集,等等。我们分发执行器服务,这是Hazelcast计算能力的一部分。它允许通过一组特定的键在特定节点上运行作业,或者在一组节点上运行作业。所以数据将是一个指针,任务将在哪里执行。目标事务或执行器服务的数据。

对于像Artifactory HA这样的系统,当它们进入无主模式时,另一个需要的选项是能够在其他成员上进行作业的故障转移,这也将在几周后发布的Hazelcast 3 - 7中实现。

执行原子数据通知的入口处理器。现在,人工HA依赖于日志,在这种情况下,在悲观日志的情况下,你总是需要在数据更新之前记录日志。入口处理器允许避免做悲观日志。它甚至没有被自己锁住。入口过程允许在没有任何日志或乐观和悲观日志的情况下对数据进行原子准备。虽然乐观API是可用的,但是像put[…]这样的操作在集群方面也是可用的。

以及用于云和自定义拓扑的Discovery SPI。所以现在,在我们实际在Artifactory中引入它之前,HA长期使用Hazelcast来实现这些目的。你在成员监听器中使用的一些东西和其他东西现在可以用Discovery SPI来完成这是它们所做的事情的标准实现。他们可以选择不同的实现,不同的方法,不同的云客户端,在本地编写等等。

我认为这是最重要的一张幻灯片。因此,您总是可以编写自己的集群软件。对吧?你可以一直这样写我们知道我们很多人都是非常精明的工程师我们这样做不是一次,可能是两次,三次。但是,你知道,它会把你从A点带到b点,对吧?它有两个轮子,你可以控制方向盘,你可以驾驶它,但是如果它不需要让你感到痛苦,或者你可以很好地享受它,那就不要去想那些事情。Artifactory HA的开发人员采取的务实的方法不是重新发明轮子或发明自行车,而是使用开源技术,将其构建在他们的产品中,并专注于对客户真正重要的事情。它是DevOps基础设施中工件的弹性、灾难恢复和可用性。现在我来回答一些问题。谢谢你的宝贵时间。

要么释放,要么死亡