从本篇开始,我们会陆续通过 2-3 篇文章介绍 Apache Ignite 的核心功能特性,有价值的功能点非常多,所以每个点写的并不详细,这几篇文章主要目的还是方便更多的人更全面的了解它,后续的话,可能会针对某个功能点做详细的说明。
一、数据网格
Ignite 内存数据网格是一个内存内的键值存储,他可以在分布式集群的内存内缓存数据。
它通过强语义的数据位置和关系数据路由,来降低冗余数据的噪声,使其可以节点数的线性增长,直至上千个节点。
Ignite 数据网格速度足够快,经过官方不断的测试,目前,他是分布式集群中支持事务性或原子性数据的最快的实现之一。
特性一览:
1. 键值存储
Ignite 数据网格是一个内存内的键值存储,可以视为分布式的分区后的哈希,集群中每个节点都持有所有数据的一部分,这意味着集群内节点越多,就可以缓存越多的数据。
重要通知:接下来 InfoQ 将会选择性地将部分优秀内容首发在微信公众号中,欢迎关注 InfoQ 微信公众号第一时间阅读精品内容。
和其他键值存储不同,Ignite 通过可插拔的哈选算法来决定数据的位置,每个客户端都可以通过插入一个自定义的哈希函数来决定一个键属于那个节点,并不需要任何特殊的映射服务或者命名节点。
2.JCache(JSR107)
Ignite 100% 兼容于 JCache(JSR107)规范,JCache 为数据缓存提供了非常简单,但是功能又非常强大的 API。
JCache 的一部分 API 包括:
- 基本缓存操作
- ConcurrentMap APIs
- 并行处理(EntryProcessor)
- 事件和度量
- 可插拔的持久化
3. 分区和复制
根据配置,Ignite 可以对内存内的数据进行分区和复制,和 REPLICATED 模式不同,数据是在集群内的所有节点中全复制的,在 PARTITIONED 模式中,数据是在集群内的多个节点中平均拆分的,允许在内存内缓存 TB 级的数据。
Ignite 也可以配置成具有多个副本,来保证故障时的数据弹性。
不管使用那种缓存模式,Ignite 都保证任何故障模式下跨所有集群节点的数据一致性。
4. 自修复集群
Ignite 集群可以自我修复,故障时客户端会自动重连,慢的客户端会被自动踢出,故障节点的数据也会被自动传播到网格内的其他节点。
5. 客户端近缓存
当数据被远程客户端访问时,Ignite 也支持客户端侧的近缓存,在事务模式下,近缓存中的数据仍然是事务性的,要么是自动更新,要么是以一直的方式更新事务提交无效。
6.ACID 事务
Ignite 支持 2 种模式的缓存操作,事务性和原子性,事务模式下,可以事务性的将多个缓存操作作为一组,而原子模式下支持多个原子操作,一次一个。原子模式更轻量通常比事务模式缓存具有更好的性能。
事务模式下 Ignite 支持乐观事务和悲观事务,使用了尽可能经过一阶段提交优化后的 2 阶段提交协议。
7. 查询和分布式关联
Ignite 提供了非常优雅的查询 API,支持:
- 基于谓词的扫描查询
- SQL 查询(ANSI 99)
- 文本查询
对于 SQL 和文本查询,Ignite 提供了内存内的索引,因此所有的数据查询都是非常快的,如果在堆外内存缓存数据,查询索引也会在堆外内存中。
Ignite 也允许用户使用可插拔的 IndexingSpi 来定制自己的索引。
8. 持续查询
持续查询对于当执行一个查询后又想持续的获得之前的查询结果的数据更新通知时,是非常有用的。
9. 堆内和堆外内存
Ignite 支持 2 种模式缓存内存内的数据,堆内和堆外,堆外内存允许当堆太大时将数据存储在主 Java 堆空间之外,来避免 JVM 垃圾回收时导致的暂停,但是数据仍然在内存中。
只要配置了堆外内存,Ignite 同时也会在堆外存储索引,这意味着索引不会占用任何堆内内存空间。
10. 分层内存
当数据访问率下降时,ignite 会有选择的将数据从堆内内存迁移至堆外内存,甚至从堆外内存迁移至交换(磁盘)存储。
当这部分数据又被访问时,他会立即被迁移到顶层,同时将其他的访问率低的数据迁移到更低的下一个内存层。
11.JDBC 驱动
Ignite 同时提供 JDBC 驱动,允许用户使用标准 SQL 查询和 JDBC API 获得缓存内的分布式数据。
Ignite 允许用户使用任何标准 SQL 工具连接至 Ignite 然后在 Ignite 缓存的内存数据中开始执行 SQL 查询。
12.Web Session 集群化
Ignite 数据网格能够缓存任何支持 Java Servlet3.0 规范的的应用服务器的 Web Session,包括 Apache Tomcat,Eclipse Jetty,Oracle WebLogic 以及其他。
当运行应用服务器集群时缓存 Web Session 对于提高 Servlet 容器的性能以及可扩展性是非常有用的。
13.Hibernate 二级缓存
Ignite 可以作为 Hibernate 的二级缓存,他可以显著的提高应用中持久化层的速度。
14.Spring 缓存
Ignite 支持基于 Spring 注解方式的 Java 方法缓存,这样的话,一个方法的执行结果就可以缓存在 Ignite 缓存中。以后如果同一个方法通过同样的参数集进行调用,结果会直接从缓存中获取而不是实际执行这个方法。
二、计算网格
分布式计算是通过并行处理的方式来获得更高的性能,更低的延迟以及线性可扩展性,Ignite 计算网格提供了一组简单的 API 来允许用户在集群内的多台计算机中执行分布式计算和数据处理。
分布式计算是基于在集群内的节点中进行任何的计算然后将结果返回的能力。
特性一览:
1. 分布式闭包执行
Ignite 计算网格允许对集群内的任何闭包进行广播和负载平衡,包括 Java8 lambda,还包括纯 Java Runnables 和 Callables。
2.ForkJoin 执行
ComputeTask 是 Ignite 对内存内 ForkJoin 的抽象和范式,也是 MapReduce 的一个轻量级形式,纯 MapReduce 并不是为了性能而构建,只是善于进行离线数据的批量处理(比如 Hadoop MapReduce)。
然而,对驻留在内存的数据进行计算时,实时性,低延迟和高吞吐量通常具有很高的优先级,同时,简化 API 也非常重要。基于这些考虑,Ignite 提供了 ComputeTask API, 这个就是 Ignite 的 ForkJoin 实现(轻量级 MapReduce)。
3. 集群化 ExecutorService
Ignite 提供了一个标准 JDK 中 ExecutorService 的集群实现,他会自动地在集群内以负载平衡的模式执行所有的计算。计算也会容错并且只要有一个节点就能保证执行,你可以把他视为集群化的分布式的线程池。
4. 计算和数据的搭配
计算和数据的搭配可以使网络中数据序列化最小化,并且可以显著的提高应用的性能和可扩展性。不管何时,都要尽量做好集群节点中缓存的待处理数据和计算的搭配。
Ignite 根据需要,可以提供多种方式自动或者手动地进行计算和数据的搭配。
5. 容错
Ignite 支持自动作业故障切换。如果一个节点崩溃或其他错误,作业会自动转移到其他可用节点重新执行。可插拔的 FailoverSpi 负责进行执行一个故障任务时新节点的选择。
至少一次保证:Ignite 保证只要有一个节点存在,任务就不会丢失。
6. 负载均衡
负载平衡组件负责平衡集群内各节点的分布式任务。Ignite 中负载平衡是通过可插拔的 LoadBalancingSpi 实现的,它控制集群内所有节点的负载并且确保集群内的每个节点的均衡负载。
对于同质化环境中的同质化任务,负载平衡是通过随机或者循环的策略实现的。然而,在很多其他的场景中,特别是在负荷不均衡时,他提供了很多的更复杂的自适应的负载平衡策略。
7. 任务检查点
检查点是通过可插拔的 CheckpointSpi 实现的,他提供了一个保存作业中间状态的功能,检查点对于长期执行的任务需要保存一些中间状态以防止节点故障是非常有用的。当一个故障节点重启时,一个作业可以载入一个保存的检查点然后从故障处继续执行。
8. 作业调度
可插拔的 CollisionSpi 对于待执行的作业到达某个节点时如何进行调度提供了细粒度的控制。他提供了很多的策略,包括:FIFO,优先级甚至磨洋工。
三、流式计算和 CEP
Ignite 流式计算允许以可扩展和容错的方式处理连续的、无止境的数据流。在一个中等规模的集群中,数据注入 Ignite 的比例会很高,很容易达到每秒百万级的规模。
工作方式:
- 客户端将流式数据注入 Ignite;
- 数据在 Ignite 数据节点中自动分区;
- 数据在滑动窗口中并发处理;
- 客户端在流式数据中执行并发 SQL 查询;
- 客户端订阅数据变化的持续查询。
特性一览;
1. 数据流处理器
数据流处理器是由 IgniteDataStreamer API 定义的,他是为了将大量的持续数据流注入 Ignite 流缓存而构建的。数据流处理器以可扩展和容错的方式,为所有数据流注入 ignite 提供了至少一次保证。
2. 并行处理
当你需要执行自己的业务逻辑而不仅仅是添加新数据时,就需要利用 StreamRecerver API 的优势了。
流接收器允许直接在缓存数据的节点上以并行的方式处理数据流,在数据进入缓存之前可以修改数据或者添加任何自定义预处理逻辑,
3. 滑动窗口
Ignite 流功能允许在数据滑动窗口内进行查询。滑动窗口被配置为 Ignite 的缓存抽取策略,可以基于时间、基于大小或者基于批量处理,可以配置一个缓存一个数据窗口,如果你需要同一个数据具有不同的滑动窗口的话,也可以非常容易的为同一个数据定义不止一个缓存。
4. 滑动窗口查询
可以使用所有的 Ignite 数据索引功能,再加上 Ignite SQL、TEXT,以及基于谓词的缓存查询,在数据流中进行查询。
5. 持续查询
持续查询对于当执行一个查询后又想持续的获得之前的查询结果的数据更新通知时,是非常有用的。
四、分布式数据结构
Ignite 以分布式的形式支持基于 java.util.concurrent 框架的大部分数据结构。比如,可以在一个节点上使用 java.util.concurrent.BlockingQeque 加入一些东西,然后再另一个节点上获取它。或者有一个分布式的 ID 生成器,他可以保证所有节点上的 ID 唯一性。
支持的数据结构包括:
- Concurrent Map (Cache)
- Distributed Queues and Sets
- AtomicLong
- AtomicReference
- AtomicSequence (ID Generator)
- CountDownLatch
特性一览:
1. 并行和非并行
队列和集合可以以并行或者非并行的方式进行部署。在并行模式中,集合中的所有元素都会驻留在同一个集群节点上。这种模式下,应该使用相对较小的集合。在非并行模式下,集合的元素会均等地分布在集群内,这就允许在内存内保存很大的集合。
2. 有界队列
有界队列允许用户持有一个有预定义最大值的队列,这将有助于控制整个缓存的容量。
3. 基于预留的 ID 生成器
ID 生成器是通过 AtomicSequence 实现的,当你以原子序列执行 incrementAndGet()(或任何其他的原子性操作)时,数据结构会保存未来值的范围,这会保证跨集群内该序列实例的唯一性。
直到所有保存的值都被使用了,所有的序列增长操作都会发生在客户端本地。
五、分布式消息
Ignite 提供了集群范围内的高性能的消息功能,支持基于发布 - 订阅以及直接点对点通信模型的数据交换。消息可以以有序的,也可以以无序的方式进行交换。
特性一览:
1. 有序和无序
Ignite 支持有序的以及无序的消息,有序消息要稍微慢一点,但是如果你用的话,Ignite 保证收到消息的顺序和发送消息的顺序一致。
2. 主题和点对点
Ignite 消息支持基于主题的订阅,主题消息可以发送给一组节点,也可以发送给某一个节点。
六、服务网格
服务网格允许用户在集群中任意部署自定义的服务,比如自定义计数器,ID 生成器,分级映射等。
服务网格的主要应用场景是提供了在集群中部署各种单例服务的能力。但是,如果你需要一个服务的多实例,Ignite 也能保证所有服务实例的正确部署和容错。
特性一览:
1. 用户定义服务
用户可以定义自己的服务并且 Ignite 会自动在集群内进行服务的分布化。比如,你可以创建自己特定的分布式计数器,或者自定义的数据加载服务,或者任何其他逻辑,然后将其部署到集群中。
2. 集群单例
Ignite 允许将任意数量的服务部署到网各节点,然而,最经常被使用的特性是在集群中部署单例服务,不管是拓扑变更还是节点故障,Ignite 都会维护单一性。
3. 容错
Ignite 会保证服务的持续有效,以及按照指定的配置进行部署,不管是拓扑变更还是节点故障。
4. 负载平衡
在所有的情况下,不只是单例服务部署,Ignite 都会自动地确保在集群内的每个节点上部署大致数量相等的服务。当集群拓扑发生变化时,Ignite 会对部署的服务进行重新评估,然后可能对已经部署的服务重新在其他节点上部署以保证更好的负载平衡。
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论 1 条评论