MongoDBにおけるシャーディングの構成と運用方法

MongoDBのシャーディング(分片)は、データの増大に伴い単一のサーバーではストレージ容量や処理能力が不足する場合に、データを複数のサーバーに分散させることで水平スケーリングを実現する技術です。

シャーディングが必要となる背景

データ量やトラフィックが増加すると、以下のような課題に直面します。シャーディングはこれらの問題を解決するために導入されます。

  • 書き込み負荷の集中: すべての書き込みがプライマリノードに集中し、パフォーマンスが低下する。
  • メモリ不足: ワーキングセットが物理メモリに収まらなくなり、ディスクI/Oが増大する。
  • ストレージの限界: 単一マシンのディスク容量を超えたデータ保持が必要になる。
  • コスト効率: 高性能な単一サーバー(垂直スケーリング)を導入するよりも、安価なサーバーを並列化する方がコストを抑えられる。

クラスターを構成する主要コンポーネント

MongoDBのシャーディング環境は、主に以下の3つの要素で構成されます。

1. シャード (Shard)

実際にデータを保持するコンポーネントです。可用性を高めるため、本番環境では各シャードをレプリカセットとして構成するのが一般的です。

2. 設定サーバー (Config Server)

クラスターのメタデータ(どのデータがどのシャードにあるか等)を管理するサーバーです。クラスター全体の構成情報を保持する重要な役割を担います。

3. クエリールーター (mongos)

アプリケーションとクラスターの仲介役となるインターフェースです。アプリケーションからは単一のデータベースのように見え、mongosが適切なシャードへリクエストを振り分けます。

シャーディングの構築手順

以下に、基本的なシャーディング環境を構築する流れを説明します。ここではテスト環境を想定し、異なるポートで各プロセスを起動します。

手順1:シャードサーバーの起動

まず、データを保存する複数のmongodインスタンスを起動します。

# データディレクトリの作成
mkdir -p /data/shard/rs0_1
mkdir -p /data/shard/rs0_2

# インスタンスの起動
mongod --shardsvr --port 30001 --dbpath /data/shard/rs0_1 --logpath /data/shard/rs0_1.log --fork
mongod --shardsvr --port 30002 --dbpath /data/shard/rs0_2 --logpath /data/shard/rs0_2.log --fork

手順2:設定サーバーの起動

次に、クラスター情報を管理する設定サーバーを起動します。

mkdir -p /data/shard/config
mongod --configsvr --port 40001 --dbpath /data/shard/config --logpath /data/shard/config.log --fork

手順3:クエリールーター (mongos) の起動

設定サーバーを指定して、ルータープロセスを立ち上げます。

mongos --configdb localhost:40001 --port 50000 --logpath /data/shard/mongos.log --fork

手順4:クラスターへのシャード追加と有効化

mongosに接続し、各ノードをシャードとして登録します。

# mongosへ接続
mongo --port 50000 admin

# シャードの追加
db.runCommand({ addshard: "localhost:30001" })
db.runCommand({ addshard: "localhost:30002" })

# データベースのシャーディング有効化
db.runCommand({ enablesharding: "app_db" })

# コレクションに対してシャードキーを設定しシャーディングを開始
db.runCommand({ shardcollection: "app_db.orders", key: { "order_id": 1, "created_at": 1 } })

レプリカセットを用いた高度な構成

可用性を重視する場合、各シャードおよび設定サーバー自体をレプリカセットとして構成します。

設定サーバーのレプリカセット化

# 設定サーバー1, 2の起動
mongod --configsvr --replSet cfs --port 40001 --dbpath /data/conf1 --fork --logpath /data/conf1.log
mongod --configsvr --replSet cfs --port 40002 --dbpath /data/conf2 --fork --logpath /data/conf2.log

# 初期化 (mongo shellより)
rs.initiate({
  _id: "cfs",
  configsvr: true,
  members: [
    { _id: 0, host: "localhost:40001" },
    { _id: 1, host: "localhost:40002" }
  ]
})

ルーターからの接続設定

レプリカセット形式の設定サーバーを指定してmongosを起動します。

mongos --configdb cfs/localhost:40001,localhost:40002 --port 50000 --fork --logpath /data/mongos.log

このようにシャーディングを構成することで、アプリケーション側のコードを大きく変更することなく、データベース層の容量とスループットを動的に拡張することが可能になります。

タグ: MongoDB Sharding Scalability database-administration

7月9日 00:01 投稿