Apache Ignite缓存基本操作

发布于:2025-07-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

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


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

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

示例代码:

Ignite ignite = Ignition.ignite();

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

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


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

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

示例代码:

CacheConfiguration<Integer, String> cfg = new CacheConfiguration<>();
cfg.setName("myNewCache");
cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);

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

配置说明:

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

注意事项:

  • 如果在集群拓扑发生变化(如节点加入或退出)时调用 getOrCreateCache(),可能会抛出异常:
    javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: Failed to start/stop cache, cluster state change is in progress.
    
  • 遇到这个异常时,建议稍后重试。

三、销毁缓存(Destroying Caches)

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

示例代码:

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

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


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

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

示例代码:

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 提供了一些带有条件判断的更新方法,用于实现线程安全的更新逻辑。

示例代码:

// 如果 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 后缀。

示例代码:

// 同步 get
V get(K key);

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

异步操作的处理方式:

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

示例监听器:

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 的高级功能文档。


网站公告

今日签到

点亮在社区的每一天
去签到