Cassandra

Apache Cassandra 完全ガイド:分散 NoSQL データベースのアーキテクチャと実装

目次

  1. はじめに
  2. Cassandra の基本概念
  3. アーキテクチャの全体像
  4. データモデルとスキーマ設計
  5. 一貫性とレプリケーション
  6. パフォーマンス最適化
  7. 運用と監視
  8. ベストプラクティス

1. はじめに

1.1 Cassandra とは

Apache Cassandra は、Facebook の Avinash Lakshman と Prashant Malik によって開発され、現在は Apache Software Foundation によってメンテナンスされている分散 NoSQL データベースです。高いスケーラビリティ、可用性、耐障害性を備えており、大規模なデータセットと高いトランザクション量を処理する必要があるアプリケーションに適しています。

Cassandra の主な特徴:

  • 水平スケーラビリティ:ノードを追加することで線形にパフォーマンスが向上
  • 高可用性:複数のレプリカにデータを分散保存
  • 最終的一貫性:CAP定理に基づいた可用性と分断耐性の優先
  • スキーマの柔軟性:カラム指向データモデル
  • 書き込み最適化:高速な書き込み操作に最適化

1.2 用語と基本概念

ノード(Node):Cassandra クラスタを構成する個々のサーバーマシン クラスタ(Cluster):複数のノードで構成されたシステム全体 キースペース(Keyspace):リレーショナルデータベースのスキーマに相当 テーブル(Table):データを格納する基本単位 レプリケーション因子(Replication Factor):データがコピーされる回数 パーティション(Partition):プライマリキーに基づくデータの物理的な分割単位


2. Cassandra の基本概念

2.1 カラム指向データモデル

Cassandra はカラム指向データベースであり、行指向のリレーショナルデータベースとは異なるアプローチを採用しています。

行指向(従来のSQL):
Row 1: | UserID | Name  | Email          | Age |
       | 1      | Alice | alice@example  | 28  |

Cassandra のカラム指向:
UserID → Name: Alice, Email: alice@example, Age: 28

この設計により、特定のカラムのクエリが効率的になり、スパースデータ(多くのカラムが NULL)も効率的に保存できます。

2.2 プライマリキー

プライマリキーは Cassandra のデータアクセスパターンの中心です。

-- シンプルなプライマリキー
CREATE TABLE users (
  user_id UUID PRIMARY KEY,
  username TEXT,
  email TEXT,
  created_at TIMESTAMP
);

-- 複合プライマリキー(パーティションキー+クラスタリングキー)
CREATE TABLE user_posts (
  user_id UUID,
  post_timestamp TIMESTAMP,
  post_id UUID,
  content TEXT,
  created_at TIMESTAMP,
  PRIMARY KEY (user_id, post_timestamp, post_id)
);

パーティションキー(Partition Key)

  • ハッシュ関数によってどのノードにデータを保存するかを決定
  • 最初のキーコンポーネント
  • データの分散を制御

クラスタリングキー(Clustering Key)

  • 同じパーティション内でのソート順序を定義
  • オプショナル
  • 範囲クエリの効率を向上

2.3 データ型

CREATE TABLE sensor_data (
  sensor_id UUID,
  timestamp TIMESTAMP,
  temperature DECIMAL,           -- 小数点数
  humidity FLOAT,                 -- 浮動小数点
  is_active BOOLEAN,              -- ブール値
  reading_count COUNTER,          -- カウンター型(分散カウント用)
  metadata MAP<TEXT, TEXT>,       -- マップ
  tags LIST<TEXT>,                -- リスト
  locations SET<TEXT>,            -- セット
  PRIMARY KEY (sensor_id, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);

主要なデータ型

  • UUID, TIMEUUID:一意の識別子
  • TEXT, VARCHAR:文字列
  • BIGINT, INT, SMALLINT:整数値
  • DECIMAL, FLOAT, DOUBLE:浮動小数点数
  • BLOB:バイナリデータ
  • DATE, TIME, TIMESTAMP:日時
  • COUNTER:分散カウンター
  • MAP, LIST, SET:コレクション型
  • FROZEN<T>:完全に不変なコレクション

3. アーキテクチャの全体像

3.1 ノードのアーキテクチャ

┌─────────────────────────────────────────────────────────┐
│                    Cassandra ノード                      │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │          クライアント接続層                        │  │
│  │  - CQL プロトコルハンドラ                         │  │
│  │  - Thrift レガシープロトコル                      │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │           クエリ処理エンジン                       │  │
│  │  - クエリパーサー                                │  │
│  │  - 実行計画生成                                  │  │
│  │  - 一貫性チェック                                │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │            ストレージエンジン                      │  │
│  │  ┌─────────┬──────────┬──────────┬─────────┐    │  │
│  │  │ Memtable│ SSTable  │ Bloom    │ Index   │    │  │
│  │  │         │          │ Filter   │         │    │  │
│  │  └─────────┴──────────┴──────────┴─────────┘    │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
│  ┌──────────────────────────────────────────────────┐  │
│  │        ディスク管理とキャッシング                  │  │
│  │  - OS PageCache                                │  │
│  │  - Bloom Filters                               │  │
│  │  - Compression                                 │  │
│  └──────────────────────────────────────────────────┘  │
│                                                          │
└─────────────────────────────────────────────────────────┘

3.2 書き込み処理フロー

クライアント
    ↓
コーディネーター選択
    ↓
一貫性チェック
    ↓
┌─────────────────────────────┐
│   Memtable に書き込み        │
│  (メモリ内バッファ)         │
└─────────────────────────────┘
    ↓
コミットログに記録
(ディスクに永続化)
    ↓
レプリケーション先に複製
    ↓
確認応答(Acknowledgement)

詳細な流れ

  1. コーディネーター選択:クライアントのリクエストを処理するノードが決定される
  2. 一貫性レベル評価:リクエストされた一貫性レベルでいくつのレプリカから確認を得るか決定
  3. Memtable 書き込み:データがメモリ内の Memtable に書き込まれる
  4. コミットログ記録:障害時の復旧のためディスクに記録
  5. レプリケーション:設定された数のレプリケーション先ノードに転送
  6. 確認応答:指定された一貫性レベルを満たしたら応答

3.3 読み取り処理フロー

クライアント
    ↓
コーディネーター選択
    ↓
一貫性レベル確認
    ↓
┌─────────────────────────────┐
│  複数レプリカから読み取り    │
│                             │
│  ・Memtable チェック        │
│  ・Bloom Filter 確認        │
│  ・SSTable 検索             │
└─────────────────────────────┘
    ↓
Read Repair(必要に応じて)
    ↓
クライアントにデータ返却

Bloom Filter の役割

  • SSTable が特定キーを含むかを O(1) で確認
  • 偽の肯定(存在しないキーを存在すると判定)の確率は低い
  • false negatives は発生しない

3.4 Memtable と SSTable

Memtable(メモリ)
  ┌──────────────────┐
  │ 最新のデータ      │
  │ (ソート済み)    │
  └──────────────────┘
         ↓
     フラッシュ
  (サイズ超過時)
         ↓
SSTable(ディスク上の不変ファイル)
  ┌──────────────────┐
  │ SSTable-1        │
  │ (古いデータ)    │
  ├──────────────────┤
  │ SSTable-2        │
  │ (中程度のデータ)│
  ├──────────────────┤
  │ SSTable-3        │
  │ (新しいデータ)  │
  └──────────────────┘

SSTable の構造

┌─────────────────────────────────────────┐
│ Index(キーオフセット)                 │
├─────────────────────────────────────────┤
│ Bloom Filter                            │
├─────────────────────────────────────────┤
│ Compressed Data Blocks                  │
├─────────────────────────────────────────┤
│ Footer(メタデータ)                    │
└─────────────────────────────────────────┘

3.5 Compaction ストラテジー

複数の SSTable
┌──────────┐  ┌──────────┐  ┌──────────┐
│SSTable-1 │  │SSTable-2 │  │SSTable-3 │
└──────────┘  └──────────┘  └──────────┘
      │             │             │
      └─────────────┴─────────────┘
            │
      Compaction
            │
      ┌─────────────┐
      │新規SSTable  │
      └─────────────┘

Compaction の目的

  • 削除済みデータ(トゥームストーン)を消去
  • 読み取り性能向上(検索対象の SSTable 数削減)
  • ディスク容量効率化

Compaction ストラテジー

  1. SizeTieredCompactionStrategy(STCS)

    • デフォルト
    • 同じサイズのテーブルをグループ化してマージ
    • 予測可能なディスク使用量
  2. LeveledCompactionStrategy(LCS)

    • レベル構造を維持
    • ディスク使用量を抑制
    • 読み取り性能向上
  3. TimeWindowCompactionStrategy(TWCS)

    • 時系列データに最適
    • 時間ウィンドウ単位でマージ

3.6 ハッシング と トークン

            Cassandra リング
        ┌──────────────────────┐
        │                      │
      ╱                          ╲
    ╱   Token范围分配              ╲
   │  0 - 3 - Node-A              │
   │                              │
   │  3 - 6 - Node-B              │
   │                              │
   │  6 - 9 - Node-C              │
    ╲                            ╱
      ╲   (VNode により柔軟)    ╱
        └──────────────────────┘

トークンの役割

  • パーティションキーをハッシュして得られた値
  • ノード上でのデータ配置を決定
  • リング上の位置を表す
  • 0~2^63-1 の範囲の値

VNode(Virtual Node)

  • 各ノードが複数のトークン範囲を所有
  • ノード追加/削除時の再配置が効率的
  • デフォルトで有効(num_tokens = 256)

4. データモデルとスキーマ設計

4.1 スキーマ設計の原則

Query-Driven Design: Cassandra はリレーショナルデータベースと異なり、クエリパターンに基づいてテーブルを設計する必要があります。

例:ユーザーのアクティビティデータ

-- ❌ 悪い設計(リレーショナル風)
CREATE TABLE user_activities (
  user_id UUID,
  activity_id UUID,
  activity_type TEXT,
  timestamp TIMESTAMP,
  details TEXT,
  PRIMARY KEY (user_id, activity_id)
);

-- ✅ 良い設計(クエリパターン単位)
-- クエリ1:特定ユーザーの最近のアクティビティ取得
CREATE TABLE activities_by_user (
  user_id UUID,
  timestamp TIMESTAMP,
  activity_type TEXT,
  activity_id UUID,
  details TEXT,
  PRIMARY KEY (user_id, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);

-- クエリ2:アクティビティタイプ別の集計
CREATE TABLE activities_by_type (
  activity_type TEXT,
  timestamp TIMESTAMP,
  user_id UUID,
  activity_id UUID,
  details TEXT,
  PRIMARY KEY (activity_type, timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC);

4.2 時系列データの設計

-- メトリクスデータの効率的な保存
CREATE TABLE metrics (
  metric_name TEXT,
  hour TIMESTAMP,
  minute TIMESTAMP,
  value DECIMAL,
  PRIMARY KEY ((metric_name, hour), minute)
) WITH CLUSTERING ORDER BY (minute DESC);

-- 年単位でのパーティショニング例
CREATE TABLE sensor_readings (
  sensor_id UUID,
  year INT,
  month INT,
  day INT,
  timestamp TIMESTAMP,
  temperature DECIMAL,
  humidity DECIMAL,
  PRIMARY KEY ((sensor_id, year, month), day, timestamp)
) WITH CLUSTERING ORDER BY (day DESC, timestamp DESC);

4.3 テーブルオプション

CREATE TABLE products (
  product_id UUID PRIMARY KEY,
  product_name TEXT,
  category TEXT,
  price DECIMAL,
  created_at TIMESTAMP
)
WITH 
  -- TTL(Time To Live)
  default_time_to_live = 86400
  
  -- Bloom Filter 設定
  AND bloom_filter_fp_chance = 0.01
  
  -- キャッシング設定
  AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
  
  -- Compaction 戦略
  AND compaction = {
    'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy',
    'min_threshold': 4,
    'max_threshold': 32
  }
  
  -- 圧縮設定
  AND compression = {
    'class': 'org.apache.cassandra.io.compress.LZ4Compressor',
    'chunk_length_in_kb': 64
  }
  
  -- ガベージコレクション猶予期間
  AND gc_grace_seconds = 864000;

4.4 インデックス戦略

-- セカンダリインデックス(使用は慎重に)
CREATE TABLE users (
  user_id UUID,
  email TEXT,
  username TEXT,
  status TEXT,
  PRIMARY KEY (user_id)
);

-- メールでの検索用インデックス
CREATE INDEX ON users(email);

-- より良い設計:専用テーブル
CREATE TABLE users_by_email (
  email TEXT,
  user_id UUID,
  username TEXT,
  status TEXT,
  PRIMARY KEY (email, user_id)
);

-- マテリアライズドビュー(Cassandra 3.0+)
CREATE MATERIALIZED VIEW users_by_status AS
  SELECT user_id, email, status
  FROM users
  WHERE status IS NOT NULL
  PRIMARY KEY (status, user_id);

5. 一貫性とレプリケーション

5.1 一貫性レベル(Consistency Level)

一貫性レベルの比較
┌──────────┬───────────────────┬──────────────────┬────────────┐
│レベル    │  書き込み         │   読み取り        │ 特徴       │
├──────────┼───────────────────┼──────────────────┼────────────┤
│ONE       │ 1つのレプリカ確認  │ 1つのレプリカから │ 高速、低一貫性 │
│TWO       │ 2つのレプリカ確認  │ 2つのレプリカから │ バランス型  │
│THREE     │ 3つのレプリカ確認  │ 3つのレプリカから │ 高一貫性    │
│QUORUM    │ 過半数確認        │ 過半数から       │ 推奨        │
│ALL       │ 全レプリカ確認    │ 全レプリカから   │ 最高一貫性  │
│LOCAL_ONE │ ローカルDC内1つ  │ ローカルDC内1つ  │ DC限定      │
│LOCAL_QUORUM│ローカルDC過半数  │ ローカルDC過半数 │推奨(マルチDC)│
│EACH_QUORUM│ 各DC過半数        │各DC過半数        │マルチDC時推奨 │
└──────────┴───────────────────┴──────────────────┴────────────┘

実装例

-- 高一貫性の書き込み
INSERT INTO users (user_id, email, created_at)
VALUES (uuid(), 'user@example.com', now())
USING CONSISTENCY QUORUM;

-- 最終的一貫性の読み取り
SELECT * FROM users WHERE user_id = ?
USING CONSISTENCY ONE;

-- クリティカルなデータの強い一貫性
SELECT * FROM payment_records 
WHERE transaction_id = ?
USING CONSISTENCY ALL
AND ALLOW FILTERING;

5.2 レプリケーション戦略

-- シンプルストラテジー(単一DC)
CREATE KEYSPACE simple_keyspace WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': 3
};

-- ネットワークトポロジーストラテジー(マルチDC推奨)
CREATE KEYSPACE prod_keyspace WITH replication = {
  'class': 'NetworkTopologyStrategy',
  'us-east': 3,
  'us-west': 2,
  'eu-central': 2
};

5.3 Read Repair と Hinted Handoff

Read Repair

読み取りリクエスト
       ↓
3つのレプリカから読み取り
       ↓
データ不一致を検出
       ↓
最新データをすべてのレプリカに書き込み
       ↓
修復完了

Read Repair の設定

ALTER TABLE users WITH read_repair_chance = 0.1;

Hinted Handoff

ノード A への書き込み
    ↓
ノード B (レプリカ) がダウン
    ↓
ノード A が「ヒント」を一時保存
    ↓
ノード B が復帰
    ↓
ノード A がヒントを再送

6. パフォーマンス最適化

6.1 メモリ管理

# cassandra.yaml 設定例

# JVM ヒープサイズ
max_heap_size: 8G
heap_newsize: 2G

# Memtable 設定
memtable_total_space_in_mb: 2048

# キャッシング設定
key_cache_size_in_mb: 512
row_cache_size_in_mb: 512

6.2 ディスク I/O 最適化

-- Compression の設定
CREATE TABLE large_table (
  id UUID PRIMARY KEY,
  data BLOB
)
WITH compression = {
  'class': 'org.apache.cassandra.io.compress.LZ4Compressor',
  'chunk_length_in_kb': 64,
  'crc_check_chance': 1.0
};

-- Bloom Filter FP チャンスの最適化
-- 存在しないキーの多くを検査する場合は低く
-- 殆どのキーが存在する場合は高めに
ALTER TABLE users WITH bloom_filter_fp_chance = 0.01;

6.3 クエリ最適化

-- ✅ 効率的なクエリ
-- パーティションキーで絞り込み
SELECT * FROM activities_by_user 
WHERE user_id = ? 
AND timestamp >= ? AND timestamp <= ?;

-- ❌ 非効率なクエリ
-- スキャンが必要
SELECT * FROM activities_by_user 
WHERE activity_type = ? ALLOW FILTERING;

-- パフォーマンス測定
SELECT COUNT(*) FROM users;

-- LIMIT でパフォーマンス改善
SELECT * FROM activities_by_user 
WHERE user_id = ? LIMIT 100;

6.4 バッチ処理

-- バッチ処理例
BEGIN BATCH
  INSERT INTO users (user_id, name) VALUES (uuid1, 'Alice');
  INSERT INTO users (user_id, name) VALUES (uuid2, 'Bob');
  INSERT INTO user_stats (user_id, count) VALUES (uuid1, 1);
APPLY BATCH;

-- Counter バッチ
BEGIN COUNTER BATCH
  UPDATE user_stats SET login_count = login_count + 1 
    WHERE user_id = uuid1;
  UPDATE user_stats SET active_users = active_users + 1 
    WHERE date = '2024-01-01';
APPLY BATCH;

6.5 Prepared Statements

-- Prepared Statement の利点:
-- 1. ネットワークトラフィック削減
-- 2. パースオーバーヘッド削減
-- 3. SQL インジェクション防止

PREPARE statement1 AS
  INSERT INTO users (user_id, email, created_at)
  VALUES (?, ?, ?);

PREPARE statement2 AS
  SELECT * FROM users WHERE user_id = ?;

7. 運用と監視

7.1 クラスタ構成例

# cassandra.yaml 主要設定
cluster_name: "ProductionCluster"
listen_address: "10.0.1.100"
rpc_address: "0.0.0.0"

# Seed ノード
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.0.1.1,10.0.1.2,10.0.1.3"

# スナップショット設定
snapshot_before_compact: false
auto_snapshot: true

# Commitlog 設定
commitlog_total_space_in_mb: 4096
commitlog_segment_size_in_mb: 32

# GC 設定
concurrent_gc_threads: 4

# NTP を推奨

7.2 ノード管理コマンド

# ノードの状態確認
nodetool status

# ノード情報表示
nodetool info

# トークン情報表示
nodetool ring

# スナップショット取得
nodetool snapshot keyspace_name -t snapshot_name

# Compaction 状態確認
nodetool compactionstats

# キャッシュ統計
nodetool cachetats

# ガベージコレクション強制実行
nodetool garbagecollect

# 修復実行(データ一貫性確保)
nodetool repair -pr keyspace_name

# ノード追加時の準備
nodetool flush keyspace_name

# ノード削除
nodetool decommission

7.3 監視メトリクス

重要なメトリクス:

1. スループット系
   - Write Latency(ms)
   - Read Latency(ms)
   - Operations/sec

2. キャッシュ効率
   - Key Cache Hit Rate
   - Row Cache Hit Rate
   - Bloom Filter False Positive

3. GC 情報
   - Young Generation GC 時間
   - Full GC 発生頻度

4. ディスク I/O
   - Disk Space Used(GB)
   - SSTable 数
   - Compaction 待機中の作業

5. ネットワーク
   - ドロップされたメッセージ
   - レプリケーション遅延

6. 一貫性
   - Read Repair 実行頻度
   - Hinted Handoff 数

7.4 ログ分析

# ログファイル位置
/var/log/cassandra/system.log

# 重要なエラーパターン
- "OutOfMemoryError"
- "FATAL"
- "TimeoutException"
- "UnknownHostException"

# ログレベル設定(cassandra-env.sh)

8. ベストプラクティス

8.1 スキーマ設計

✅ 推奨事項:
1. クエリパターンに基づくテーブル設計
2. 正規化より非正規化を優先
3. ワイドローを避ける(パーティションサイズ制限)
4. TTL を適切に設定
5. ホットパーティションを回避
6. 十分なテスト環境で検証

❌ 避けるべきこと:
1. ALLOW FILTERING の多用
2. LIMITなしの大規模スキャン
3. 全レプリカが必須でない場合の ALL 一貫性
4. スキーマの頻繁な変更
5. 無制限の collection 型

8.2 パフォーマンス

最適化チェックリスト:

□ Connection Pooling の実装
□ Batch Size の最適化(50-1000 行)
□ Async 操作の活用
□ 適切な Consistency Level の選択
□ インデックス使用の最小化
□ Partition Size のモニタリング
□ GC Tuning の実施
□ キャッシュヒット率の確認

8.3 運用

運用チェックリスト:

□ 定期的な修復(nodetool repair)
□ バックアップ戦略の実装
□ ディスク容量監視
□ ノード追加/削除手順の文書化
□ 災害復旧計画の策定
□ アラート設定
□ キャパシティプランニング
□ セキュリティ設定の確認

8.4 セキュリティ

-- ユーザーと権限管理
CREATE ROLE admin WITH PASSWORD = 'strong_password' 
  AND LOGIN = true 
  AND SUPERUSER = true;

CREATE ROLE app_user WITH PASSWORD = 'password' 
  AND LOGIN = true;

GRANT SELECT, INSERT, UPDATE ON KEYSPACE prod 
  TO app_user;

GRANT SELECT ON KEYSPACE prod.users 
  TO app_user;
# cassandra.yaml
# 認証設定
authenticator: PasswordAuthenticator

# 認可設定
authorizer: CassandraAuthorizer

# 暗号化設定
server_encryption_options:
  internode_encryption: all
  keystore: /path/to/keystore
  keystore_password: password
  truststore: /path/to/truststore
  truststore_password: password

9. トラブルシューティング

9.1 一般的な問題と対処

問題 1: ノードがダウンしている

診断:
$ nodetool status
→ DN(Down Normal)ステータス

対処:
1. ノードのログを確認
2. ディスク容量をチェック
3. メモリ使用量を確認
4. ネットワーク接続を確認
5. サービスを再起動

問題 2: 読み取り遅延が増加

診断:
$ nodetool tablehistograms keyspace table
→ P95, P99 遅延を確認

対処:
1. キャッシュヒット率を確認
2. SSTable 数をチェック
3. Compaction 状態を確認
4. GC ログを分析
5. 必要に応じてスケールアウト

問題 3: メモリ不足エラー

診断:
- OutOfMemoryError 発生
- GC オーバーヘッド

対処:
1. ヒープサイズを増加
2. Memtable サイズを調整
3. キャッシュサイズを削減
4. ノードをスケールアウト
5. パーティションサイズを監視

9.2 パフォーマンスプロファイリング

# JVM メトリクス
jps -l

# ガベージコレクション分析
jstat -gc -h10 <pid> 1000

# スレッドダンプ
jstack <pid> > thread_dump.txt

# ヒープダンプ
jmap -dump:live,format=b,file=heap.bin <pid>

10. ケーススタディ

10.1 ユーザーアクティビティログシステム

要件

  • 日々数十億のイベントログを保存
  • 特定ユーザーの最近のアクティビティを素早く取得
  • アクティビティタイプ別の集計

スキーマ設計

CREATE KEYSPACE analytics WITH replication = {
  'class': 'NetworkTopologyStrategy',
  'us-east': 3,
  'us-west': 2
};

-- テーブル1: ユーザー別のアクティビティ
CREATE TABLE activities_by_user (
  user_id UUID,
  day DATE,
  timestamp TIMESTAMP,
  event_type TEXT,
  event_id UUID,
  payload TEXT,
  PRIMARY KEY ((user_id, day), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC)
  AND default_time_to_live = 86400
  AND compaction = {
    'class': 'TimeWindowCompactionStrategy',
    'compaction_window_size': 24,
    'compaction_window_unit': 'HOURS'
  };

-- テーブル2: イベントタイプ別の集計
CREATE TABLE event_counters (
  event_type TEXT,
  hour TIMESTAMP,
  count COUNTER,
  PRIMARY KEY (event_type, hour)
) WITH default_time_to_live = 604800;

操作例

-- アクティビティ記録
INSERT INTO activities_by_user 
(user_id, day, timestamp, event_type, event_id, payload)
VALUES (?, ?, ?, ?, uuid(), ?) 
USING TIMESTAMP now();

-- ユーザーの最近7日間のアクティビティ取得
SELECT * FROM activities_by_user 
WHERE user_id = ? AND day >= ? AND day <= ?
LIMIT 1000;

-- イベントタイプのカウント更新
UPDATE event_counters 
SET count = count + 1 
WHERE event_type = ? AND hour = ?;

10.2 リアルタイムセンサーデータシステム

要件

  • 複数の IoT センサーからのリアルタイムデータ
  • 時間範囲でのクエリが多い
  • 古いデータの自動削除

スキーマ設計

CREATE KEYSPACE sensor_data WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': 2
};

CREATE TABLE sensors (
  sensor_id UUID,
  year INT,
  month INT,
  day INT,
  hour INT,
  timestamp TIMESTAMP,
  temperature DECIMAL,
  humidity DECIMAL,
  pressure DECIMAL,
  PRIMARY KEY (
    (sensor_id, year, month, day),
    hour,
    timestamp
  )
) WITH CLUSTERING ORDER BY (hour DESC, timestamp DESC)
  AND default_time_to_live = 7776000  -- 90 days
  AND compaction = {
    'class': 'TimeWindowCompactionStrategy',
    'compaction_window_size': 1,
    'compaction_window_unit': 'DAYS'
  };

-- リアルタイムデータ取得用
CREATE TABLE sensor_latest (
  sensor_id UUID PRIMARY KEY,
  timestamp TIMESTAMP,
  temperature DECIMAL,
  humidity DECIMAL,
  pressure DECIMAL,
  updated_at TIMESTAMP
) WITH default_time_to_live = 3600;

11. 結論

Apache Cassandra は、高いスケーラビリティと可用性が必要な大規模分散システムに最適なデータベースです。

主な利点

  • 線形スケーラビリティ
  • 高い可用性と障害耐性
  • 大規模なデータセットの効率的な処理
  • 予測可能なパフォーマンス

考慮すべき点

  • 操作の複雑性
  • 最終的一貫性
  • スキーマ設計の重要性
  • 継続的な監視と最適化

Cassandra を効果的に活用するには、その設計思想を理解し、アプリケーションの要件に合わせた適切な設定とスキーマ設計が不可欠です。


参考リソース

  • Apache Cassandra 公式ドキュメント
  • Cassandra Query Language(CQL)リファレンス
  • DataStax Academy
  • Cassandra 運用ガイド