Meituan Dianpingの分散データアクセス層ミドルウェアMTDDLの詳細な説明

Meituan Dianpingの分散データアクセス層ミドルウェアMTDDLの詳細な説明

背景

2016 年第 3 四半期の初め、Meituan Takeout Order 2.0 のリリース後、加盟店数と商品数が急増し、商品ライブラリの容量とピーク書き込み QPS がすぐに大きな圧力に直面すると予測されました。これは、オンライン サービスのクエリ パフォーマンス、DB (データベース、以下 DB) マスター スレーブの遅延、テーブル変更の難しさなどの一連の問題にも影響します。

[[273412]]

上記の問題を解決するには、通常 2 つの解決策があります。最初の解決策は、既存の製品ライブラリを直接垂直に分割することです。これにより、書き込みピーク QPS の過剰と DB マスター スレーブ遅延という現在の問題を軽減できます。 2 番目の解決策は、既存の大規模なコモディティ データベースを個別のデータベースとテーブルに分割して、既存の問題を根本的に解決することです。ソリューション 1 は実装期間が短いですが、問題を一時的にしか解決できません。データベースとテーブルを分割することは避けられないことがわかります。

シャーディングデータベースとテーブルのソリューションを決定した後、テイクアウト注文、決済、メインサイト向けのシャーディングデータベースとテーブルの実装ソリューションを調査し、業界の多くのシャーディングデータベースとテーブルミドルウェアも調査しました。パフォーマンス、安定性、実装コストを総合的に考慮した結果、テイクアウト商品のシャーディングプロジェクトをサポートするために、クライアント側シャーディングミドルウェアMTDDLを独自に開発することを決定しました。これがMTDDLの起源です。

もちろん、MTDDL の設計と開発においては、MTDDL の汎用性、拡張性、機能の包括性、アクセスの容易さを十分に考慮しました。これまで合計4つのフェーズが開発され、MySQLの動的データソース、読み書き分離、分散型一意主キージェネレーター、シャーディング、接続プール、SQLモニタリング、動的構成などの一連の機能を実現しました。シャーディングアルゴリズムと分散型一意主キー生成アルゴリズムの高いスケーラビリティをサポートし、フルアノテーションモードでのアクセスをサポートし、ビジネス側で構成ファイルを導入する必要がありません。

以下では、いくつかの業界ソリューションと MTDDL の設計目標について詳しく説明し、ソース コードの観点から MTDDL の論理アーキテクチャ全体と具体的な実装を分析します。

業界調査

業界コンポーネントの実装ソリューションの概要、機能、利点、欠点 Atlas Qihoo 360 は、開発および保守されている MySQL プロトコルに基づくデータ中間層プロジェクトです。 MySQL クライアントおよびサーバー プロトコルを実装し、サーバーとしてアプリケーションと通信し、クライアントとして MySQL と通信します。プロキシベースにより、読み取りと書き込みの分離と単一データベースのシャーディングを実現します。機能はシンプルで、パフォーマンスと安定性に優れています。シャーディングはサポートされていません。 MTAtlas は、オープンソースの Atlas をベースに、元の Meituan DBA チームによって行われた一連のアップグレードと変換です。プロキシベースでは、読み取りと書き込みの分離と単一データベースのシャーディングをベースとしたシャーディングの機能開発が完了しました。 Atlas をベースにしたシャーディングをサポートします。当時はまだテスト段階であり、ビジネス関係者が TDDL を使用することは推奨されていません。 Taobao は自社のビジネス特性に基づいて TDDL フレームワークを開発しました。これは主に、アプリケーションに対するシャーディングの透明性と異種データベース間のデータ複製の問題を解決します。集中型構成に基づく JDBC です。データソースはクライアントベースで実装され、動的なデータソース、読み取り/書き込み分離、およびシャーディングを実現します。シャーディングの機能はまだオープンソース化されておらず、公開されているドキュメントもほとんどありません。 diamond (Taobao が内部で使用する永続構成を管理するシステム) に依存する必要があります。Zebra Zebra は、データ ソース、DAO、監視などのデータベースを処理するために Dianping が内部で使用するミドルウェア セットです。動的データ ソース、読み取り/書き込み分離、シャーディング、CAT を実現するクライアント ベースです。監視機能は完全であり、監視アクセスは比較的複雑です。当時は、c3p0、Druid、Tomcat JDBC などの接続プールのみがサポートされており、シャーディング アルゴリズムは Groovy 式のみをサポートしていたため、拡張が容易ではありませんでした。

設計目標

Meituan Dianping の分散データ アクセス層ミドルウェアである MTDDL (Meituan Distributed Data Layer) は、会社全体に共通のデータ アクセス層サービスを提供することを目的としています。 MySQL 動的データ ソース、読み取り/書き込み分離、分散一意主キー ジェネレーター、サブライブラリとサブテーブル、動的構成などの機能をサポートします。また、クライアントの観点からデータ ソースのさまざまな側面 (接続プール、SQL など) の監視もサポートします。今後はNoSQLやCacheなど複数のデータソースへの対応も検討していく予定です。

特徴

  • 動的データソース
  • 読み取りと書き込みの分離
  • 分散型ユニークプライマリキージェネレータ
  • サブライブラリとサブテーブル
  • 接続プールとSQL監視
  • 動的構成

論理アーキテクチャ

次の図は、完全な DAO レイヤー挿入メソッド呼び出しシーケンス図であり、MTDDL の論理アーキテクチャ全体を簡単に説明しています。これには、分散された一意の主キーの取得、動的データ ソースのルーティング、SQL 追跡の監視が含まれます。


具体的な実装

動的データソースと読み取り/書き込みの分離

Spring JDBC AbstractRoutingDataSource に基づいて、MultipleDataSource 動的データ ソース クラスが拡張され、動的データ ソース アノテーションと AOP を通じて実装されます。

動的データソース

MultipleDataSource 動的データ ソース クラスは、Spring JDBC AbstractRoutingDataSource 抽象クラスを継承し、determineCurrentLookupKey メソッドを実装し、setDataSourceKey メソッドを通じて dataSourceKey を動的に調整することで、データ ソースを動的に調整する機能を実現します。クラス図は次のとおりです。


動的データソース AOP

ShardMultipleDataSourceAspect は、DAO メソッドを強化する動的データ ソース アスペクト クラスです。特定のデータ ソースを指定するために、DataSource 動的データ ソース アノテーションをスキャンして、対応する dataSourceKey を取得します。具体的なフローチャートは以下のとおりです。


設定と使用例

  1. /**
  2. * 参照構成
  3. */
  4. <bean id= "multipleDataSource"クラス= "com.sankuai.meituan.waimai.datasource.multi.MultipleDataSource" >
  5. /** データソースの設定 */
  6. <プロパティ= "targetDataSources" >
  7. <マップキー-type= "java.lang.String" >
  8. /** データソースの書き込み */
  9. <エントリキー= "dbProductWrite"値参照 = "dbProductWrite" />
  10. /** データソースを読み取ります */
  11. <エントリキー= "dbProductRead"値参照 = "dbProductRead" />
  12. </マップ>
  13. </プロパティ>
  14. </bean>
  15. /**
  16. * DAOは動的なデータソースアノテーションを使用します
  17. */
  18. パブリックインターフェース WmProductSkuDao {
  19. /** データソースの追加、削除、変更、書き込み */
  20. @データソース( "dbProductWrite" )
  21. パブリックvoid挿入(WmProductSku sku);
  22. /** データソースをクエリする */
  23. @データソース( "dbProductRead" )
  24. パブリックvoid getById(long sku_id);
  25. }

分散型ユニークプライマリキージェネレータ

ご存知のとおり、シャーディングを行う際に最初に解決しなければならないのは、分散された一意の主キーの問題です。業界には関連するソリューションが多数存在します。


まとめると、オプション 3 の欠点は何らかの方法で回避できますが、他のオプションの欠点に対処するのは難しいため、オプション 3 が選択されます。現在、このソリューションは Meituan-Dianping の技術エンジニアリング部門によって実装されており、分散 ID 生成システム Leaf と MTDDL がこの機能に統合されています。

分散ID生成システムLeaf

Meituan Dianping の分散 ID 生成システム Leaf は、実際には DB ベースのチケット サービスです。共通のチケット テーブルを使用して分散 ID の永続性を実現し、更新ステートメントを実行してチケットのバッチを取得します。取得されたチケットはメモリ内に割り当てられ、割り当て後に次のチケットのバッチが DB から取得されます。全体的なアーキテクチャ図は次のとおりです。


各ビジネス タグは DB レコードに対応しており、DB MaxID フィールドにはタグに現在割り当てられている最大 ID 値が記録されます。

IDGenerator サービスが開始されると、DB から番号セグメントが適用されます。受信番号セグメントの長さは genStep = 10000 です。DB トランザクションは MaxID = MaxID + genStep を設定します。 DB 設定が成功すると、番号セグメントの割り当てが成功します。各 IDGenerator 番号セグメントの割り当てはアトミック追加によって行われ、割り当てが完了すると新しい番号セグメントが再度適用されます。

一意の主キー生成アルゴリズムの拡張

MTDDL は、Leaf アルゴリズムを統合するだけでなく、IDGenStrategy インターフェイスを実装するための新しい一意の主キー生成戦略クラスを追加することで、一意の主キー アルゴリズムの拡張もサポートします。 IDGenStrategy インターフェイスには 2 つのメソッドが含まれています。getIDGenType は一意の主キー生成戦略を指定するために使用され、getId は特定の一意の主キー生成アルゴリズムを実装するために使用されます。クラス図は次のとおりです。


サブライブラリとサブテーブル

動的データ ソース AOP に基づいて、シャーディング AOP が拡張され、シャーディング ShardHandle クラスを通じてシャーディング データ ソース ルーティングとシャーディング計算が実装されます。 ShardHandle は ShardContext クラスに関連付けられており、ShardContext はすべてのシャーディング アルゴリズムをカプセル化します。クラス図は次のとおりです。


データベースとテーブルのシャーディングのフローチャートは次のとおりです。


分割データベースと分割テーブルのモジュロアルゴリズム

シャーディングに使用されるデフォルトのアルゴリズムはモジュロ アルゴリズムです。テーブル シャーディング アルゴリズムは (#shard_key % (group_shard_num * table_shard_num)) であり、データベース シャーディング アルゴリズムは (#shard_key % (group_shard_num * table_shard_num)) / table_shard_num です。ここで、group_shard_num はシャードの数、table_shard_num は各データベースのシャードの数です。

たとえば、大きなテーブルを 100 個の小さなテーブルに分割し、それらを 2 つのデータベースに分散すると、0 ~ 49 は最初のデータベースに含まれ、50 ~ 99 は 2 番目のデータベースに含まれます。コア実装は次のとおりです。

  1. パブリッククラスModStrategyHandleはShardStrategyを実装します{
  2. @オーバーライド
  3. パブリック文字列 getShardType() {
  4. 戻る  「モッド」 ;
  5. }
  6. @オーバーライド
  7. パブリックDataTableName ハンドル(String tableName、String dataSourceKey、 int tableShardNum、
  8. int dbShardNum、オブジェクト shardValue) {
  9. /** テーブルに散在する値を計算します */
  10. 長い shard_value = Long.valueOf(shardValue.toString());
  11. 長いtablePosition = shard_value % tableShardNum;
  12. 長いdbPosition = テーブル位置 / (テーブルシャード番号 / dbShard番号);
  13. 文字列 finalTableName = new StringBuilder().append(tableName).append( "_" ).append(tablePosition).toString();
  14. 文字列 finalDataSourceKey = new StringBuilder().append(dataSourceKey).append(dbPosition).toString();
  15. 新しい DataTableName(finalTableName, FinalDataSourceKey)を返します
  16. }
  17. }

データベースとテーブルシャーディングアルゴリズムの拡張

MTDDL は、シャーディングのモジュラー アルゴリズムをサポートするだけでなく、シャーディング アルゴリズムの拡張もサポートします。これは、ShardStrategy インターフェースを実装する新しいシャーディング戦略クラスを追加することで実現できます。 ShardStrategy インターフェイスには 2 つのメソッドが含まれています。getShardType はデータベースとテーブルのシャーディング戦略を指定するために使用され、handle は特定のデータ ソースとテーブルのシャーディング計算ロジックを実装するために使用されます。クラス図は次のとおりです。


完全な注釈アクセス

ビジネス アクセスを最大限に容易にするために、MTDDL は、ShardInfo、ShardOn、および IDGen の 3 つのアノテーションを通じて実装される完全なアノテーション方式でデータベースとテーブルのシャーディング機能を使用します。

ShardInfo アノテーションは、シャーディング テーブル名のプレフィックス tableName、シャード テーブルの数 tableShardNum、シャードの数 dbShardNum、シャーディング戦略 shardType、一意のキー生成戦略 idGenType、一意のキー ビジネス パーティ識別子 idGenKey など、特定のシャーディング構成を指定するために使用されます。 ShardOn アノテーションはシャーディング テーブル フィールドを指定するために使用されます。 IDGen アノテーションは、一意のキー フィールドを指定するために使用されます。具体的なクラス図は次のとおりです。


設定と使用例

  1. // 動的データソース
  2. @データソース( "dbProductSku" )
  3. // tableName: テーブル名のプレフィックス、tableShardNum: テーブル シャードの数、dbShardNum: データベース シャードの数、shardType: データベース シャーディング戦略、idGenType: 一意のキー生成戦略、idGenKey: 一意のキーのビジネス パーティ識別子
  4. @ShardInfo(テーブル名 = "wm_food" 、テーブルShardNum = 100、dbShardNum = 1、シャードタイプ = "mod" 、idGenType = IDGenType.LEAF、idGenKey = LeafKey.SKU)
  5. @成分
  6. パブリックインターフェース WmProductSkuShardDao {
  7. // @ShardOn( "wm_poi_id" ) は、アノテーションによって変更されたオブジェクトの wm_poi_id フィールドを shardValue として使用します。
  8. // @IDGen( "id" ) は一意のキーを設定するフィールドを指定します
  9. パブリックvoid挿入(@ShardOn( "wm_poi_id" ) @IDGen( "id" ) WmProductSku sku);
  10. // @ShardOn はこのアノテーションによって変更されたパラメータを shardValue として使用します
  11. パブリックリスト <WmProductSku> getSkusByWmPoiId(@ShardOn long wm_poi_id);
  12. }

接続プールとSQL監視

DB 接続プールを不適切に使用すると、多くの問題が発生する可能性があります。たとえば、接続プール内の最大接続数が小さすぎると、スレッドが接続を取得できなくなります。接続を取得するための待機時間が長すぎるため、多くのスレッドがハングします。アイドル接続リサイクラーの実行時間が長すぎるため、アイドル接続が時間内にリサイクルされないなどの問題が発生します。効果的かつ正確な監視が不足していると、問題を迅速に特定して履歴を追跡することが不可能になります。

さらに、SQL 実行の監視が不十分な場合、DB クエリの遅延などの潜在的なリスクをタイムリーに検出することが難しくなり、DB サーバーのパフォーマンス低下やダウンタイムの根本原因となることがよくあります (遅いクエリについては、「MySQL インデックスの原則と遅いクエリの最適化」の記事を読むことをお勧めします)。 MTDDL はバージョン 1.0.2 から接続プールと SQL 監視およびその他の関連機能を正式に導入しました。

接続プールの監視

実装

Spring と組み合わせることで、c3p0、dbcp1、dbcp2、mtthrift などのさまざまなソリューションに完全に適応し、監視用に Spring コンテナーに新しく追加されたデータ ソースを自動的に検出し、Meituan Dianping の統合監視コンポーネント JMonitor を通じて監視データを報告します。全体的なアーキテクチャ図は次のとおりです。


接続量監視

接続プール内のアクティブな接続数、アイドル接続数、および合計接続数を監視します。カウンターの形式は次のとおりです: (接続プール タイプ。データ ソース。アクティブ/アイドル/合計接続)。効果図は以下のとおりです。


接続時間の監視を取得する

アイドル接続時間を監視および取得します。カウンター形式: (ds.getConnection.data source.time)、効果図は次のとおりです。


SQL 監視

実装

Spring AOP テクノロジを使用してすべての DAO メソッドの機能を強化し、Meituan Dianping の分散セッション追跡コンポーネント MTrace を通じて SQL 呼び出しデータを記録および報告し、クライアントの観点から SQL 実行時間、QPS、呼び出し量、タイムアウト率、失敗率などの指標を監視します。全体的なアーキテクチャ図は次のとおりです。


成果を達成する

Meituan Dianping のサービスガバナンスプラットフォーム OCTO にログインし、サービスを選択して宛先分析を表示します。効果図は以下のとおりです。


動的構成

データ ソースやサブデータベース、サブテーブルの構成を動的に調整してオンライン DB の緊急事態を解決したり、オンライン変更を再起動せずに即時に有効にしたりといったビジネス側の動的なニーズを満たすために、MTDDL はバージョン 1.0.3 から動的構成関連の機能を正式に導入しました。

実装

Spring コンテナが起動すると、データ ソースとサブライブラリおよびサブテーブル関連の構成が Meituan Dianping の統合構成センター MCC に自動的に登録されます。動的な調整は、MCC 構成管理ページで行うことができます。 MCC クライアントは、変更イベントを感知した後、ローカル構成を更新します。データ ソース構成が変更されると、新しい構成に従って新しいデータ ソースが構築され、古いデータ ソースが置き換えられ、最後に古いデータ ソースが正常に閉じられます。具体的なフローチャートは以下のとおりです。


動的データソース

現在、dbcp、dbcp2、c3p0 などのデータ ソースがサポートされています。効果図は以下のとおりです。


動的なデータベースとテーブル分割

シャード数、シャーディング戦略、一意のキー生成戦略、一意のキービジネスパーティ識別子などの動的な構成をサポートします。効果図は次のとおりです。


バージョンの反復

MTDDLはこれまで4つのフェーズで開発されており、今後段階的にオープンソース化される予定です。具体的なバージョンの反復は次のとおりです。

<<:  企業はクラウドコンピューティングのサポートをDIYで検討すべき

>>:  JVM からの魂を問う質問: 「あなたは一体何のゴミなのですか?」

推薦する

ウェブサイトが検索エンジンと訪問者に異なるコンテンツを表示するのはいつですか?

検索エンジンを含め、Web サイトがさまざまな訪問者に対して異なるコンテンツを表示する一般的な理由は...

クラウドネイティブ時代にアプリケーションを安全に保つために自動化が重要な理由

過去 1 年間で、長年にわたり実装されてきたテクノロジー ロードマップの実現が加速し、デジタル変革を...

将来の検索エンジンの唯一の道

今後の検索エンジンの避けられない道。インターネットを見ると、日々新たな変化が起きていますが、検索エン...

クラウド コンピューティングの開発が始まって 10 年が経ちましたが、なぜ 2018 年に PaaS の重要性が急速に明らかになったのでしょうか。

クラウドコンピューティングの概念が提唱されてから約10年が経ちました。この 10 年間で、クラウド ...

2018年ダブル11プレセールインサイトレポート

ダブルイレブンのプロモーションに牽引され、ブランド広告も過去半月で小幅な上昇を見せ、特に美容、食品飲...

グレープシティは2018年のマイクロソフトテクノロジー&エコシステムカンファレンスに登場し、「開発者を支援する」という使命を果たし続けています。

2018年マイクロソフトテクノロジー&エコシステムカンファレンス(マイクロソフトテックサミット201...

51 Toutiao WeChat Moments広告アシスタントは、商店が商品を宣伝するのに役立ちます

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス商人はWeChatモーメ...

SEOで一生懸命働いて感じたこと、考えたこと、得たもの

私は自分のウェブサイトを宣伝した経験と、よく使ういくつかの方法を皆さんと共有したいと思います。最初は...

アマゾンAWS:中国でのクラウドコンピューティング事業は売却せず、施設のみを売却

昨夜、Amazon AWSは中国事業を売却しておらず、中国の顧客に対してAWSサービスを引き続き提供...

サービスベースとプラットフォームベース:2つのWeiboマーケティングモデルの比較

はじめに:Weiboは企業マーケティングの主戦場になりつつあります。どの業界においても、最初に主導権...

VMware が Forrester によってゼロ トラスト ネットワーク アクセスのリーダーに選出

VMware (NYSE: VMW) は最近、世界的な市場調査会社 Forrester が Forr...

GoogleのPRアップデートで中国のウェブマスターに遅ればせながらの新年の贈り物

2012年、多くのウェブマスターがGoogleがウェブページのPR(ページランク)をいつ更新するかを...

Alibaba Cloudデータセンターのアップグレードにより、きめ細かなシナリオが深まり、新しい小売業のデジタル化が加速

9月18日、2020年雲奇カンファレンスにおいて、アリババクラウドのデータミドルウェア製品が全面的に...

他の人の経験から学ぶ: リンクベイトの実装方法

『詩経』には「他山の石で玉を磨く」という慣用句がある。元々の意味は、他山の石を磨くことで美しい玉に変...

微博の損失はユーザーから始まる

Weiboの時価総額は、かなり長い間、95億ドル前後で推移している。かつて中国のオンライン「世論の場...