Blogs

データベースシャーディングとは何ですか? その仕組みは?

最新アプリケーションのスケーラビリティとパフォーマンスの向上

January 18, 2024

今日のデータ主導型の世界では、現代のアプリケーションが大量の情報を管理するというますます大きな課題に直面しています。従来のモノリシックデータベースはボトルネックに悩まされ、パフォーマンスが低下し、スケーラビリティが制限されていました。データベースシャーディングは、複数のシャードにデータを分散することでスケーラビリティを高め、パフォーマンスを向上させるように設計された強力なソリューションです。

データベースシャーディングとは

データベースシャーディングは、データベースを水平方向にスケーリングする手法です。データを複数のデータベースインスタンス、つまりシャードに分割することで、パフォーマンスを向上させ、大量のデータが 1 つのデータベースに与える影響を軽減します。(参照: データベースシャーディング)

各シャードは基本的に、データ全体のサブセットを含む個別のデータベースインスタンスまたはサーバーです。シャーディングの目的は、データとデータベースの負荷を複数のシャードに分散させ、分散システムのスケーラビリティ、パフォーマンス、耐障害性を向上させることです。

シャーディングの主な構成要素:

  1. シャードキー: これは、さまざまなシャードにデータを分散するために使用される属性です。これは、特定のデータがどのシャードに属するかを決定するラベルのようなものです。データを均等に分散し、効率的にクエリを実行するには、適切なシャードキーを選択することが重要です。一般的なシャードキーには、ユーザー ID、製品カテゴリ、日付などがあります。
  2. シャード: これらは、データ全体のサブセットを保持する個別のデータベースです。大きなライブラリが複数のセクションに分かれていると想像してみてください。各セクション (シャード) は特定のカテゴリーの本に焦点を当てています。データの合計は、シャードキーに基づいてこれらのシャードに分散されます。
  3. シャードマップ (またはカタログ): これはディレクトリのように機能し、どのシャードに特定のシャードキー値のデータが保存されているかを追跡します。アプリケーションがデータにアクセスする必要がある場合、シャードマップを参照して適切なシャードを探します。タイトルや著者 (シャードキー) に基づいて、特定の本 (データ) を検索するセクション (シャード) がわかる図書館カードカタログのようなものです。
  4. シャードルーター: これはアプリケーション内のコンポーネントか、シャードマップを操作する別のサービスです。アプリケーションロジックからシャードキーを受け取り、シャードマップを使用して目的の操作 (読み取りまたは書き込み) に適したシャードを決定します。その後、シャードルーターはリクエストを特定のシャードに送ります。

シャーディングのメリット

  • 拡張性の強化: シャーディングでは、複数のデータベース (シャード) にデータを分散することで水平スケーリングが可能になります。データ量が増えるにつれて、追加のシャードをシームレスに統合できるため、パフォーマンスを犠牲にすることなくアプリケーションの拡大に対応できるようになります。
  • パフォーマンスの向上: シャーディングは、クエリが個々のシャード内の特定のデータサブセットを対象とできるようにすることで、クエリの実行を最適化します。これにより、スキャンされるデータ量が減り、応答時間が大幅に短縮され、ユーザーエクスペリエンスの応答性が向上します。
  • 可用性の向上: シャーディングはある程度のフォールトトレランスを導入します。1 つのシャードに問題が発生しても、他のシャードは影響を受けないため、システム全体の可用性への影響を軽減できます。これにより、アプリケーションの耐障害性が向上し、サービスの継続性が保証されます。

Node.js での実装

データベースシャーディングとその利点の基礎を理解できたので、Node.js と MongoDB を使った実践的な実装例を見てみましょう。

2 つのシャード (データベースインスタンス) の作成

この例では、2 つのデータベースインスタンスを作成し、両方をホストしています アトラス。必要に応じて Docker またはセルフホストを使用することもできます。

シャードマップの定義

シャードマップを定義するには、製品カテゴリをそれぞれのシャード接続文字列にマップする単純な JavaScript オブジェクトを作成します。

const shardMap = {
    'Clothing': 'database url for clothing products',
    'Electronics': 'database url for electronics products',
    'default': 'database url for all other products'

}

カテゴリに基づいて適切なシャードを返す関数を定義する

製品カテゴリを入力として受け取り、適切なシャード接続を返す関数を作成します。

// Fetch the right shard
const fetchShard = (category) => {
    // get shard credentials
    const credentials = shardMap?.[category]
    // connect with the server
    return new MongoClient(credentials ?? shardMap?.default);
}

商品をアップロードするための API ルートの定義

商品のアップロードを処理する API ルートを設定します。このルートは以下を使用します。 フェッチ・ハード 製品を保管するための正しいシャードを決定する機能。

app.post('/products', async (req, res) => {

    const {products} = req.body;
    for (const product of products) {
        // get database connection for each product
        const client = await fetchShard(product?.category)
        const db = client.db('database-sharding')
        const productCollection = db.collection("products");
        await productCollection.insertOne(product)
    }
    res.send("ok")
})

カテゴリに基づいて商品を返すAPIルートを定義する

カテゴリ別に商品を取得するためのAPIルートを設定します。このルートでは、次のものも使用します。 フェッチ・ハード クエリする正しいシャードを決定する関数。

app.get('/products/:category', async (req, res) => {
    const {category} = req.params;
    try {
        // find out the correct shard
        const client = await fetchShard(category)
        // connect to the database
        const db = client.db('database-sharding')
        const productCollection = db.collection("products");
        const products = await productCollection.find({category}).toArray();
        res.send(products)
    } catch (err) {
        console.log(err)
        res.status(500).json({message: 'Error fetching products'});
    }
});

アプリケーションをテストしてください

アプリケーションをテストするには、Postman や Curl などのツールを使用して API エンドポイントに HTTP リクエストを送信できます。例えば:

  1. 商品をアップロードするには:
  1. カテゴリー別に商品を検索するには:

シャーディングに関する考慮事項とベストプラクティス

データベースシャーディングには、スケーラビリティとパフォーマンスの面で大きな利点がありますが、実装を成功させるには、その複雑さとベストプラクティスを知っておくことが重要です。

  • アプリケーションの複雑さの増大: シャーディングは、アプリケーションとデータベース間の抽象化をさらに強化します。シャードルーティング、シャードキー選択、シャード間での一貫性の問題を管理する必要があります。
  • シャードキー選択: 適切なシャードキーを選択することが重要です。データをシャード全体に均等に分散し、最も頻繁に使用するクエリパターンに合わせる必要があります。シャードキーの選択が不適切だと、ボトルネックになり、シャーディングのメリットが損なわれる可能性があります。
  • スケーラビリティに関する考慮事項: シャーディングは水平方向のスケーリングを可能にしますが、特効薬ではありません。新しいシャードを追加することにはそれなりの管理オーバーヘッドが伴います。データアクセスパターンと成長予測を評価して、シャーディングが特定のニーズに最も適したソリューションかどうかを判断してください。

シャーディングの利点と考慮事項を理解することで、データ需要が進化し続ける中で、Node.js アプリケーションを最適化してスケーラビリティとパフォーマンスを向上させるための意思決定を行うことができます。シャーディングは強力なツールですが、他の強力なツールと同様に、最大限の利益を得るには慎重な計画と実行が必要であることを忘れないでください。