這段內容主要講解了 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(...)
:設置緩存的原子性模式(例如TRANSACTIONAL
或ATOMIC
)。- 還可以設置很多其他參數,比如備份數量、緩存模式(分區/復制)等。
注意事項:
- 如果在集群拓撲發生變化(如節點加入或退出)時調用
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)
獲取到緩存后,可以進行常見的 put
、get
、remove
等操作。
示例代碼:
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 的高級功能文檔。