Apache Ignite基线拓扑释疑

Stella981
• 阅读 720

Ignite项目刚开源时,它被定义为一种纯粹的内存解决方案:一种分布式缓存,可将数据放入内存以加快访问速度。但随后在2017年推出了Apache®Ignite™2.1版本,它首次发布了Ignite的原生持久化模块,让Ignite可以作为一个完整的分布式数据库。从那以后Ignite就不再依赖于外部持久性存储机制,以及随之而来的数据库配置和管理问题。

Ignite原生持久化支持分布式ACID并且兼容SQL,可以与Ignite的固化内存架构透明地集成。Ignite持久化是可选的,可以打开和关闭,关闭时,Ignite就是一个纯粹的内存存储。

不过用户也对Ignite的持久化模式产生了一些疑问,例如:“如何防止脑裂情况下难以处理的数据冲突?”,“如果节点故障实际上不会丢失数据,那么如果不做分区再平衡,是否可以继续?“,”如何自动执行比如集群激活这样的操作?“

这些问题都需要给予解答。

Ignite的基线拓扑是服务端节点的一个集合,用于同时在内存和Ignite持久化中存储数据。基线拓扑中的节点在功能方面没有限制,并且也作为常规的服务端节点,充当Ignite中数据和计算的容器。

如果启用了Ignite持久化,则必须要有基线拓扑,它表示集群中将数据保存到磁盘上的一组服务端节点。

通常,当集群在Ignite持久化启用后的首次启动时,集群处于非激活状态,不允许任何CRUD操作。比如,如果尝试执行SQL或键值操作,会抛出异常,如下图所示:

Apache Ignite基线拓扑释疑

这样做的目的是,在集群重启过程中,如果应用要修改还未加入集群、但是持有数据的节点上的数据时,避免可能出现的性能、可用性和一致性问题。因此需要为启用了Ignite持久化的集群定义基线拓扑,之后就可以手动或通过Ignite自动维护拓扑,下面会深入了解这个概念的细节,看看如何使用它。

基线拓扑:第一步

从概念上讲,内存模式集群是无状态的:没有专用节点,所有节点都是对等的,每个都可以被赋予缓存分区,获得计算任务,或者在其上部署服务。如果节点退出集群,则用户请求将由其它节点接管,并且已删除节点的数据将不再可用。

在持久化模式下,节点即使在重启后仍保持有状态,在启动期间,节点会从磁盘读取数据,并恢复状态。因此,节点的重新加载不需要从其它集群节点进行数据复制(也称为再平衡),在故障发生时存在于集群中的数据也将从本地磁盘恢复。

基线拓扑是将有状态的节点集(可在重启后恢复)与其它节点区分开来的机制,基线拓扑(后续称为“BLT”)其实就是配置了数据存储的节点标识符的集合。

持久化的数据:冲突保护

分布式系统的脑裂问题已经很难处理,但是在开启持久化的背景下变得更为危险,考虑一个简单的场景,比如有一个集群和一个复制缓存,然后执行以下操作:

  • 停止集群然后启动一个叫做子集A的子集群;
  • 更新缓存中的部分数据;
  • 停止该子集然后启动子集B;
  • 对同样的键执行其它一些更新操作。

Apache Ignite基线拓扑释疑

因为Ignite工作于数据库模式,所以在第二个子集的节点被搁置后,更新不会丢失,如果我们再次运行第二个子集,这个数据仍然有效,恢复初始集群后,不同的节点可以包含相同键的不同值。

只是通过停止和运行节点,集群中的数据就已经处于未定义状态,这是不可能自动解决的,需要BLT来防止这种情况。

这个想法就是,在持久化模式下,集群需要另一个阶段:激活。

在第一次激活期间,在磁盘上创建并保存了第一个基线拓扑,其中包含了激活时集群中存在的每个节点的信息。

此数据还包括根据在线节点的ID计算的哈希值。如果在下次激活期间拓扑缺少某些节点(例如集群重新加载并且一个节点停止服务),则将再次计算哈希值,并将之前的值保存在相同BLT的激活历史记录中。

因此,基线拓扑维护了一个哈希链,描述了每次激活后的集群构成。

在阶段1和阶段3,启动节点子集后,需要激活不完整的集群,然后每个在线节点将在本地更新BLT,即向其中添加新的哈希。每个子集的所有节点都可以计算相同的哈希,但不同子集的哈希值会不同。

这时可能会猜到以下内容:如果某个节点尝试加入其它的组,则系统会认为其在该组之外已被激活,并且将拒绝访问。

但是要注意,这种验证机制不会对脑裂场景中的冲突提供绝对保护。如果集群分成两半,例如每半部分至少保留一个分区的副本,并且这一半没有重新激活,可能会遇到每一半都发生相同数据冲突变化的情况。BLT与CAP定理不冲突,但通过显式管理错误保护用户免受冲突。

好处

除了防止冲突,BLT还可以增强一些很好的兼容性。

好处1:少一个手动动作。应在每次集群重启后手动完成上述激活; 没有“开箱即用”的自动化解决方案。使用BLT,集群可以独立决定是否需要激活。

虽然Ignite集群是一个弹性系统,可以自动添加或删除节点。BLT基于此,在数据库模式下,帮助用户维护稳定的集群配置。

Apache Ignite基线拓扑释疑

首次激活集群时,新组成的基线拓扑会记住拓扑中应存在哪些节点。重新启动后,每个节点都会检查其它BLT节点的状态,一旦所有节点进入在线状态,集群将自动激活。

好处2:更节省网络资源。当然,这个想法建立在拓扑结构长期保持稳定的前提下。在BLT之前,如果节点从拓扑中退出哪怕10分钟,都会导致缓存分区再平衡以维持足够的备份。但是,如果节点几分钟内就能恢复,为什么要花费网络资源并拖慢整个集群的速度?基线拓扑就可以对这种情况进行优化。

集群默认会假定故障节点将很快恢复,此时间段内,某些缓存可以使用较少的备份,但不会导致服务减慢或停止。

管理基线拓扑

因此就可以知道,基线拓扑由第一次集群激活时自动配置,激活之后,在BLT中就持有了所有在线的服务端节点。

手工BLT管理是通过Ignite发行版的控制脚本实现的,相关的详细说明请参见这个文档

该脚本暴露了一个非常简单的API,仅支持三种操作:添加节点删除节点配置新的基线拓扑

虽然添加节点是一个相对简单的操作而没有重大风险,但是从BLT中删除节点就是一项更复杂的任务。在生产环境下执行此操作可能会导致竞争,即在最糟糕的情况下,整个集群可能会无响应。因此删除需要满足一个条件:要删除的节点必须处于离线状态,如果尝试删除在线节点,脚本将抛出异常从而终止。

从BLT中删除节点时,还需要手工执行一项操作:停止此节点。因为这种情况不常见,所以这点额外的工作也可以忽略不计。

用于BLT管理的Java接口甚至更简单:它只公开了一个方法,基于一个节点列表配置基线拓扑。

结论

维护数据的完整性工作必不可少,必须在任何数据存储中解决。关于分布式关系数据库,尤其是Ignite,这个任务变得更具挑战性,考虑一些实际的、数据完整性可能被破坏的场景,基线拓扑会提供很多的帮助。

Ignite还对性能高度重视,BLT还有助于显着节省资源并缩短系统响应时间。

原生持久化功能最近才实现,必将不断发展,变得更强大、更高效、更易于使用,而基线拓扑概念也会随之不断演变。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
翼
3年前
js 数组 转为树形结构
需要转换为树形的数组vardata{"orderById":null,"platformCommissionProportion":1,"name":"添加剂","pid":13,"id":26
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
8个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这