ホームページ > バックエンド開発 > PHPチュートリアル > 同時実行性の高い Web サイトでは、データベースの主キーが増加するときの重複の問題をどのように解決するのでしょうか?

同時実行性の高い Web サイトでは、データベースの主キーが増加するときの重複の問題をどのように解決するのでしょうか?

WBOY
リリース: 2016-06-17 08:30:44
オリジナル
2574 人が閲覧しました

この種の問題は、さまざまな Weibo、フォーラム、ポストバー、およびトラフィックの多いその他の場所で発生するはずです。

返信内容:

グローバル ID ジェネレーター。
私たちの毎日の注文も10,000件で、もちろんTiebaやWeiboと同じレベルではありません。
また後日紹介します

-------------------------------------2015/5/27
1主キーを「追加が推奨されない理由」に設定します
この場合、データベース自体は単一点であり、ID が重複するため解体できません。

2 データベースの自動インクリメント メカニズムを利用してグローバル ID の一意性を実現します
次のステートメントを使用します:
REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID( );
これにより、グローバル ID は確実に一意になりますが、Tickets64 テーブルは依然として単一ポイントです。

3 データベースの自動インクリメント メカニズムを利用して、グローバル ID の一意性を実現し、単一ポイントを排除します。
2 に基づいて、2 つの (複数) データベース インスタンスをデプロイし、
自動インクリメント ステップを設定します。を 2 (複数ある場合はインスタンスの数)、つまり auto-increment-increment = 2
auto-increment-offset を 1, 2....
に設定します。このようにして、最初のデータベース サーバーの自動インクリメント ID は 1 3 5 7 9
2 番目のデータベース サーバーの自動インクリメント ID は 2 4 6 8 10

4 となり、データベースの読み取りと書き込みの過剰な圧力の問題が解決されます。グローバル ID が要求されるたびにデータベースを要求します
例えば、初めて業務サービスを起動する場合、固有の ID 3559 が要求されます
方法 2 または 3 の場合、ID は 3559 になります。毎回データベースをリクエストするため、データベースに多大な負荷がかかります
IDとして3559 * 65536 (たとえば、65536である必要はありません) + メモリ自動インクリメント変数を使用できます
場合メモリ自動インクリメント変数が 65535 に達すると、データベースから自動インクリメント ID を再取得します
この方法では、複数の業務サーバーがあっても ID が繰り返されません:
最初の ID は 3559 * 65536 + 1,2,3....65535
2 番目の値は 3560 * 65536 + 1,2,3....65535
最初の値は 65535 次に、データベースを自動に変更します-ID をインクリメントします。この時点では、3561 * 65536 + 1,2,3....

現在は 4 を使用しています。 Instagram のシャーディングと ID
では、Instagram が UUID を生成する方法について説明しましたが、WeChat Moments も同様の方法を使用しています。

このサービスは twitter/snowflake で言及されています · GitHub は uuid の生成に使用されます。 多くの方法がありますが、ここではいくつかの例を示します。

1. 自己増加フィールドの代わりに UUID を使用します。主な障害は、プログラミングが少し面倒で、多くのフレームワークがプログラミングをサポートしていないこと、そしてプログラマーが知的には理解できない問題に遭遇していることです。さらに、UUID は迷信であってはなりません。実際、UUID のクラッシュが発生しています。
2. 一意の ID を使用してサービスをグローバルに生成します。Google のパブリック アーキテクチャ ドキュメントでは、個別の Oracle ノードを使用してグローバルに一意の自動インクリメント ID を生成することが紹介されています。シーケンスのためだけに Oracle を購入するのは、確かに少しクレイジーです。お金を持って、意志を持ってください。
3. いくつかのネゴシエーション アルゴリズムを使用して、各ノードの自己増加 ID が他のノードと競合しないようにします。欠点は、適切に拡張できるアルゴリズムを見つけるのが難しいことです。 GUID が多くのスペースを占めると言えば、私もそれを実現する方法を見つけなければならないと感じたので、Go 言語で関数を作成し、Github の etworker/idxgen · GitHub に置きました。

目的は、各文字のオプション範囲を GUID [0-9a-z] のわずか 16 から [0-9a-zA-Z_-] の合計 64 に変更することです。

比較検討した結果、スペースは GUID よりもはるかに小さいですが、実際の測定効果は問題なく、数 1000 万世代を実行しました。これには約 100 かかりました。壊れたラップトップでは数秒、時々 1 回繰り返されました。一意性が心配な場合は、IsUniqueIdx() 関数を自分で実装してください。

ちなみにこれをDockerに詰め込んでSkylarkにデプロイしたアドレスはidxgen-etworker.alaudacn.me:49662です。 は、一度更新すると新しいIDが表示されるので試してみると良いでしょう。 スノーフレーク 要は「複数のIDをいかに重複なく短時間で生成するか」ということです。
データベースに を書き込むときに を使用すると、重複を回避できますが、過剰な同時実行により遅延が発生します。
メモリまたはキャッシュに自動インクリメントを直接書き込みます生成を高速化できますが、停電などで消失する可能性があるので、データベースかファイルに定期的に書き込むことができます(書き込む際には増加している方とライブラリにある方の比較も必要です)
保険のために、上記の状況が失敗するのを防ぐために、通常はマイクロ秒まで正確な時間を ID に追加します。つまり、 時間 (マイクロ秒レベル) + 自動インクリメントです。係数 ; より大きなアクセス、災害復旧、または配布に対処するには、マシン フラグを追加します。これは、 マシン フラグ + 時間 (マイクロ秒レベル) + 自動インクリメント係数
; 現在、このソリューションを使用しています。約 1,000/秒の同時実行で ID を生成することは、比較的安定した安全なソリューションであると考えられています。 もちろん、各場所の長さは、データの量や保存時間などを考慮する必要があります。タオバオのようなものであれば、
ユーザー ID + 買い物記録 ID + 時間
などを組み合わせて 1 つの購入記録 ID にする必要があります。やっぱりデータ量が多すぎる チケット サーバー: 分散された固有の主キーを安価に提供 自動インクリメントされる主キーが繰り返される場合、コードには大きなバグがあるとしか言えません。 基本的に guid を使用しており、guid アルゴリズムの実装はバージョンごとに若干異なりますが、クラッシュを心配する必要はありません。 GUID はより多くのスペースを占有するだけです。 解決できない場合は、すべてのデータベースを削除することはありませんので、時間をかけてください。
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート