点燃服务网格 - 重新启动

26 月 XNUMX 日,我们举办了 Apache Ignite GreenSource 聚会,开源项目的贡献者在会上发言 阿帕奇点燃。 这个社区生活中的一个重要事件是组件的重组 点燃服务网格,它允许您将自定义微服务直接部署到 Ignite 集群中。 他在聚会上谈到了这个艰难的过程 维亚切斯拉夫·达拉杜尔、软件工程师和 Apache Ignite 贡献者已有两年多。

点燃服务网格 - 重新启动

让我们从 Apache Ignite 的总体情况开始。 这是一个分布式键/值存储数据库,支持 SQL、事务性和缓存。 此外,Ignite 允许您将自定义服务直接部署到 Ignite 集群中。 开发人员可以访问 Ignite 提供的所有工具 - 分布式数据结构、消息传递、流媒体、计算和数据网格。 例如,当使用数据网格时,管理单独的数据存储基础设施的问题以及由此产生的管理费用就消失了。

点燃服务网格 - 重新启动

使用服务网格 API,您只需在配置中指定部署方案以及相应的服务本身即可部署服务。

通常,部署方案指示应在集群节点上部署的实例数量。 典型的部署方案有两种。 第一个是集群单例:在任何给定时间,保证用户服务的一个实例在集群中可用。 第二种是节点单例:在每个集群节点上部署一个服务实例。

点燃服务网格 - 重新启动

用户还可以指定整个集群中服务实例的数量,并定义谓词来过滤合适的节点。 在这种情况下,服务网格本身将计算部署服务的最佳分布。

此外,还有Affinity Service这样的功能。 亲和性是定义密钥与分区的关系以及拓扑中各方与节点的关系的函数。 通过该键,您可以确定存储数据的主节点。 通过这种方式,您可以将自己的服务与密钥和关联函数缓存相关联。 如果亲和函数发生变化,就会发生自动重新部署。 这样,服务将始终位于其需要操作的数据附近,从而减少访问信息的开销。 这种方案可以称为一种并置计算。

既然我们已经弄清楚了Service Grid的美妙之处,那么我们就来谈谈它的发展历史。

以前是什么

服务网格的先前实现基于 Ignite 的事务复制系统缓存。 Ignite 中的“缓存”一词指的是存储。 也就是说,这并不像您想象的那样是暂时的。 尽管缓存是复制的并且每个节点都包含整个数据集,但在缓存内部它具有分区表示。 这是由于存储优化所致。

点燃服务网格 - 重新启动

当用户想要部署服务时发生了什么?

  • 集群中的所有节点使用内置的连续查询机制订阅更新存储中的数据。
  • 发起节点在读提交事务下,在包含服务配置(包括序列化实例)的数据库中进行记录。
  • 当收到新条目的通知时,协调器根据配置计算分配。 结果对象被写回数据库。
  • 如果节点是分发的一部分,则协调器必须部署它。

什么不适合我们

在某些时候,我们得出结论:这不是使用服务的方式。 有几个原因。

如果部署过程中出现错误,那么只能从发生错误的节点的日志中找到。 只有异步部署,因此从部署方法将控制权返回给用户后,需要一些额外的时间来启动服务 - 在此期间用户无法控制任何事情。 为了进一步发展服务网格、创建新功能、吸引新用户并使每个人的生活更轻松,需要做出一些改变。

在设计新的服务网格时,我们首先希望提供同步部署的保证:一旦用户从API返回控制权,他就可以立即使用服务。 我还想赋予发起者处理部署错误的能力。

此外,我想简化实施,即摆脱交易和重新平衡。 尽管缓存是复制的并且没有平衡,但在具有许多节点的大型部署期间还是会出现问题。 当拓扑发生变化时,节点需要交换信息,并且在大型部署中,这些数据可能会很重。

当拓扑不稳定时,协调器需要重新计算服务的分配。 一般来说,当您必须在不稳定的拓扑上处理事务时,这可能会导致难以预测的错误。

问题

什么是没有伴随问题的全球变化? 第一个是拓扑结构的变化。 你需要明白,在任何时刻,甚至在服务部署的时刻,节点都可以进入或离开集群。 此外,如果在部署时节点加入集群,则需要一致地将有关服务的所有信息传输到新节点。 我们不仅讨论已经部署的内容,还讨论当前和未来的部署。

这只是可以收集在单独列表中的问题之一:

  • 如何在节点启动时部署静态配置的服务?
  • 从集群中离开节点 - 如果该节点托管服务该怎么办?
  • 如果协调员变更了怎么办?
  • 如果客户端重新连接集群怎么办?
  • 是否需要处理激活/停用请求以及如何处理?
  • 如果他们要求销毁缓存,而我们有与之相关的关联服务怎么办?

而这还不是全部。

作为目标,我们选择了事件驱动方法,使用消息实现流程通信。 Ignite 已经实现了两个允许节点在它们之间转发消息的组件 - communications-spi 和 discovery-spi。

点燃服务网格 - 重新启动

Communication-spi允许节点直接通信并转发消息。 它非常适合发送大量数据。 Discovery-spi 允许您向集群中的所有节点发送消息。 在标准实现中,这是使用环形拓扑来完成的。 还与 Zookeeper 集成,在本例中使用星形拓扑。 另一个值得注意的重要点是 discovery-spi 保证消息一定会以正确的顺序传递到所有节点。

让我们看一下部署协议。 所有用户的部署和取消部署请求均通过 discovery-spi 发送。 这给出了以下内容 保障:

  • 该请求将被集群中的所有节点接收。 这将允许请求在协调器更改时继续处理。 这也意味着在一条消息中,每个节点都将拥有所有必要的元数据,例如服务配置及其序列化实例。
  • 严格的消息传递顺序有助于解决配置冲突和竞争请求。
  • 由于节点进入拓扑也是通过 discovery-spi 处理的,因此新节点将接收使用服务所需的所有数据。

当收到请求时,集群中的节点会验证该请求并创建处理任务。 这些任务排队,然后由单独的工作人员在另一个线程中处理。 之所以以这种方式实现,是因为部署可能会花费大量时间,并且会严重延迟昂贵的发现流程。

来自队列的所有请求都由部署管理器处理。 它有一个特殊的工作人员从该队列中提取任务并初始化它以开始部署。 此后,将发生以下操作:

  1. 由于新的确定性分配函数,每个节点独立计算分布。
  2. 节点生成包含部署结果的消息并将其发送给协调器。
  3. 协调器聚合所有消息并生成整个部署过程的结果,该结果通过 discovery-spi 发送到集群中的所有节点。
  4. 收到结果后,部署过程结束,然后从队列中删除任务。

点燃服务网格 - 重新启动
新的事件驱动设计:org.apache.ignite.internal.processors.service.IgniteServiceProcessor.java

如果在部署期间发生错误,节点会立即将此错误包含在发送给协调器的消息中。 消息聚合后,协调器将获得有关部署期间所有错误的信息,并将通过 discovery-spi 发送此消息。 错误信息将在集群中的任何节点上可用。

服务网格中的所有重要事件均使用此操作算法进行处理。 例如,更改拓扑也是通过 discovery-spi 发送的消息。 总的来说,与以前的协议相比,该协议相当轻量且可靠。 足以应对部署期间的任何情况。

接下来会发生什么?

现在谈谈计划。 Ignite 项目的任何重大变更都是作为 Ignite 改进计划(称为 IEP)完成的。 服务网格重新设计还有一个 IEP - 个别化教育计划#17 带有嘲讽的标题“服务网格中的石油变化”。 但实际上,我们换的不是机油,而是整个发动机。

我们将 IEP 中的任务分为两个阶段。 第一个是主要阶段,包括重新设计部署协议。 它已经包含在 master 中,您可以尝试新的 Service Grid,它将出现在 2 版本中。 第二阶段包括许多其他任务:

  • 热重新部署
  • 服务版本控制
  • 提高容错能力
  • 瘦客户端
  • 用于监控和计算各种指标的工具

最后,我们可以为您提供关于服务网格的建议,以构建容错、高可用性的系统。 我们还邀请您访问我们的网站: 开发列表 и 用户列表 分享您的经验。 您的经验对于社区来说非常重要;它将帮助您了解下一步的发展方向,以及未来如何开发组件。

来源: habr.com

添加评论