2人のユーザーが同じユーザー名で同じ瞬間に登録するのを防ぐ方法は?


11

何百万人ものユーザーが同時に登録しているため、登録をシリアル化できません。並行して登録する必要があります。

データベースにユーザー名「user1」が含まれていないとしましょう。2人のユーザーが「user1」に同時に登録しようとすると、それが受け入れられます。ただし、後で問題が発生します。これは起こらないはずです。

論理的な解決策を探しています。特定のものではありません。これを解決するためのアイデア。


The Workplaceでこれを投稿しようする以前の試みで説明が与えられたら、インタビューの質問
-gnat

4
これは正当なソフトウェアアーキテクチャの問題です。良い面接の質問をするだけで、それ以外の問題はありません。
カールビーレフェルト

7
何百万人ものユーザーが同時に登録していますか?本当に?数百万人のユーザーが同時に登録している場合、数十億人の登録ユーザーを処理するなど、より大きな問題が発生します。そして、おそらくそれを処理するサーバーを購入するためのお金。
gnasher729

2
@AddzyKこれは、将来的に直面する仮説的な問題であり、論理的な解決策が必要ですか?ここでは範囲外であることを確認してください。
パパラッチ

3
仮説的な答えは次のとおりです。他の誰かにそれをするためにお金を払ってください。1秒あたり数百万人の新しいユーザーがいるので、お金があります。
-whatsisname

回答:


15

データベースにユーザー名「user1」が含まれていないとしましょう。2人のユーザーが「user1」に同時に登録しようとすると、それが受け入れられます。

なぜそれを受け入れるのですか?一意の制約を適用したり、ユーザー名を主キーとして使用したり、トランザクション内のアプリケーションコードでチェックを実行したりするのは簡単です。

絶対にデータベーストランザクションを使用してデータベースを使用し、これが発生しないようにする必要があります。そうしないと、アプリケーションはデータベースデータの不変式を維持できません。

スケーリングに関しては、データベースは、必要な整合性の種類に応じたさまざまなロックモード、複数のデータベースサーバー用の分散データベースなど、必要なテクノロジーを既に発明しています。


登録をロックしても、他のユーザーが同時に登録できなくなることはありませんか?
アディジーK

2
+1、大まかな計算を実行しただけで、Facebookでさえ1秒あたり平均数回のサインアップしかありません。したがって、データベース自体の制約に依存するだけで十分です。
GrandmasterB

2
@AddzyK:ロックは、データベースが制約を実施しなければならない瞬間にのみ発生します。はい、同時に登録する他のユーザーは並んで待つ必要がありますが、その待ち時間は非常に短く、最大規模のシステムであってもほとんど発生しません。
ロバートハーベイ

1
@GrandmasterB平均は、ここで完全なストーリーを伝えていない場合があります。質問に基づいて、これはオーストラリアの人口調査など、重いピーク負荷を処理するためのものであると想定しました。
-DeadMG

@AddzyK可能性があります。基本的に、テーブルの一部をロックするだけで済みます。gnasher729の答えなど、これに対処するためのスキームは数多くありますが、これを処理できる市販の分散データベース製品を入手できるはずです。独自の部分ロックスキームをロールする必要がある場合でも、DHTなど、それを処理する既知の方法がたくさんあります。
-DeadMG

7

これには標準的な解決策があります。登録を行う複数のワーカーを作成します。各リクエストにはユーザー名に適用されるハッシュがあり、ハッシュはリクエストを処理するワーカーを決定します。この方法では、同じユーザー名に対する2つのリクエストを同時に処理することはできません。

この種類のリクエストでは、すべてのデータベースをデータストアとしてではなく、リスクなどの分散キーバリューストアを考慮してください。


2

それって問題ですか ?

ユーザー名(ユーザーのメールアドレスではない)がログインに使用される場合、2人のユーザーに一意でないユーザー名で登録を終了させることは受け入れられません。

ユーザー名が認証に使用されていない場合は、バックグラウンドプロセスを使用して倍精度浮動小数点型(タイムスタンプなどに基づく)を識別してフラグを立て、ユーザーに次回ログオン時にユーザー名を強制的に変更させることができます。

はい、それは問題です

あなたが尋ねているように、私はユーザー名が一意のIDであると想定されていると思います。次のアプローチを使用できます。

  1. 前:登録プロセスで、新しいユーザーが自分の名前の利用可能性を確認する必要があるステップを予測します。その際、登録を完了することができる一時的なステータスとセッションIDを使用して、使用可能なアカウント名を保存してください。
  2. 同じ時間:gnasher729応答のより一般的で柔軟なバリアントは、単純なハッシュ関数(シンボルテーブルの管理に使用される関数など)を使用して、一意の登録サーバーiにIDを割り当てることです(i = h(username)modulo number_of_servers)制限/セグメント化されたスコープの一意性を処理します
  3. 後:登録の最後に、ユーザーがクリックしたときregisterに、トランザクションデータベースに要求を送信します(フィールドを一意として定義できる場合)。エラーが発生すると、不運なユーザーに「おっと、問題がありました」というメッセージを送信し、別のIDを選択するように依頼します。
  4. 非同期:ユーザーを登録します。ユーザーレコードを再読み込みして、変更されていない単一のレコードであることを確認します。問題がある場合は、ユーザーに変更を依頼する(非同期ではない)か、問題があることをメールで送信する(非同期ですが、ユーザーの観点からは迷惑です)ログイン手順の一部としてユーザーにユーザー名を変更させる。

1

ユーザーの一意の識別子と考えるものを再考してください。各ユーザーは既に一意のメールアドレスを持っているため、この問題は既に解決されています。もちろん、これは、「Mike Nakis」のように、複数のユーザーが同じ名前を登録できることを意味します。それに問題はありますか?本気ですか?たとえば、facebookでは問題ありません。「マイクナキス」と呼ばれるFacebookユーザーが複数存在します。Facebookのログインページを見てください。「メールまたは電話」と「パスワード」を要求します。


0

何百万人ものユーザーが同時に登録する場合、26 x 26の登録サーバーを使用します。1つはaaで始まるユーザー用、1つはabで始まるユーザー用などです。その結果、各サーバーに同時に登録するユーザーは数千人になります。それでも処理できない場合は、26 x 26 x 26サーバーを使用します。


5
...そして、あなたの製品の所有者は国際化を望んでいます
...-Telastyn

2
NFKDなどの正規化された形式である限り、同じ原則がUnicode文字列に適用されます。ユーザー名をハッシュし、ハッシュに基づいて適用することもできます。ただし、この答えは基本的に独自の分散データベースを実装することです。
-DeadMG

1
ある国で何百万人ものユーザーが同時に登録しているということですか?その場合、彼らは実際のソリューションにもっとお金を払うのに十分なお金を持っているべきです。
gnasher729

より具体的には、これはDHTの実行方法の始まりにすぎません。
-DeadMG

これは、2人のユーザーが同じ名前を同時に登録するという問題をどのように修正しますか?両方の名前が同じ2文字で始まるため、同じ登録サーバーで処理されますか?
-HorusKol
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.