开源IMDG之GridGain
最后更新于:2022-04-01 20:33:18
作为另一款主流的开源数据网格产品,GridGain是Hazelcast的强有力竞争者。同样提供了社区版和商业版,近日GridGain的开源版本已经进入[Apache孵化器项目Ignite](http://ignite.incubator.apache.org/)(一款开源的内存计算(In-Memory Computing)IMC中间件),目前Apache正在迁移GridGain开源版本的代码到Ignite项目。鉴于经过之前Hazelcast的介绍已经对数据网格产品有了一定了解,本文着重介绍GridGain与Hazelcast差异化之处。
### 1 重叠功能列举
上面简单列举了一些Hazelcast和GridGain的重叠功能,而两者的差异之处主要在于以下几个方面:
Ø 整体功能的全面性:围绕内存计算提供的**功能**。
Ø 使用性:对**SQL支持**的完整性、对**Continuous Query**的支持、以及与持久化存储的**数据集成**。
Ø 性能:免费的**off-heap存储**实现。
Ø 可靠性方面:**事务**的隔离性、内存**溢出到磁盘**。
Ø 管理:提供强大的**后台管理界面**。
此外,企业版还提供了Portable跨平台对象、安全和审计、数据中心复制、可还原的本地cache以及split-brain网络分段问题解决等功能。本文暂不关注企业版中的附加功能,下面开始着重介绍上面列举的开源社区版与Hazelcast的功能差异。
### 2 全面的内存计算功能栈
从整体功能上来说,GridGain是个出色的多面手,不仅可以完成本职工作-内存计算/数据网格,还提供了:
1) GGFS(GridGain In-Memory File System),类似Spark生态圈中的Tachyon,能够加速MapReduce任务的执行。
2) 完整的ACID和事务支持,可以作为内存数据库。
3) 流式数据/事件处理,可以作为CEP事件处理器。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13ce3880.jpg)
![](image/d41d8cd98f00b204e9800998ecf8427e.jpg)
### 3 丰富的查询功能
一般开源IMDG产品支持基本的对象过滤查询能力,但GridGain底层借助H2数据库引擎来解析和执行SQL,所以支持复杂的对象联结查询,类似于GemFire中的OQL提供的功能,以及仅在Hazelcast商业版本中才支持的Continuous Query功能。
首先来看一下我们的测试数据和Entity是什么样子,代码忽略了构造函数、getter/setter和toString等方法。Person中包含了id、name、salary三个基本属性,并与Organization是多对一的关系,与Address是一对一的关系。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d03c3b.jpg)
对于POJO要注意几点:1)查询中涉及的成员变量都要标上**@GridCacheQuerySqlField**注解;2)因为POJO会被哈希到其他结点上的分区,所以要实现**序列化接口**;3)下面例子只测试了**one-to-one**(直接嵌套实体Address)、**many-to-one**(通过orgId关联其他实体)关系的查询,而没有尝试one-to-many和many-to-many(都是在实体中嵌套另一实体id的集合);4)GridCacheConfiguration要开启**setQueryIndexEnabled(true)**。
#### 3.1 简单的过滤查询
简单的对象过滤查询是最常见的,也是其他网格产品像Hazelcast支持的。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d176e5.jpg)
#### 3.2 同cache下的join查询
同cache下可能会关联的数据,可以通过数据亲和性设置使相关数据分配到同一分区中,从而避免网络传输开销。当然,Hazelcast也是支持数据亲和性的,本节关注的重点是join查询。代码类似于3.3中的跨cache查询,差别只不过是:1)Organization对象不是保存到org-cache,而是与Person对象一起保存到person-cache;2)SQL中不需要显式指明缓存名称,因为对象都在一个缓存person-cache中。
#### 3.3 跨cache的join查询
~~被join的cache(org-cache)必须是REPLICATE的,从而在各个结点上都存在,不会产生交叉join。~~(注:Impala支持这种join,将产生N*M次数据通信)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d2a509.jpg)
#### 3.4 字段查询
GridGain不仅支持查询结果为实体,同时也支持各种SQL函数对实体进行各种操作,如聚合、字符串操作等。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d3f995.jpg)
#### 3.5 Continuous查询
Continuous查询不支持SQL,只支持Predicate风格组装查询。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d52f00.jpg)
执行效果如下,首先初始化到缓存中的Person对象中有一个salary=300,满足条件,所以本地callback收到通知。之后我们试着更新缓存中的一个Person对象的salary=250,于是再次收到通知。最后我们新建一个Person,salary=500,并保存到缓存中,于是再次收到通知。这就是Continuous Query的运行效果。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d685d7.jpg)
### 4 集成持久化存储
类似Hazelcast,GridGain也提供了**read-through**、**write-through**以及异步**write-behind**三种与后端持久化存储通信的方式。此外,GridGain还支持事务提交时批量write,以及缓存entry**即将过期时**自动重新re-cache(**refresh-ahead**)功能。像refresh-ahead功能在GemFire等商业产品中才会实现。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d7a5c9.jpg)
### 5 堆外内存存储
不像Hazelcast等开源产品只在商业版中提供off-heap存储功能,GridGain在开源版本中就提供了此功能,从而显著地扩充JVM管理的内存容量,并减轻GC压力和停顿时间。GridGain提供了*ONHEAP_TIERED*(**默认堆优先,溢出到非堆内存**)、*OFFHEAP_TIERED*(不使用堆,直接将所有entry放入非堆内存)、*OFFHEAP_VALUES*(将key存储在堆,value存储在非堆内存)三种模式。当堆和非堆内存都不足时,还可以开启SWAP,将数据溢出到磁盘(详见第7部分:数据溢出到磁盘)。下图表示了堆、非堆、磁盘、外围存储的容量和延迟的关系。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13d9d9f6.jpg)
### 6 完整的ACID和事务支持
内存事务与传统数据库事务有一点点不同。因为IMDG产品使用的是易逝内存,所以故障或断电时内存数据会全部丢失。一般IMDG重启时会从备份结点或其他持久化存储中恢复数据。但这不代表内存事务不重要!只要集群是存活的,GridGain就要保证不同结点间的数据一致性。为此,GridGain提供了两种*TRANSACTIONAL*和*ATOMIC*两种配置:
Ø **TRANSACTIONAL**:完整的ACID属性的事务,以及显式的锁。
Ø **ATOMIC**:没有事务和锁。
GridGain使用**2PC(两阶段提交)协议**实现分布式事务,同时支持**乐观**和**悲观**两种模式。乐观模式下所有key在提交时才会加锁,所以在Prepare阶段,prepare消息发送给各结点获取事务中将要操作的key的锁,各结点通过ACK消息应答。而悲观模式下,所有key在提交前就已加锁,所以Prepare阶段不需要做任何事。在Commit阶段,commit消息发送给各结点提交,若失败则发送回滚消息给各结点。可以设置各个结点之间是同步还是异步提交(注:Hazelcast支持一种**2PC扩展协议**,具体的优势还有待研究)。最后,GridGain支持*READ_COMMITTED*,*REPEATABLE_READ*和*SERIALIZABLE*三种事务隔离级别,默认是REPEATABLE_READ。而Hazelcast只支持REPEATABLE_READ一种。
### 7 数据溢出到磁盘
在第5部分堆外内存存储中提到过GridGain的层次化存储,以下面的缓存配置为例,它同时开启了off-heap和swap。1)首先,数据优先保存在堆内存中。2)当entry总数超过100个时,会通过LRU淘汰到非堆内存中。3)当超过非堆内存的最大容量5MB时,会将多出的数据保存在磁盘上。当然,磁盘IO操作的代价是很大,我们可以优先考虑使用超大的**非堆内存**,或者使用**SSD闪存**,以及开启操作系统的**磁盘IO缓存**来进行优化。
GridCacheConfiguration cacheCfg = new GridCacheConfiguration();
cacheCfg.setEvictionPolicy(new GridCacheLruEvictionPolicy(**100**));
cacheCfg.setOffHeapMaxMemory(**5 * 1024L * 1024L**);
cacheCfg.setSwapEnabled(**true**);
### 8 强大的管理界面
首先,以相同配置启动三个GridGain实例。然后,启动gridgain-fabric-os-6.5.5/bin/ ggvisorui.exe,在Visor GUI中选择File->Connect->External标签页下,直接localhost+默认端口连接即可进入Dashboard。在这能看到我们刚刚启动的三个结点的总体信息。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13dbb9c9.jpg)
点击Data Grid标签页,可以查看各个cache的内存使用、读写以及命中情况,例如我们初始化了3个Person和2个Organization对象,并分别保存到了person-cache和org-cache中,于是我们可以在此标签页看到Primary Entry和Write个数都是3和2。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-31_57c6b13dd35c7.jpg)
';
比较 | Hazelcast | GridGain | |
使用性 | 安装 | Maven引入Jar包即可,无需安装软件 | |
客户端 | 支持各种语言的客户端 | ||
框架集成 | 集成Hibernate、Web Session、Spring | ||
基本功能 | 分布式计算工具 | 分布式的集合、并发包、消息队列、调度器 | |
性能 | 性能配置 | 内存索引、Near-Cache、数据亲和性 | |
可靠性 | 数据备份 | 分区数据冗余备份 | |
持久化 | read-through,write-through/behind | ||
事务 | 保证数据一致性 | ||
扩展性 | 自动分区 | 支持本地、分区、复制三种方式 | |
动态拓扑 | 动态添加删除结点,自动rebalance |