Ignite是一个功能强大的分布式缓存框架,相比Redis更复杂、可阅资料少、学习成本高,本文旨在帮助读者快速入门。

Apache Ignite是一个分布式数据库,支持以内存级的速度进行高性能计算。Ignite所支持的编程语言主要包括:Java、C#以及C++,其中Java版本的对应API是最丰富的。

时下最主流的分布式数据库应当是Redis,然而某些情况下我们的项目可能无法使用Redis进行开发。例如:由于Redis的底层是使用C语言实现的,而Ignite的底层则是使用Java语言实现,因此如果我们所在公司的云环境不支持C语言环境那么就无法对Redis进行部署。此时,我们可以考虑使用Ignite作为Redis的取代方案。

与Redis相比,Ignite由于也是内存数据库因而同样具有很高的计算效率,且也支持Redis这种Key-Value的存储形式。Ignite中缓存的Key和Value都是Object类型的对象,相比Redis而言更加灵活,可以支持更多用户自定义的数据类型,而Redis则受限于其所提供的String、Hash、Set等数据类型。

除了具有相似的K-V缓存结构,Ignite还有很多优于Redis的特性,例如:Ignite完全兼容JCache缓存规范而Redis不支持、Ignite完全支持ACID事务而Redis只能提供部分支持、Ignite支持缓存数据的全复制而Redis不支持。

本章节以主流的Java Maven项目为例,对Ignite的简单部署和使用进行示例说明。

Maven项目当中,Ignite的部署十分简单,不需要再单独下载安装包然后通过终端命令行的方式启动节点。只需要在项目的pom.xml中添加Ignite的依赖坐标,即可成功对其实现引入。

值得注意的是,如果项目或子项目的pom.xml文件中引用了h2内存数据库的相关依赖,那么必须将其版本覆盖为2.14.197,否则Ignite会报启动错误,这是因为Ignite的jar包中所引入的h2版本是2.14.197,因此如果不一致就会导致版本冲突,进而导致Ignite节点启动失败。

其中,最基本的配置就是设置当前Ignite服务器节点(自己)所连接的IP地址。Ignite节点之间的网络通信主要是通过TCP协议实现的,其默认端口是47500。

TcpDiscoveryVmIpFinder是静态的IP发现器,可以指定一组IP地址和端口,IP发现器将检查这些IP地址和端口以进行节点发现。一旦建立了与提供的任何IP地址的连接,Ignite就会自动发现所有其它节点。

Ignite节点的启动是通过Ignition.start方法触发的,在对Ignite的节点完成配置后就可以调用该方法启动一个Ignite节点。在启动时Ignite会将为节点分配为服务端节点或客户端节点,如果不进行设置,Ignite节点将自动作为服务端节点启动。

Ignite客户端节点的启动和服务端节点的代码几乎完全一样,由于Ignite节点默认以服务端模式启动,因此只需要手动地将Ignite设置为客户端节点即可。

上图中,“servers=1,clients=1”表示当前存在1个服务端节点以及1个客户端节点。

在通过简单的Java程序实例对Ignite服务端节点和客户端节点的部署连接进行示例说明后,再简要地对Ignite的集群特性进行介绍。

Ignite的节点可以分为服务端节点和客户端节点两种类型。服务端节点是Ignite集群的主体,主要的作用是存储数据、执行计算任务等,而客户端节点只是作为常规节点加入集群,但并不对数据进行存储。

通常情况下,本地开发时我们可以使用基于组播或静态的IP发现,但公司项目一般部署在云环境,IP地址并不能保证固定不变,可能会由于容器故障重启或其他不可控原因而动态变化,因此3.2节中的IP发现方式就会失效。Ignite为这种类似的应用场景提供了一种很便捷的SPI:基于JDBC数据库的IP发现机制。

客户端程序和服务端几乎是一模一样的,2.3节所述,区别仅在于客户端程序员需要显式地调用IgniteConfiguration.setClientMode(true)方法让Ignite节点以客户端的模式启动。

在对Ignite的简单部署和Ignite集群的相关特性有了简单了解后,我们通过一些简单的实例来对Ignite的缓存进行示例说明。

前文中,由于只是简单地启动了Ignite节点,并未进行缓存操作,因此并未对Ignition.start的返回值进行获取。当我们要进行缓存相关操作时,需要获取start方法所返回的Ignite实例,通过对该实例对象的调用以实现缓存的相关操作。

调用createCache时,如果缓存已经存在则会创建失败,具体判断缓存是否存在是根据缓存的名字实现的,每个IgniteCache都有一个缓存名CacheName,我们所传入的字符串s会被当作cacheName进行创建缓存实例。

除了字符串外,创建缓存时的参数也可以是CacheConfiguration类型的对象,其K和V表示的是缓存的Key和Value的类型。CacheConfiguration的setName方法可以设置Ignite缓存的名称,效果等同于createCache(String s),因此如果像下图这样创建缓存就会创建失败,因为两个缓存的名称都叫做“name”。

启动Ignite客户端程序,IDEA控制台输出如下错误,可见Ignite是通过缓存的name字段判断缓存是否冲突的。

Ignite缓存的写入主要通过put方法实现,键值均是Object类对象,既可以是Java原生对象,也可以是自定义的类对象。除此之外,也可以通过putAll一次性存入多个键值对。带Async后缀的方法则是异步实现,带IfAbsent的方法表示不存在时存入数据,getAndPut则会获取所写入的缓存数据。

Ignite缓存的读取主要通过get方法实现,通过传入key来获取value。除此之外,也可以通过getAll传入一个key的Set集合,一次性获取Set集合中所有key多对应的多个key-value键值对。

在对Ignite的部署、集群、缓存基本操作有了一定程度的了解后,我们通过Spring Cloud微服务来实现一个Ignite模拟Redis的小项目案例,加深读者对Ignite的应用理解。

由于Ignite缓存是Object类型,因此我们通过定义一个常量类型作为缓存名来对

缓存进行分类,例如String类型的缓存所传入的缓存名称则为String,Hash类的

不需要以微服务的注。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注