サーバーシステムを開発するとき、大規模で同時のデータ要求に適応するために、特に分散システムで作業するときは、データを非同期的に保存する必要があります。現時点では、挿入データベースが自動IDを取得するのを返すのを待つことはできません。代わりに、グローバルな一意のIDを使用して、データベースを挿入する前に、グローバルな一意のIDを生成する必要があります。ゲームサーバーでは、グローバルな一意のIDを将来のサーバーの組み合わせに使用でき、重要な競合はありません。将来的には、ビジネスの成長が発生した場合、データベースとスプリットテーブルを実装できます。たとえば、ユーザーのアイテムは同じシャードに配置する必要があり、このシャードは、1000を超えて1000を超えて100000未満のユーザーIDを含むユーザーIDの範囲値に基づいて決定できます。現在、以下が一般的に使用されています。
1。Java自身のuuid。
uuid.randomuuid()。toString()は、サービスプログラムを通じてローカルに生成でき、IDの生成はデータベースの実装に依存しません。
利点:
ローカルでIDを生成すると、リモートコールは必要ありません。
繰り返さない世界は世界だけです。
水平拡張能力は非常に優れています。
短所:
IDには128ビットがあり、大きなスペースを占有し、文字列型として保存する必要があり、インデックスの効率は非常に低いです。
生成されたIDにはタイムスタンプが含まれておらず、トレンドを増やすことを保証することはできません。データベースデータベースを分割するときに頼ることは困難です。
2。Redisベースの増分メソッド
Redis自体はシングルスレッドで操作され、Incrは原子的に増加した動作を保証します。また、インクリメンタルステップサイズの設定もサポートします。
利点:
展開が簡単で使いやすいです。 Redis APIを呼び出すだけです。
複数のサーバーがRedisサービスを共有して、共有データの開発時間を短縮できます。
Redisは、単一の障害点の問題を解決するためにクラスターに展開できます。
短所:
システムが大きすぎる場合、複数のサービスリクエストを同時にRedisにリクエストすると、パフォーマンスのボトルネックが発生します。
3。Flickerからの解決策
このソリューションは、データベースの自動インクリメントIDに基づいており、IDを生成するために特に別のデータベースを使用します。オンラインで詳細を見つけることができます。個人的には、使用するのは非常に面倒であり、使用することはお勧めしません。
4。ツイッタースノーフレーク
Snowflakeは、Twitterのオープンソースである分散ID世代アルゴリズムです。その中心的なアイデアは、ミリ秒数として41ビット、マシン番号として10ビット、12ビットをミリ秒以内のシリアル番号として使用して、長いタイプのIDを生成することです。このアルゴリズムは、理論的にはマシンごとに最大1,000*(2^12)IDを生成できます。これは約400Wで、ビジネスのニーズを完全に満たすことができます。
Snowflakeアルゴリズムのアイデアによれば、ビジネスシナリオに基づいて独自のグローバルユニークなIDを生成できます。 Javaの長さの長さは64ビットであるため、設計したIDは64ビットで制御する必要があります。
利点:高性能、低遅延。独立したアプリケーション。時間によって秩序ある。
短所:独立した開発と展開が必要です。
たとえば、設計したIDには次の情報が含まれています。
| 41ビット:タイムスタンプ| 3ビット:面積| 10ビット:機械番号| 10ビット:シリアル番号|
一意のIDを生成するJavaコード:
/***カスタムIDジェネレーター* ID生成ルール:ID最大64ビット** | 41ビット:タイムスタンプ(MS)| 3ビット:エリア(コンピュータールーム)| 10ビット:機械番号| 10ビット:シリアル番号|*/public class gameUuid {//参照時間プライベートLONG TWEPOCH = 128834974657L; // 2010年11月4日01:42:54 GMT //リージョンフラグディジットプライベート最終的な静的長い領域digitsプライベート最終的な静的ワーカーインドビット= 10L; //シリアル数桁プライベート最終的な静的シーケンス= 10L;マシンIDプライベート最終的な静的long maxworkerid = -1l ^(-1L << workeridbits); //シリアル番号の最大値プライベート最終的な最終的な静的シーケンスマスク= -1L ^(-1L <<シーケンスビット); SequenceBits + workeridbits; //時間は23ビットの左にシフトされます。 private static long lasttimestamp = -1L;プライベートロングシーケンス= 0L;プライベートファイナルロングワーカー。プライベート最終的な長い地域。 public gameuuid(long workerid、long regionid){//範囲外の場合、例外がスローされている場合(workerid> maxworkerid || workerid <0){新しいIllegalargumentexception( "Worker IDは0"以下ではありません ");} if(regionad> maxregionid || maxregumentid <0)または0 ");} this.workerid = workerid; this.regionid = regionid;} public gameuuid(long workerid){//範囲外の場合は範囲外の場合(workerid> maxworkerid || workerid <0){show new emillarargumentexception( "worker idは%dを超えることはできません"); 0);}/*** @param ispadding* @param busid* @return*/private synchronized nextid(boolean ispadding、long timestamp = timegen(); long paddingnum = regionid; if(ispadding){paddingnum = busid;} if(time trie spry <frtimed;後方に「 +(lastTimestamp -Timestamp) + "MilliseConds"のIDを生成することを拒否します。シーケンスはわずか10ビットで、シーケンセンマスクと組み合わされて、ハイビットシーケンス=(シーケンス + 1)&シーケンスマスクを削除します; //オーバーフローかどうか、つまりミリ秒ごとに1024を超えます。 1024の場合、シーケンスマスクと組み合わされ、シーケンスは0IF(シーケンス== 0)に等しくなります{//スピンは次のミリ秒タイムスタンプ=テールネックスマリス(lastTimestAmp);} // Mantissaがよりランダムであることを確認するために、最後のビットシーケンス= new Securerandom()。nextInt(10);} lastTimestamp = Timestamp; Return((Timestamp -Twopoch)<< TimestampleFtshift)| (paddingnum << regionidshift)| (workerid << workeridshift)|シーケンス;} //生成時間が以前よりも小さく(NTPコールバックなどの問題が原因)を防ぎ、インクリメンタルトレンドを維持し、ロングテールネクストミリス(最終的な長いlastTimestamp){long timestamp = this.timegen();保護されたlonggen(){return system.currenttimemillis();}}カスタムメソッドを使用する際に注意すべきことがいくつかあります。
成長傾向を維持するには、一部のサーバーの時間を早期に回避し、一部のサーバーが遅くなることを避ける必要があるため、すべてのサーバーの時間を制御する必要があり、NTPタイムサーバーがサーバーに呼び戻す時間を回避する必要があります。ミリ秒を横断すると、シリアル番号は常に0に達し、シリアル番号0のIDが増え、モジュロディング後に不均一なIDが生成されるため、シリアル番号は毎回0に属しませんが、ランダム数は0から9になります。
ニーズに応じて上記の方法を選択できます。ゲームサーバーの開発では、モバイルゲームなどの独自のゲームタイプに応じて選択できます。シンプルで簡単に間違いを犯すことはできません。この種のゲームで単一のサーバーによって作成された新しいIDの数はあまり大きくないため、ニーズを完全に満たすことができます。大規模なワールドゲームサーバーの場合、それらは主に配布されるため、スノーフレークを使用できます。上記のスノーフレークコードは単なる例であり、ニーズに応じてカスタマイズする必要があるため、追加の開発量があり、上記の予防策に注意を払う必要があります。
上記は、Javaコードを使用してゲームサーバーを実装して、Javaコードに基づいてグローバルな一意のIDを生成する方法の要約です。私はそれが誰にでも役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!