[php] mysql グローバル ID 生成ソリューション、phpmysql グローバル id_PHP チュートリアル

WBOY
リリース: 2016-07-12 09:03:39
オリジナル
896 人が閲覧しました

【php】mysql グローバル ID 生成ソリューション、phpmysql グローバル ID

ビジネスが成長するにつれて、本番システムでは常にビジネス量が小規模から大規模に増加するプロセスが発生します。スケーラビリティは、システムの高可用性を検討するための重要な指標です。データベース システム; 単一のテーブル/データベース内のデータ量が多すぎて更新量が急増し続ける場合、MySQL DBA はビジネス システムのシャーディング ソリューションを提案することがよくあります。シャーディングが必要なため、商品を保管するデータベースなど、一部のビジネス システムではシャーディング キーの問題について議論することは避けられません。では、グローバルに一意の ID を生成するにはどうすればよいでしょうか。 DBA の観点から、いくつかの一般的なソリューションを紹介します。

1. CAS思考を活用する

CAS プロトコルとは何ですか

Memcached は、バージョン 1.2.4 で CAS (Check and Set) プロトコルを追加しました。これは、Java の同時 CAS (Compare and Swap) アトミック操作に似ており、変更される同じ項目の同時実行を処理します。複数のスレッドによる質問

CASの基本原則

基本原理は非常に簡単で、一言で言えば「バージョン番号」です。

次の例から理解できます:

CAS が使用されていない場合、次のシナリオが発生します:

  • 最初のステップで、A はデータ オブジェクト X を取り出します。
  • 2 番目のステップでは、B がデータ オブジェクト X を取り出します。
  • 3 番目のステップでは、B がデータ オブジェクト X を変更し、それをキャッシュに置きます。
  • ステップ 4、A はデータ オブジェクト X を変更し、それをキャッシュに置きます。
  • 結論: データ書き込みの競合は 4 番目のステップで発生します。
CAS プロトコルを使用するシナリオは次のとおりです。

最初のステップでは、A はデータ オブジェクト X を取り出し、CAS-ID1 を取得します。

2 番目のステップでは、B はデータ オブジェクト X を取り出し、CAS-ID2 を取得します。
    3 番目のステップでは、B はデータ オブジェクト X を変更し、キャッシュに書き込む前に、CAS-ID がキャッシュ スペース内のデータの CAS-ID と一致するかどうかを確認します。結果は「一貫性」で、CAS-ID2 を持つ変更された X がキャッシュに書き込まれます。
  • 4 番目のステップでは、A はデータ オブジェクト Y を変更し、キャッシュに書き込む前に、CAS-ID がキャッシュ スペース内のデータの CAS-ID と一致するかどうかを確認します。結果が「不一致」の場合、書き込みは拒否され、ストレージ障害が返されます。
  • このように、CASプロトコルは「バージョン番号」という考え方を利用して競合問題を解決しています。 (オプティミスティックロックコンセプト)
  • 実際、これは厳密には CAS ではありませんが、比較と交換のアトミック操作のアイデアを使用しています。
生成の考え方は次のとおりです。グローバル ID が生成されるたびに、現在のグローバル最大 ID が最初にシーケンス テーブルから取得されます。次に、取得したグローバルIDに1を加算し、1加算後の値をデータベースに更新します。例えば、1加算後の値は203、テーブル名はusers、データテーブルの構造は以下のようになります。 リーリー

SQL文

リーリー SQL ステートメント内の

および gid

update ステートメントの影響を受けるレコード数が 0 の場合、別のプロセスが事前に値 203 を生成し、データベースに書き込んでいることを意味します。再生成するには、上記の手順を繰り返す必要があります。

コードは次のように実装されます:

リーリー

2. グローバルロックを使用する

並行プログラミングを実行する場合、通常はロック機構が使用されます。実際、グローバル ID の生成により、同時実行の問題も解決されます。

世代のアイデアは次のとおりです:

redisのsetnxメソッド、memcaceのaddメソッドを使用した場合、指定したキーが既に存在する場合はfalseを返します。この機能を使用してグローバル ロックを実装します

グローバルIDを生成する前に毎回、指定されたキーが存在するかどうかを確認し、存在しない場合はredisのincrメソッドまたはmemcacheのincrementを使用して1を加算します。この 2 つのメソッドの戻り値は 1 を加算した値になります。存在する場合はループ待ち状態になります。ループ中にキーがまだ存在するかどうかが常にチェックされ、キーが存在しない場合は上記の操作が実行されます。

コードは次のとおりです:

リーリー

3. Redisとdbの組み合わせ

Redis を使用してメモリを直接操作すると、パフォーマンスが向上する可能性があります。しかし、redis が停止した場合はどうすればよいでしょうか?上記の 2 つの解決策を組み合わせると、安定性が向上します。

コードは次のとおりです:

リーリー

4. フリッカーの解決策

mysql 自体が auto_increment 操作をサポートしているため、この機能を実装するためにこの機能を使用することを考えるのは自然です。 Flicker は、グローバル ID 生成ソリューションで MySQL の自己増加 ID メカニズム (auto_increment + replace into + MyISAM) を使用します。 64 ビット ID を生成するための具体的な解決策は次のとおりです:

まず別のデータベース (例: チケット) を作成し、次にテーブルを作成します:
リーリー

レコードを挿入して実行すると、

、クエリの結果は次のようになります:

リーリー

アプリケーション側では、次の 2 つの操作を実行し、トランザクション セッションで送信する必要があります:
リーリー

このようにして、増加する重複しない ID を取得できます。

これまでのところ、高可用性の観点から、単一のデータベースでのみ ID を生成してきました。 SELECT * from Tickets64次のステップは、単一障害点の問題を解決することです。Flicker は、2 つのデータベース サーバーで ID を生成できるようにしました。 auto_increment 値とステップ サイズを調整して奇数 ID と偶数 ID を生成します。

リーリー

最後に、クライアントはポーリングを通じて ID を取得するだけで済みます。

  • 利点: データベースの自己増加 ID メカニズムを最大限に活用して高い信頼性を提供し、生成される ID は規則的です。
  • 短所: 2 つの独立した MySQL インスタンスを占有するため、リソースが無駄になり、コストが高くなります。

参考:

http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/

http://segmentfault.com/a/1190000004090537

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/1079797.html技術記事 [php] mysql グローバル ID 生成ソリューション、phpmysql グローバル ID 生成システムは、ビジネスの成長に応じて常にビジネス量のプロセスを経ます。スケーラビリティとは、データベース システムの高可用性を考慮することです...
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート