Hazelcast

分散キャッシュJavaインメモリデータグリッドクラスタリングスケーラビリティNoSQL

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

スター履歴

hazelcast/hazelcast Star History
データ取得日時: 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);