分散ルーチンのサブデータベースとテーブルについてのランダムな話

「サブデータベースとサブテーブルのランキング」なので、何について話したいのか、何について話さないのかを決める必要があります。

  1. まず、特定のサブデータベースサブテーブルフレームワークの実装とソースコードについては説明しません。これは、説明の範囲ではありません。
  2. 私たちはアイデアについて話し合っており、主にデータベースとテーブルを分割する方法のルーチン、落とし穴とは何か、そしてあなたはどのような経験を持っているかについて話し合っています。具体的な詳細については説明しません。もちろん、自分の能力には限りがありますが、他の人を惹きつけたいと思っています。
  3. サブデータベースとサブテーブルは特効薬ないことを明確にする必要があります。これは、MySQLのスタンドアロンパフォーマンスが十分でない場合にコストを節約するための単なる方法です。上司にとって、彼はコストを節約するだけでなく、ビジネスをサポートし、安定した耐久性のあるパフォーマンスを提供したいと考えています。

プログラマーは創意工夫を凝らし、頭を悩ませ、日々のハードワークと練習を行い、最後に2つの主な方法を生み出します。

  1. エージェント埋め込みモードは、jarパッケージを使用してコードに統合します。コードは、ルーティングルールとシャーディングキーを使用して、データベースとテーブルを分割します。これは埋め込みモードです。
  2. csモード(クライアントサーバーモード)は、mycatなどの3パーティコンポーネントを提供します。mycatと同様に、シャーディングスフィアのプロキシモードです。集中化が行われ、3パーティコンポーネントの高可用性を保証する必要があります。 。

より良い技術的選択がある場合、それ自体が複雑なソリューションであるため、サブライブラリやサブテーブルは使用しません。これは単なる妥協案です。NewSQLと商用データベースの方が適しています(たとえば、Oracleの場合、ほとんどのシナリオでパフォーマンスは十分ですが、コストは高くなります)。

ある日、oceanbaseやtidbなどの優れた経済的なnewSQLがあれば、基本的にサブデータベースとサブテーブルに別れを告げることができます。

データベースとテーブルの戦略を使用することを選択した理由は、基本的に、一方では使用コストが高すぎないため、一方ではスタンドアロンDBデータベースのパフォーマンスが十分ではないためです。一方、newSQLは現在、未成熟で高すぎるため、あえて使用しないでください。

サブライブラリとサブテーブル、豊富なオープンソースフレームワーク、コミュニティ、成熟したケースのメーカーはたくさんあるので、

直接の理由は、アリがプラットフォーム上にいるということです。私たちの国内の精神は、アリが使用するものとアリのやり方を使用することです。私はこの傾向に真剣に取り組んでいます。私の考えでは、私たち自身のテクノロジーについてはまだ前向きな見方があります。アリに頼るのではなく、テクノロジーだけに頼るのが最善です。

たくさん言ったので、トピックに戻って問題を調べ始めます。

1.サブテーブルのみを作成しても大丈夫ですか?それでもテーブルを分割してライブラリを分割する必要があります。分割されている場合、ライブラリは複数のサーバー上にありますか?これを考慮する方法

現在の事業規模だけでなく、今後3〜5年の事業動向も見ていきたいと思います。

技術の選択に関しては、私たちの目標は常に現在のビジネスに最も適したもの、最低のコスト、最高の利益を選択することであり、適切なものが最良です。

私たちが選択する最善のソリューションは、技術チームが保持できるソリューションです。選択が現在の事業開発に適さなくなった場合は、より適切なものに変更できます。これは物事の発展の必然的な法則です。

または、ビジネスはより高いレベルに発展しておらず、すでにGGであり、それはちょうどいいです。より良い施設を購入するためにお金を無駄にしないでください。損失を止めるだけです。

または、現在の計画は本当に十分ではありません、私たちはより強力なセットを変更しました、それはより多くのお金がかかりますが、より多くの人々を喜ばせます、しかしこれは私たちの心ではなく、私たちの目的それ自体が適切な技術アーキテクチャを通じてビジネス開発をサポートしますそしてより良いコード。

一文の要約は、あなたがお金を使わなければならないので、それからそれを使うということです。

シーンごとのディスカッション

写真は千の言葉に値します。これら2つのシナリオを別々に見てみましょう。

以下のための オフラインデータ分析シナリオ

主にデータの分析に使用され、分析データの後のデータは削除できるため、サブテーブルのみで十分です。非同期タスクは、数か月/日のデータを削除します。

分散ルーチンのサブデータベースとテーブルについてのランダムな話

 

以下のための リアルタイムのビジネス・システム

大量のトラフィックを伝送する必要がある分散ビジネスシステム2Cの場合は 、データベースとテーブルの両方検討することをお勧めし ます

分散ルーチンのサブデータベースとテーブルについてのランダムな話

 

サブライブラリの前提条件、推定ビジネス

サブデータベースとサブテーブルの前提は、取引量を見積もることです。経験値を提供します。これは、最も適切な値を表すものではなく、単なる定性分析です。

QPS 500-1000以下,   那么采用主从读写分离,基本上足够支撑业务了;

QPS 1000-10000,考虑分布分表是一个比较合适的事情 

12000TPS 30000QPS 32库 1024表 
1000多万 16000QPS 16库512表

基本的に:サブデータベースとサブテーブルは1回限りの販売です。初期の設計は非常に重要であり、後の拡張とデータ移行の難しさを決定します。予備設計では、今後3〜5年の計画が必要になる可能性が高く、短期的には1〜2年の計画が必要です。計画に従って、データベースを分割するかどうかを決定し、テーブル、およびライブラリとテーブルの数。

問題自体に戻ると、これは主に現在の取引量と取引量の成長率に依存します。

これらの次元に基づいて、一連の式を示します。

某年数据增量M = (1 + 数据年增速K)^ n  * 初始数据量 N

第一年增量 M1 = (1+k)   * N 
第二年增量 M2 = (1+K)^2 * N
第三年增量 M3 = (1+K)^3 * N

三年数据总量 M' = N + m1 + m2 + m3

1000万個のデータを含む1つのテーブルで計算してみましょう。合計で複数のテーブルがあります。現在、必ずしも1000wである必要はありませんが、2000w〜5000wで問題ありません。これは、最初に経験値であり、次に定量分析が必要です。

定量分析には圧力テストが必要です。オンライン構成のストレステストを実行するには、ライブラリインスタンスを使用する必要があります。この構成では、システムスループットに影響を与えることなく、1メートルの最大容量が安全なリンクになります。これは設計の初期段階で適切にガイドできます。 。

次に、サブデータベースが必要な場合、各データベースが独立したインスタンスであることを確認する必要があるかどうかについて説明します。

いいえ、特定の問題を詳細に分析する必要があります。

開発環境、つまりRDがコードを書くためのライブラリを開発する場合、1台のマシンで複数のライブラリセットを使用できます。結局のところ、開発環境には並行性がなく、開発に使用されるのはせいぜいです。ストレステストに使用しない限り問題ありません。

オンライン環境の場合は、ライブラリを複数のマシンに展開することに加えて、読み取りと書き込みの分離とライブラリの高可用性も考慮する必要があります。オンラインとオフラインの主な違いは、オンラインには高可用性の要件がありますが、オフラインにはないということです。

2つの違いについて考えてみてください違いは、コスト管理にあります。

データベースをマシンインスタンスにデプロイする場合は、シナリオ、コスト、およびデータベースが必要かどうかによって異なると結論付けます。特定の問題を分析します。

2.ルーティングキーを生成する方法は?スノーフレークアルゴリズムを使用できますか?元のデータベースの主キーが自己増加する場合、固有のビジネス上の制約はありません。移行後、元のデータをサブデータベースとサブテーブルにルーティングするにはどうすればよいですか。

良い質問。

まず、ルーティングキーを生成する方法は?

基本的に、これは信頼性の高い分散発行体を実装する方法の問題ですアイデアについて話すことができるので、それについて話すだけですが、一人で話すのは長い間です。

アイデア:

一部のフレームワークには、shardingSphere / ShardingJDBCクラスのSnowFlakeアルゴリズムなどの独自の主キージェネレーターがあります。

  1. UUID:文字列形式、確かに一意ですが、読みやすさが低く、数学的な計算が難しく、直感的ではなく、比較的長く、大きなスペースを占有します
  2. SNOWFLAKE:リーフを改善するために使用することも、リーフ自体を分散番号発行者の完全なセットとして使用することもできます。また、高可用性が保証されています。

もちろん、他の方法もあります。

すでにサブデータベースとサブテーブルを作成しているため、システムも分散されている可能性が高く、インプロセスナンバリングを使用することは理想的な方法ではありません。

分散番号発行サービスを単純​​に実装する場合は、redisインクリメントを使用して一連の発行者を実装するか、データベースの自己インクリメントの一意のIDを使用して実装できますが、それでも実装するには自分で開発する必要があります。番号発行システム。

前の写真を使ってあなたの考えを表現してください。この内容は後で別の記事に書かれます。

分散ルーチンのサブデータベースとテーブルについてのランダムな話

 

要約すると、本質的に、これは信頼できる分散型発行体を実装する方法の問題です。

したがって、特定の分散番号発行メカニズムに依存するという問題を絡める必要はありません。最終的な選択に注意を払い、より多くのトレードオフを行うだけです。

3.単一のデータベースであり、ルーティングキーがなく、主キーが一意の識別子として使用されている場合、サブデータベースとテーブルをどのように操作できますか?

非常に簡単です。元の一意の識別子は何ですか?これは、サブデータベースサブテーブルの後で使用できます。

ただし、ビジネス属性キーがないため、データ移行後にビジネス属性の自然な主キーを追加することをお勧めします。また、新しいルーティングルールを構成する必要がある可能性が高くなります。

具体的なプロセスは次のとおりです。

  1. データの移行
  2. ルーティング構成を変更して、新しいクエリルール、サブデータベースおよびサブテーブルのルーティングルールを指定します
  3. DAOやリポジトリに含まれるコードなどのCRUDコードをコードに含めるようにコードを変更し、コードにルーティングルールを追加します。簡単に言えば、元のIDを使用してクエリ、挿入、削除を実行できますが、主に変更点は、ルーティングルールが必要なことです。

テーブルに関係なく、データベースのテーブルへの移行のコアと言います。データの整合性を確保するには、コードをリファクタリングする必要があります。コードを変更する必要のない包括的なプログラムを作成することは困難です。妥協して複雑さの程度を減らすだけです。

元の主キーIDは、新しいデータベースサブデータベースとサブテーブルに移行されました。これは継続的ではありませんが、一意である必要があります。新しいデータベーステーブルの自動インクリメント主キーは、引き続き必要ですが、ビジネス属性はありません。サブデータベースの理由テーブルが分割された後、主に挿入とクエリの効率を向上させるために、自動インクリメントの主キーが必要になります。主キーインデックスツリーを介して、テーブル操作に戻ります。

これは、元々自動インクリメントIDを使用してビジネス属性を持っていたという事実と同等です。これは余談です。ビジネスの意味を表すために自動インクリメントの主キーを使用しないようにしてください

3.シャードキーの選び方

私たちの答えはまだ正確な声明を出すことはできません。私はビジネスシナリオの要件に従って選択する必要があるとしか言えません。

これは一般的すぎるので、いくつかの例で表現しましょう。

对于用户表,使用用户唯一标识, 如:userId作为分片键;
对于账户表,使用账户唯一标识,如:accountId作为分片键;
对于订单表,使用订单唯一标识, 如:orderId作为分片键;
对于商家相关信息表,使用商家唯一标识, 如:merchantId作为分片键;
......

ユーザーの注文を確認する場合は、userIdを使用してルーティングテーブルに移動し、注文を注文テーブルに挿入して、ユーザーのすべての注文をテーブルシャードに分散できるようにする必要があります。これにより、分散トランザクションの導入を回避できます。

たとえば、ディメンションがユーザーではなく他のディメンションであると言う場合、特定のマーチャントのすべてのユーザーの注文クエリます

次に、マーチャントのmerchantIdを使用してデータのコピーを保存する必要があります。ルーティングするときは、マーチャントIDを使用してルーティングします。このマーチャントのユーザー注文である限り、マーチャントの注文テーブルに書き込みます。次に、注文について商人が所属している、私たちシャードから入手できます。

上記の説明を明確に表現するには、図を使用してください。

ユーザーの場合、シャーディングキーの機能は次のとおりです
。usertable.png

マーチャントの場合、
シャードキーの機能は次のとおりです。merchanttable.png

したがって、結論は次のとおりです。ビジネスシナリオの要件に従って選択し、特定の問題を詳細に分析し、クエリの効率を向上させるために分散トランザクションが導入されないようにする必要があります。

さらに、主流のアプローチでは、複雑なクエリが必要な場合は、異なるディメンションに基づいて二重に書き込むか、ElasticSearchやハイブを使用するなどの異種メソッドを導入して直接クエリを実行できます。

4.データをバッチで挿入する場合、実際のビジネスで分散トランザクションを実行するかどうかに関係なく、各サブデータベースに挿入されます。

3番目の質問も多かれ少なかれこの質問への答えに言及しました。

サブデータベースとテーブルを実装するプロセスでは、分散トランザクションの導入を回避するように努める必要があります。

上記の3番目の質問から、ルーティングキーがある場合、問題ははるかに単純であることがわかります。ほとんどの場合、分散トランザクションを導入する必要はありませんが、導入しないと苦痛になります。

異常な挿入および挿入トランザクションシナリオを確実にする必要がある場合は、分散トランザクションが必要です。しかし、これは非効率的で不適切です。

第一に、順不同の挿入シナリオは多くありません。第二に、分散トランザクションが導入された場合、トランザクションの強度は小さくなく、挿入のパフォーマンスに大きな影響を与えます。最善の方法ではありません。

結果整合性に基づいてそれを行うことをお勧めします。そうしないと、分散トランザクションの導入が効率に大きく影響し、システムの複雑さが増します。私たちの設計システムの目的は、複雑なソリューションを必要としないことだと思います。お茶を飲む時間があります。何か他のことをしてみませんか。

したがって、この質問の結論は次のとおりです。分散トランザクションを回避するようにしてください。分散トランザクションを導入する必要がある場合は、トランザクションの範囲と強度を最小限に抑える必要があります。妥協を通じて、スキームの実現可能性についてさらに検討します。
パフォーマンスは非常に重要です。分散トランザクションなしで実行できます。実行方法は、結果整合性を使用します。

ただし、「分散トランザクションは避けられないので、どうすればよいですか」と言う場合。次に、それを使用します。必要がない場合は、エンティティを増やさないでください。あなたがそれを使わなければならないならば、それを使うだけで、言うまでもありません。

5.ライブラリに多数のテーブルがあり、1つのテーブルがテーブルに分割されている場合、テーブルとテーブルを分割せずにテーブルを配置するにはどうすればよいですか?ブランチ内の特定のライブラリに割り当てられていますか?

基本的に:これは、非サブデータベースとサブテーブルのデータ、およびサブデータベースとサブテーブルのデータの分散の問題です。

実際、サブデータベースとサブテーブルのミドルウェアには、対応する機能があることがよくあります。この機能は、デフォルトのルーティングルールと呼ばれることがよくあります。どのように理解しますか?

つまり、サブデータベースとサブテーブルのないこれらのテーブルの場合デフォルトのルーティングルールで 十分であるため、常にデフォルトのデータソースにルーティングされます。

ホワイトリストに相当します。ミドルウェアのドキュメントを検索して、デフォルトのルーティングルールがどのように構成されているかを確認します。基本的に、ミドルウェアはこの問題を考慮します。ShardingSphereの場合、構成例は次のとおりです。

CustomerNoShardingDBAlgorithm
    default-table-strategy: (缺省表分区策略)
        complex:
        sharding-columns: db_sharding_id
        algorithm-class-name: com.xxx.XxxClass
    tables:
        ops_account_info: (必须要配置这个,才能使用缺省分表策略)
        actual-data-nodes: db-001.ops_account_info

詳細な例を挙げます。例:

サービスが元のデータベースのサブデータベースである場合(たとえば、ユーザーデータベースがuser01とuser02に分割されている場合)、非分散テーブルを特定のデータベースにルーティングするように強制しますか(たとえば、非分散テーブルをルーティングします)。ユーザーへのテーブル01)?

ここで説明する本質は次のとおりです。デフォルトのルーティングルール。デフォルトのルーティングルールに従うように特定のテーブルを構成するだけで済みます。たとえば、ユーザーテーブル、注文テーブル、構成テーブルがあります。その中には、ユーザーテーブルと注文があります。サブデータベースサブテーブルであり、configにはサブデータベースとサブテーブルがありません。

次に、構成テーブルをユーザーライブラリの0ライブラリ、1ライブラリ、2ライブラリ、どこにでも配置するだけで済みます。

配置後は、サブデータベースとサブテーブルミドルウェアの構成ファイルでデフォルトのルーティングルールを構成し、特別に構成テーブルを構成するだけです。構成テーブルを確認して、指定されたライブラリに移動するだけです。

他も同様ですが、そのような要求がある限り、対応する構成を追加してください。

どのテーブルがルーティングルールに従わないかをミドルウェアに明示的に伝え、これらのテーブルが配置される場所を伝える必要があります。
少量のリクエストでライブラリに配置するのが最善です。または、ライブラリを個別に構築することもできます。ライブラリサブデータベースサブテーブルを実行しないテーブルを配置し、実行する
ルーティングルールを構成しません。実際、これは引き続きデフォルトのルーティングルールです。

あなたはなぜこれをやっているのですか?意図は何ですか?

私の理解では、データベースとテーブルを分割する理由は、リクエストが非常に大きく、同時実行性を減らす必要があるためです。リクエストの頻度が低いテーブルの場合、データベースとテーブルを分割せずにテーブルを使用できます。または、単一のテーブルで使用する場合は、デフォルトのルーティングルールとして構成するだけです。

8.データ移行プロセスとデータの整合性を確保する方法

簡単に言えば、データ移行はデータの二重書き込みに依存し、データの整合性はデータの整合性の検証に依存します。

移行の場合、次の手順があります。

分散ルーチンのサブデータベースとテーブルについてのランダムな話

 

  1. 最初にコードを変更し、デュアルライトサブデータベースサブテーブルコードを追加します。オンラインにします。
  2. データの二重書き込み、同期増分データを開始します。二重書き込み、主な目的は、同期データの全量の期限であるリアルタイムデータに追いつき、この時間以降のデータが確実に完了するようにすることです(同時に、非同期データ整合性チェックを通じてプログラムはデータの整合性を検証しますが、二重書き込みの信頼性を確保できる場合は、この比較を実行できるかどうかを確認できます。実行することをお勧めします)
  3. 履歴データの全量が同期され、データの整合性が検証されます。通常、データの全量が同期され、同期書き込みの方法は必要ありません。その理由は、同期書き込みではコード結合が高いためです。一方、システムに影響を与えます。したがって、非同期で記述することがよくあります。このプロセスを次のテキストで示します。
  4. 二重書き込みコードを削除し、サブデータベースとサブテーブルの完全なロジックをクエリします。
    完全なデータ同期が完了したら、スイッチを使用して、完全な読み取り/書き込みサブデータベースとサブテーブルロジックに切り替えます。現時点では、古いロジックにはリクエストルーティングがありません。古いロジックをオフラインにするためのリリースウィンドウを見つけるだけで済みます。この時点で、行はサブデータベースとサブテーブルのコードフローに完全に移行されています。

最後に、私たちは戻らなければなりません、私たちは戻らなければなりません、私たちは戻らなければなりません!

元のリンク:http://wuwenliang.net/2021/01/09/Distributed Routines:Discussing the Sub-database and Sub-table /

この記事がお役に立てば幸いです。私の公式アカウントをフォローし、キーワード[インタビュー]に返信して、Javaのコアナレッジポイントとインタビューギフトパッケージをまとめてください。共有する技術的な乾物の記事や関連資料がもっとあります。みんなが一緒に学び、進歩できるようにしましょう!

おすすめ

転載: blog.csdn.net/weixin_48182198/article/details/112436867