MySQL シャーディング入門ガイド

MySQL シャーディング入門ガイド

序文

リレーショナル データベースは、システムのボトルネックになる可能性が高くなります。単一のマシンのストレージ容量、接続数、および処理能力には制限があります。データ量と同時実行性が増加すると、データベースをセグメント化する必要があります。

データ シャーディングの手段は、データベースとテーブルを異なる部分に分割することです。ライブラリとテーブルのシャーディングには 2 つの側面があります。シャーディング テーブルなしでライブラリのみをシャーディングする場合と、シャーディング ライブラリなしでテーブルのみをシャーディングする場合があります。

データベース分散の核となる内容は、データの分割と、分割後のデータの配置および統合に他なりません。

データベースを複数のテーブルに分割する必要があるのはなぜですか?

サブテーブル

1 つのテーブル内のデータの量が多すぎると、SQL 実行のパフォーマンスに重大な影響を及ぼします。一般的に、単一のテーブルが数百万に達すると、パフォーマンスは比較的低下するため、テーブルをサブテーブルに分割する必要があります。

テーブルを分割するということは、1 つのテーブルのデータを複数のテーブルに入れて、1 つのテーブルのみをクエリすることを意味します。たとえば、テーブルをプロジェクト ID ごとに分割し、1 つのテーブルに固定数のプロジェクト データを配置して、各テーブルのデータ量を制御可能な範囲内で制御できるようにします。

サブライブラリ

経験上、データベースは最大 2000 件の同時リクエストをサポートするときに拡張する必要があり、健全な単一データベースの同時実行値は 1000 前後で維持するのが最適です。すると、1 つのライブラリのデータを複数のライブラリに分割し、アクセスするときに 1 つのライブラリのみにアクセスすれば済みます。

これは、データベースとテーブルのシャーディングと呼ばれます。なぜデータベースとテーブルをシャーディングする必要があるのでしょうか?

  • 同時サポート機能の向上
  • ディスク使用量を削減
  • SQL実行パフォーマンスの向上

データベースとテーブルを分割する方法

写真を直接見てください:

垂直分割の場合、テーブルの垂直分割を回避するために、システム設計の最初にテーブルを適切に設計することをお勧めします。

水平分割は、範囲または特定のフィールド ハッシュによって実行できます。範囲で分割するメリットは、容量の拡張が簡単で、新しいテーブルやデータベースを用意するだけで済むことです。ただし、ホットな問題を引き起こしやすいため、実際に使用する際にはビジネスシナリオと組み合わせて検討する必要があります。ハッシュ分割のメリットは、各データベースやテーブルのリクエスト負荷を均等に分散できることです。デメリットは、容量拡張が難しく、以前のデータを再ハッシュする必要があり、データ移行のプロセスが必要になることです。

シャーディングによって生じる問題

サブデータベースとサブテーブルは、単一のマシンと単一のデータベースによってもたらされるネットワーク IO、ハードウェア リソース、および接続数への負荷を効果的に軽減できます。しかし、いくつかの問題も発生しました。

  • トランザクションの一貫性の問題は、分散トランザクションまたは最終的な一貫性の確保を通じて解決されます。
  • クロスノード関連クエリ結合問題グローバルテーブル、フィールド冗長性、データアセンブリ、ER 断片化
  • ノード間のページング、ソート、集計関数の問題 まず、異なるシャードノードでクエリを実行し、最後に結果を要約またはマージします
  • グローバル主キー重複回避問題 さまざまな分散ID生成アルゴリズム
  • データの移行と拡張の問題が範囲シャーディングである場合、容量を拡張するにはノードを追加するだけで済みます。
    ハッシュの場合、一般的な方法は、まず履歴データを読み取り、次に指定されたシャーディング ルールに従って各シャード ノードにデータを書き込みます。

データ移行

2 つのデータ移行ソリューションを紹介します。

最も低レベルの解決策は、システムをしばらくシャットダウンし、事前に作成されたデータ インポート ツールを使用して単一のテーブルからデータを抽出し、それをサブライブラリとサブテーブルに書き込むことです。

2 番目のソリューションは、デュアル書き込み移行ソリューションであり、より信頼性が高いようです。オンラインシステムでは、以前にデータが書き込まれたすべての場所、追加、削除、変更操作、古いデータベースの追加、削除、変更に加えて、新しいデータベースの追加、削除、変更が追加されます。これは、いわゆる二重書き込みです。システムが展開された後、ソリューション 1 のデータ インポート ツールを実行して、古いデータベースを読み取り、新しいデータベースを書き込みます。書き込み時には、gmt_modified などのフィールドに基づいてデータの最終変更時刻を決定する必要があります。新しいデータベースにデータがない場合、またはデータが新しいデータベースのデータよりも新しい場合にのみ、データが書き込まれます。簡単に言えば、新しいデータを古いデータで上書きすることは許可されていません。

1 回の書き込み後も、不一致が残る場合があります。この場合、プログラムは自動的に新しい検証ラウンドを実行し、新しいデータベースと古いデータベースの各テーブルの各データを比較します。相違点がある場合、プログラムは古いデータベースからデータを読み取り、再度書き込みます。データが完全に一致するまでこのサイクルを繰り返します。

ミドルウェア

サブライブラリとサブテーブル用のより一般的なミドルウェアは次のとおりです。

  • Cobar: これは Alibaba の b2b チームによって開発され、オープンソース化されました。これは、アプリケーション サーバーとデータベース サーバーの間にあるプロキシ レイヤー ソリューションです。アプリケーションは、JDBC ドライバーを介して Cobar クラスターにアクセスします。Cobar は、SQL とデータベースのパーティション分割ルールに従って SQL を分解し、MySQL クラスター内のさまざまなデータベース インスタンスに配布して実行します。読み取り/書き込み分離、ストアド プロシージャ、データベース間の結合、ページングなどの操作はサポートされていません。近年更新されておらず、利用する人もあまりいません。
  • TDDL: Taobao チームによって開発されたクライアント層ソリューションです。基本的な CRUD 構文と読み取り/書き込み分離をサポートしていますが、結合や複数テーブルクエリなどの構文はサポートしていません。現時点ではまだ Taobao のダイヤモンド構成管理システムに依存しているため、あまり使用されていません。
  • Atlas: 360 オープン ソース、プロキシ レイヤー ソリューションに属します。数年間メンテナンスが行われておらず、現在使用している企業はごくわずかです。
  • Sharding-jdbc: Dangdang のオープンソースのクライアント層ソリューションは、ShardingSphere に名前が変更されました。データベースとテーブルのシャーディング、読み取りと書き込みの分離、分散 ID 生成、柔軟なトランザクション (ベスト エフォート配信トランザクション、TCC トランザクション) など、あまり制限のない幅広い SQL 構文をサポートします。また、多くの企業が利用しており、コミュニティも活発です。
  • Mycat: Cobar をベースにしたプロキシ レイヤー ソリューションです。サポートされている機能は非常に充実しています。 Sharding-jdbc と比較すると、新しいです。

要約すると、Sharding-jdbc と Mycat が検討できるオプションです。

Sharding-jdbc などのクライアント層ソリューションの利点は、デプロイメントが不要で、運用および保守コストが低く、プロキシ層での二次転送が不要で、パフォーマンスが高いことです。欠点はカップリングです。
Mycat のプロキシ レイヤー ソリューションの欠点は、一連のミドルウェアを自分で導入して保守する必要があり、運用と保守のコストが高くなることですが、利点はプロジェクトに対して透過的であることです。

MySQL パーティショニング (非推奨)

ここでパーティショニングが導入されているのは、主に分割、データベースとテーブルのシャーディングなどの概念との混乱を避けるためです。
MySQL はバージョン 5.1 以降でパーティション機能をサポートしています。パーティショニングとは、データベースが特定のルールに従ってテーブルを複数のより小さく管理しやすい部分に分割することを意味します。データベースにアクセスするアプリケーションに関しては、論理的には 1 つのテーブルまたは 1 つのインデックスしかありませんが、実際にはこのテーブルは複数の物理パーティションで構成されている可能性があり、これはアプリケーションには透過的です。
MySQL パーティショニングでは、パーティション キーの概念が導入され、非常に大きなテーブルの管理に役立つ分割統治アプローチが採用されています。パーティション キーは、特定の間隔値、特定の値リスト、または HASH 関数に基づいてデータを集計し、ルールに従ってデータが異なるパーティションに分散されるようにするために使用されます。 MySQL 5.7 では、主に 6 つのパーティション タイプが使用できます。

  • RANGE パーティション分割: 指定された連続した間隔範囲に基づいて、データを異なるパーティションに割り当てます。
  • LIST パーティション分割: RANGE パーティション分割と似ていますが、違いは、LIST パーティション分割は列挙値リスト パーティション分割に基づいているのに対し、RANGE は指定された連続間隔範囲パーティション分割に基づいていることです。
  • COLUMNS パーティション分割: RANGE および LIST と似ていますが、パーティション キーが複数の列または非整数にできる点が異なります。
  • HASH パーティション分割: 指定されたパーティション数に基づいて、データは異なるパーティションを法として分散されます。
  • KEY パーティショニング: HASH パーティショニングに似ていますが、MySQL が提供するハッシュ関数を使用します。
  • サブパーティション: 複合パーティションまたは結合パーティションとも呼ばれ、プライマリ パーティションの下に別のパーティションを作成し、データを再度分割します。

LIST パーティションの例を次に示します。

テーブルorders_listを作成します(
  id INT AUTO_INCREMENT、
  顧客姓 VARCHAR(30)、
  ストアID INT、
  営業担当者ID INT、
  注文日 日付、
  注 VARCHAR(500)、
  インデックス idx (id)
) エンジン = INNODB
  PARTITION BY LIST(store_id) (
  パーティション p1
  値 (1, 3, 4, 17)
  インデックスディレクトリ = '/var/orders/district1'
  データディレクトリ = '/var/orders/district1'、
  パーティション p2
  (2, 12, 14)の値
  インデックスディレクトリ = '/var/orders/district2'
  データディレクトリ = '/var/orders/district2',
  パーティション p3
  値 (6, 8, 20)
  インデックスディレクトリ = '/var/orders/district3'
  データディレクトリ = '/var/orders/district3',
  パーティション p4
  値 (5, 7, 9, 11, 16)
  インデックスディレクトリ = '/var/orders/district4'
  データディレクトリ = '/var/orders/district4',
  パーティション p5
  値 (10, 13, 15, 18)
  インデックスディレクトリ = '/var/orders/district5'
  データディレクトリ = '/var/orders/district5'
);

パーティショニングの利点:

  • ストレージ容量を拡張します。
  • クエリを最適化します。 WHERE 句にパーティション条件が含まれている場合、必要なパーティションのみをスキャンしてクエリの効率を向上させることができます。SUM() や COUNT() などの集計関数を含むクエリを実行する場合、各パーティションで並列処理できます。
  • 有効期限が切れたデータ パーティションや保存する必要のないデータ パーティションについては、パーティションを削除することでデータをすばやく削除できます。
  • クエリ データを複数のディスクに分散して、クエリ スループットを向上させます。

要約する

MySQL シャーディングに関するこの記事はこれで終わりです。MySQL シャーディングの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 順序再構築に関する簡単な説明: MySQL シャーディング
  • MySQL シャーディングの詳細
  • MySQL でよく使用されるデータベースとテーブル シャーディング ソリューションの概要
  • MySQLデータベースシャーディングとテーブルシャーディングが完全に崩壊
  • MySQLデータベースとテーブルシャーディング後の主キー処理のいくつかの方法
  • SpringBoot+MybatisPlus+Mysql+Sharding-JDBC シャーディング
  • MySQLデータベースとテーブルを分割するいくつかの方法

<<:  editplus の Zen コーディング例コードの説明

>>:  jsはカスタムドロップダウンボックスを実装します

推薦する

HTML フォーマットの json のサンプルコード

さっそく、コードを直接投稿します。具体的なコードは次のとおりです。 <!DOCTYPE htm...

Tomcat ソースコード起動コンソールの中国語文字化けのデバッグプロセス記録

問題を見つける今日はTomcatのソースコードを勉強するつもりなので、公式サイトからTomcatのソ...

MySQLは実際に分散ロックを実装できる

序文前回の記事では、eコマース シナリオでのフラッシュ セールの例を通じて、モノリシック アーキテク...

値の転送を実現するために、2つの同じレベルのコンポーネントをVueで作成します。

Vue コンポーネントは接続されているため、コンポーネント間で値を渡す必要があるのは避けられません...

docker-machineの使い方の詳しい説明

Docker-machineはDockerが公式に提供しているDocker管理ツールです。これは d...

CSS パフォーマンスの最適化 - will-change の使用方法の詳細な説明

will-change は、要素にどのような変更が行われるかをブラウザに伝え、ブラウザが事前に最適化...

HTMLヘッダータグの使用に関する詳細な説明

HTMLはヘッドとボディの2つの部分で構成されています** ヘッド内のタグはヘッドタグです** タイ...

HTMLのmarquee属性でテキストを踊らせる

構文: <marquee> …</marquee>モバイル属性マーキーを使用...

aタグ疑似クラスの機能と記述順序は何ですか?

a タグ疑似クラスの役割: 「:link」: 訪問されていないタグの状態。 「:visited」: ...

WindowsでiTunesのバックアップパスを変更する方法

0. 準備: • iTunesを閉じる• タスクマネージャーでiTunesから始まるサービスを終了し...

XHTML と CSS の Web ページ作成の問題に対する解決策

XHTML CSS ページ制作中に遭遇する問題の解決策は、解決策と呼ぶには少々大げさです。せいぜい、...

CSS スティッキー配置位置の詳細な説明: スティッキー問題の落とし穴

前書き: position:sticky は CSS ポジショニングの新しい属性です。相対ポジショニ...

JavaScript で外部変数にアクセスするサブ関数の 3 つのソリューション

序文Web ページを作成するときに、次のような状況に遭遇することはよくあります。 <本文>...

Navicat は CSV データを MySQL にインポートします

この記事では、Navicatを使用してcsvデータをmysqlにインポートする方法を参考までに紹介し...

アイデアを war パッケージにパッケージ化し、tomcat にデプロイしてアクセス パスの問題 (図とテキスト)

Web プロジェクトを war にパッケージ化するアイデアにとって最も重要なことは、アトリフィカを...