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(...):设置缓存的原子性模式(例如 TRANSACTIONAL 或 ATOMIC)。
  • 还可以设置很多其他参数,比如备份数量、缓存模式(分区/复制)等。

注意事项:

  • 如果在集群拓扑发生变化(如节点加入或退出)时调用 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)

获取到缓存后,可以进行常见的 put、get、remove 等操作。

示例代码:

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

相关推荐
真上帝的左手1 天前
30. 技术专题-‌应用框架组件-缓存-Redis
数据库·redis·分布式·缓存·中间件
bksczm1 天前
C++Redis开发(Ubuntu 22.04)
数据库·redis·缓存
goehou1 天前
缓存该删还是该改,LLM 服务里的双写问题
redis·缓存·llm·一致性·系统设计
利威尔xu2 天前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
程序猿编码2 天前
解决 LLM 算力浪费,一套统一 KV 管理层实现缓存复用
人工智能·神经网络·机器学习·缓存·llm·大模型推理
zrc0070072 天前
steam无法登录 steam错误 登录时出现错误。请稍后再试。解决办法 steam无法登录解决办法 湖南地区steam DNS问题解决办法
windows·经验分享·游戏·缓存·游戏程序·创业创新·玩游戏
CCblandy2 天前
缓存淘汰实测:一次全表扫描把 LRU 命中率从 46% 打到 38%,W-TinyLFU 守住 50% 却贵 11 倍
后端·python·缓存·性能优化·架构
Wang's Blog2 天前
Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存
java·缓存·交友
麻瓜code2 天前
双写一致性:为什么是“删缓存“,而不是“改缓存“
java·缓存·mybatis
snow@li2 天前
redis:RedisDesktopManager(RDM/RESP.app)Redis 数据可视化全景深度梳理
数据库·redis·缓存