Hazelcast
GitHub概要
hazelcast/hazelcast
Hazelcast is a unified real-time data platform combining stream processing with a fast data store, allowing customers to act instantly on data-in-motion for real-time insights.
スター6,425
ウォッチ292
フォーク1,870
作成日:2012年3月21日
言語:Java
ライセンス:Other
トピックス
big-datacachingdata-in-motiondata-insightsdistributeddistributed-computingdistributed-systemshacktoberfesthazelcastin-memoryjavalow-latencyreal-timescalabilitystream-processing
スター履歴
データ取得日時: 2025/10/22 08:07
キャッシュライブラリ
Hazelcast
概要
Hazelcastは、Javaベースのオープンソース分散インメモリデータグリッドプラットフォームです。分散キャッシュ、分散コンピューティング、分散データストレージの機能を統合し、高可用性とスケーラビリティを提供します。標準的なJava Mapインターフェースを使用しながら、データを複数のJVMインスタンス間で自動的に分散・複製し、パーティション耐性とデータの一貫性を保証します。
詳細
Hazelcastは、従来のリレーショナルデータベースやファイルシステムへの依存を減らし、メモリ内でのデータ処理により大幅なパフォーマンス向上を実現するプラットフォームです。分散システムにおいて、データの局所性を活用し、ネットワーク呼び出しを最小化することで、高速なデータアクセスと処理を可能にします。
主要な分散データ構造
- Map: クラスタ全体に分散されたキー・バリューペア。SQLクエリ、WAN複製、Near Cacheをサポート
- Cache: JCache仕様準拠のHazelcast実装
- Queue/Priority Queue: FIFO順序または設定可能な順序でのアイテム追加・削除
- Set/List: 重複を許可しない分散コレクションと順序を保持する分散リスト
- MultiMap: 単一キーに対して複数の値を格納できる特殊なMap
- Replicated Map: 各メンバーに完全複製されるキー・バリューペア
- Topic/Reliable Topic: 複数の購読者へのメッセージ配信(pub/sub)
エンタープライズ機能(CP Data Structures)
- Atomic Long/Reference: 分散環境での原子的な値操作
- Countdown Latch: 並行アクティビティのゲートキーパー
- Semaphore: スレッド数制御のためのパーミット作成
メリット・デメリット
メリット
- 高いスケーラビリティ: ノード追加による線形的な性能向上
- 障害耐性: 自動的なフェイルオーバーとデータ複製による高可用性
- 標準API互換: 既存のJava CollectionフレームワークAPIとの互換性
- データローカリティ: 同一キーでの操作を同一メンバーで実行してネットワーク負荷を軽減
- リアルタイム処理: イベントリスナーによるデータ変更の即座な通知
- 豊富なエコシステム: Kubernetes、Spring Boot、Apache Kafka等との統合
デメリット
- メモリ消費: 大量のデータを扱う際のメモリ要件の増大
- ネットワーク依存: ネットワーク分断時の一時的なサービス中断リスク
- 複雑性: 分散システムならではの設定・運用の複雑さ
- Java特化: 主にJavaエコシステムに限定される利用範囲
参考ページ
書き方の例
基本的なHazelcastインスタンスの作成と分散Map操作
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
// Hazelcastインスタンスの作成
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
// 分散Mapの取得
IMap<String, String> map = hazelcast.getMap("my-distributed-map");
// データの書き込み
map.put("1", "John");
map.put("2", "Mary");
map.put("3", "Jane");
// データの読み込み
System.out.println(map.get("1")); // John
System.out.println(map.get("2")); // Mary
System.out.println(map.get("3")); // Jane
クラスタ設定とネットワーク設定
import com.hazelcast.config.Config;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.config.JoinConfig;
Config config = new Config();
config.setClusterName("my-cluster");
// ネットワーク設定
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(5701);
networkConfig.setPortAutoIncrement(true);
// クラスタ参加設定
JoinConfig joinConfig = networkConfig.getJoin();
joinConfig.getMulticastConfig().setEnabled(false);
joinConfig.getTcpIpConfig()
.setEnabled(true)
.addMember("192.168.1.100")
.addMember("192.168.1.101");
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(config);
分散キューとメッセージング
import com.hazelcast.collection.IQueue;
import com.hazelcast.topic.ITopic;
// 分散キューの利用
IQueue<String> queue = hazelcast.getQueue("my-queue");
queue.offer("Hello");
queue.offer("World");
String item = queue.poll(); // "Hello"
// パブリッシュ・サブスクライブメッセージング
ITopic<String> topic = hazelcast.getTopic("my-topic");
// メッセージリスナーの登録
topic.addMessageListener(message -> {
System.out.println("受信: " + message.getMessageObject());
});
// メッセージの送信
topic.publish("Hello, Cluster!");
分散実行サービス
import com.hazelcast.core.IExecutorService;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
// 分散実行サービスの取得
IExecutorService executor = hazelcast.getExecutorService("my-executor");
// タスクの定義
Callable<Integer> task = () -> {
return 100 + 23;
};
// タスクの実行
Future<Integer> future = executor.submit(task);
Integer result = future.get(); // 123
// 特定のメンバーでタスクを実行
executor.executeOnKeyOwner(task, "my-key");
Near Cacheの設定
import com.hazelcast.config.NearCacheConfig;
import com.hazelcast.config.MapConfig;
Config config = new Config();
// Near Cache設定
NearCacheConfig nearCacheConfig = new NearCacheConfig();
nearCacheConfig.setName("my-map-near-cache");
nearCacheConfig.setInMemoryFormat(InMemoryFormat.BINARY);
nearCacheConfig.setInvalidateOnChange(true);
nearCacheConfig.setTimeToLiveSeconds(0);
nearCacheConfig.setMaxIdleSeconds(60);
// Map設定にNear Cacheを追加
MapConfig mapConfig = new MapConfig("my-map");
mapConfig.setNearCacheConfig(nearCacheConfig);
config.addMapConfig(mapConfig);
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(config);
エントリプロセッサーによる効率的なデータ処理
import com.hazelcast.map.EntryProcessor;
// カスタムエントリプロセッサー
public class IncrementProcessor implements EntryProcessor<String, Integer, Integer> {
@Override
public Integer process(Map.Entry<String, Integer> entry) {
Integer currentValue = entry.getValue();
if (currentValue == null) {
currentValue = 0;
}
Integer newValue = currentValue + 1;
entry.setValue(newValue);
return newValue;
}
}
// エントリプロセッサーの使用
IMap<String, Integer> map = hazelcast.getMap("counters");
map.put("counter1", 5);
// 効率的なインクリメント操作(ネットワーク負荷を軽減)
Integer result = map.executeOnKey("counter1", new IncrementProcessor());
System.out.println("新しい値: " + result); // 6
イベントリスナーとデータ変更通知
import com.hazelcast.core.EntryEvent;
import com.hazelcast.map.MapListener;
// Mapリスナーの実装
MapListener listener = new MapListener() {
@Override
public void entryAdded(EntryEvent event) {
System.out.println("追加: " + event.getKey() + " = " + event.getValue());
}
@Override
public void entryUpdated(EntryEvent event) {
System.out.println("更新: " + event.getKey() +
" 旧値=" + event.getOldValue() +
" 新値=" + event.getValue());
}
@Override
public void entryRemoved(EntryEvent event) {
System.out.println("削除: " + event.getKey());
}
};
// リスナーの登録
IMap<String, String> map = hazelcast.getMap("my-map");
map.addEntryListener(listener, true);