Apache Ignite缓存基本操作

这段内容主要讲解了 Apache Ignite 中缓存(IgniteCache)的基本操作,包括获取缓存、创建缓存、销毁缓存、执行原子操作以及异步操作等。下面我将用中文对这些内容进行详细解释,帮助你更好地理解。


一、获取缓存实例(Getting an Instance of a Cache)

所有对缓存的操作都必须通过 IgniteCache 实例来完成。你可以获取一个已经存在的缓存,或者动态创建一个新缓存。

示例代码:

java 复制代码
Ignite ignite = Ignition.ignite();

// 获取名为 "myCache" 的缓存实例
IgniteCache<Integer, String> cache = ignite.cache("myCache");

⚠️ 注意:不同缓存的泛型类型可能不同,比如 IgniteCache<Integer, String>IgniteCache<String, Person> 是不同的类型。


二、动态创建缓存(Creating Caches Dynamically)

你也可以在运行时动态创建一个缓存,使用 getOrCreateCache() 方法。如果缓存已经存在,就直接返回;如果不存在,就根据配置创建。

示例代码:

java 复制代码
CacheConfiguration<Integer, String> cfg = new CacheConfiguration<>();
cfg.setName("myNewCache");
cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);

IgniteCache<Integer, String> cache = ignite.getOrCreateCache(cfg);

配置说明:

  • setName(...):设置缓存名称。
  • setAtomicityMode(...):设置缓存的原子性模式(例如 TRANSACTIONALATOMIC)。
  • 还可以设置很多其他参数,比如备份数量、缓存模式(分区/复制)等。

注意事项:

  • 如果在集群拓扑发生变化(如节点加入或退出)时调用 getOrCreateCache(),可能会抛出异常:

    java 复制代码
    javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: Failed to start/stop cache, cluster state change is in progress.
  • 遇到这个异常时,建议稍后重试。


三、销毁缓存(Destroying Caches)

使用 destroy() 方法可以从整个集群中删除一个缓存。

示例代码:

java 复制代码
Ignite ignite = Ignition.ignite();
IgniteCache<Long, String> cache = ignite.cache("myCache");
cache.destroy();  // 删除名为 "myCache" 的缓存

⚠️ 注意:此操作是不可逆的,会删除所有节点上的缓存数据和配置。


四、基本原子操作(Basic Atomic Operations)

获取到缓存后,可以进行常见的 putgetremove 等操作。

示例代码:

java 复制代码
IgniteCache<Integer, String> cache = ignite.cache("myCache");

// 存入数据
for (int i = 0; i < 10; i++) {
    cache.put(i, Integer.toString(i));
}

// 获取数据
for (int i = 0; i < 10; i++) {
    System.out.println("Got [key=" + i + ", val=" + cache.get(i) + ']');
}

批量操作注意事项:

  • 使用 putAll()removeAll() 等批量操作时,是作为一系列原子操作执行的。
  • 如果部分操作失败,会抛出 CachePartialUpdateException,并包含失败的 key 列表。
  • 如果希望批量操作作为一个整体完成,建议使用 事务

五、条件更新操作(Conditional Updates)

Ignite 提供了一些带有条件判断的更新方法,用于实现线程安全的更新逻辑。

示例代码:

java 复制代码
// 如果 key 不存在,则插入,返回旧值
String oldVal = cache.getAndPutIfAbsent(11, "Hello");

// 如果 key 不存在,插入,返回是否成功
boolean success = cache.putIfAbsent(22, "World");

// 如果 key 存在,替换,返回旧值
oldVal = cache.getAndReplace(11, "New value");

// 如果 key 存在,替换,返回是否成功
success = cache.replace(22, "Other new value");

// 如果值匹配,才替换
success = cache.replace(22, "Other new value", "Yet-another-new-value");

// 如果值匹配,才删除
success = cache.remove(11, "Hello");

六、异步操作(Asynchronous Execution)

Ignite 的很多缓存操作都有对应的 异步版本 ,方法名通常带有 Async 后缀。

示例代码:

java 复制代码
// 同步 get
V get(K key);

// 异步 get
IgniteFuture<V> getAsync(K key);

异步操作的处理方式:

  • 返回一个 IgniteFuture 对象,表示异步操作的结果。
  • 可以阻塞等待结果,也可以注册监听器来非阻塞地处理结果。

示例监听器:

java 复制代码
IgniteCompute compute = ignite.compute();

IgniteFuture<String> fut = compute.callAsync(() -> "Hello World");

fut.listen(f -> System.out.println("Job result: " + f.get()));

七、线程池与闭包执行(Closures Execution and Thread Pools)

  • 如果异步操作在注册监听器前就已经完成,监听器会由当前线程 同步执行
  • 如果异步操作还未完成,监听器会在操作完成后由线程池中的线程 异步执行
    • 缓存操作的异步回调通常由 系统线程池 执行。
    • 计算任务的异步回调通常由 公共线程池 执行。

注意事项:

  • 不要在监听器中再调用同步的缓存或计算操作,这可能导致 线程池饥饿(pool starvation)死锁
  • 如需嵌套异步操作,可以使用 自定义线程池 来避免资源争用。

总结表格

操作类型 描述
获取缓存 通过 ignite.cache("name") 获取缓存实例
创建缓存 使用 getOrCreateCache(cfg) 动态创建缓存
销毁缓存 调用 cache.destroy() 删除缓存
原子操作 put, get, remove 等基本操作
条件更新 putIfAbsent, replace, remove 等带条件操作
异步操作 使用 xxxAsync() 方法和 IgniteFuture
线程池 监听器可能由系统或公共线程池执行,避免同步调用

如果你是刚开始学习 Ignite,理解这些基本缓存操作非常重要。它们是构建分布式缓存应用的基础。对于更复杂的场景,如事务、查询、索引等,请参考 Ignite 的高级功能文档。

相关推荐
小旭95273 小时前
商品详情实现与缓存问题(穿透、击穿、雪崩)解决方案
java·数据库·spring boot·后端·缓存
Mr. zhihao4 小时前
Redis 内存管理深度解析:过期删除与内存淘汰策略
数据库·redis·缓存
Solis程序员4 小时前
分层缓存调度:削峰控压下的 Feed 流高性能设计
缓存
難釋懷4 小时前
Redis内存回收-过期key处理
数据库·redis·缓存
Nayxxu6 小时前
Gemini 长上下文成本估算表:输入、输出、缓存怎么拆
java·缓存
爱莉希雅&&&8 小时前
Redis哨兵模式和主从复制和集群模式搭建与扩容缩容
linux·redis·缓存·集群·哨兵·数据库同步
JohnnyDeng948 小时前
OkHttp 拦截器链与缓存策略:深度解析网络层的核心机制
okhttp·缓存
m0_474606789 小时前
JAVA - 使用Apache POI 自定义报表字段手写导出(支持-合并单元格)
java·开发语言·apache
Harm灬小海9 小时前
【云计算学习之路】企业常用服务搭建:构建Apache WEB服务器
运维·服务器·学习·云计算·apache
MRSM_019 小时前
Redis 缓存、队列、排行榜的核心用法
数据库·redis·缓存