分散アプリケーション開発では、自己増加 ID の生成が一般的な要件です。スタンドアロン環境では、データベースの自動インクリメント主キーを使用して自動インクリメント ID を実装できます。ただし、分散環境では、自動インクリメント主キーを使用すると重複が発生します。そのため、他のソリューションを使用する必要があります。自動インクリメント ID の一意性を確保します。
Redis は、分散型自己増加 ID ソリューションを実装できる高性能インメモリ データベースです。この記事では、開発者がプロジェクトに合ったソリューションを選択できるように、3 つの一般的な Redis 分散型自己増加 ID ソリューションを紹介し、それらを比較します。
redis incr コマンドに基づく
Redis は、指定されたキーを自動インクリメントし、自動インクリメントされた値を返すことができる incr コマンドを提供します。 incr コマンドを使用して自動インクリメント ID を生成する場合、キーを固定文字列に設定し、操作のたびに文字列をインクリメントできます。
Redis を使用して分散自動インクリメント ID スキームを生成するためのメイン コードは次のとおりです。
from redis import StrictRedis redis = StrictRedis(host='localhost', port=6379, db=0) def get_next_id(): return redis.incr('id_generator')
Redis の incr コマンドはアトミックな操作であるため、生成された ID が確実に複数のクライアントが同時にアクセスした場合に生成されます。
redis incr コマンドに基づく解決策は非常にシンプルですが、致命的な欠陥があります: Redis の利用可能な最大値 (デフォルトは 2^31) に達すると、ID が自動的に増加し続けます。 -1) の場合、エラーが返されます。そのため、システムがオンラインになった後、長時間サービスを再起動しないと、ID が利用できなくなり、データの損失やデータの中断が発生する可能性があります。
Redis スクリプト Lua スクリプトに基づく
Redis の自己増加 ID が長期間利用できない問題を回避するために、Lua スクリプトを使用して自己増加 ID の範囲を制御できます。 ID。 Lua スクリプトは、1 つのアトミック操作で複数の操作を完了できるため、自動インクリメント ID を生成するときに、常にインクリメントし続けるのではなく、ビジネス要件に基づいて自動インクリメント ID を生成する範囲を指定できます。 。
以下は、Lua スクリプトに基づいて実装された Redis 分散自動インクリメント ID スキームのコードです:
from redis import StrictRedis redis = StrictRedis(host='localhost', port=6379, db=0) SCRIPT = """ local name = KEYS[1] local start = tonumber(ARGV[1]) local stop = tonumber(ARGV[2]) if redis.call('exists', name) == 0 then redis.call('set', name, start) return tonumber(start) end local id = redis.call('incr', name) if id < stop then return tonumber(id) else redis.call('set', name, start) return tonumber(start) end """ def get_next_id(start, stop): result = redis.eval(script=SCRIPT, keys=['id_generator'], args=[start, stop]) return result
この Lua スクリプトでは、start と stop という 2 つのパラメーターを定義します。自動制御 ID 生成範囲を増やします。キー id_generator が Redis に存在しない場合は、start に初期化して start に戻ります。それ以外の場合は、Redis の incr コマンドを使用して id_generator をインクリメントし、インクリメントされた値が stop 値を超えるかどうかを判断します。それを超えた場合は、id_generator の値を start にリセットして start に戻り、そうでない場合は、新しく生成された ID を返します。
Lua スクリプトをベースにしたこの実装では、自動インクリメント ID 生成の範囲を柔軟に制御できますが、実装がより複雑になり、Lua スクリプトを実行してパラメーターを渡すには Redis eval コマンドを使用する必要があります。
redis Redlock に基づく
Redlock は Redis が提供する分散ロック ソリューションであり、分散環境で同じリソースに同時に 1 つのクライアントのみがアクセスできるようにすることができます。 Redlock を使用して分散自動インクリメント ID スキームを実装し、生成された自動インクリメント ID が一意であることを確認できます。
Redlock を使用して分散自己増加 ID スキームを実装するためのメイン コードは次のとおりです。
from redis import StrictRedis from redlock import Redlock redis = StrictRedis(host='localhost', port=6379, db=0) redlock = Redlock([{"host": "localhost", "port": 6379, "db": 0}], retry_times=3) def get_next_id(): with redlock.lock('id_lock', 1000): return redis.incr('id_generator')
Redlock を使用して分散自己増加 ID スキームを実装することにより、次の必要性を回避できます。複数のクライアントが同時に ID にアクセスできるようにするため、重複の問題が発生し、自動インクリメント ID の生成時にロックしてスレッド セーフの問題を防ぐことができます。
ただし、ロック操作は多くの時間とリソースを消費するため、同時実行性が高いシナリオでは Redlock のパフォーマンスが低下する可能性があります。
比較分析
分散型自己増加 ID ソリューションの 3 つの Redis 実装には、それぞれ長所と短所があります。それらの比較を分析してみましょう:
利点: 実装が簡単で、便利で高速です。
デメリット: ID が勝手に増え続けるため、ID の使用不能、データの損失、データの中断などの問題が発生する可能性があります。
適用可能なシナリオ: データ ID の高い連続性を必要としない単純なビジネス シナリオ。
利点: 自動インクリメントされる ID の生成範囲を柔軟に制御して、データの継続性を確保できます。
欠点: 実装は複雑で、Redis eval コマンドを使用して Lua スクリプトを実行し、パラメーターを渡す必要があります。
該当するシナリオ: データ ID の継続性とビジネス ロジックに関する厳しい要件があるシナリオ (電子商取引、金融など)。
利点: ロック操作によりスレッドの安全性が確保され、繰り返しデータが生成される問題が回避されます。
欠点: ロック操作は多くの時間とリソースを消費するため、同時実行性が高いシナリオではパフォーマンスが低下する可能性があります。
該当するシナリオ: 高い同時実行性、分散性、およびデータ ID の連続性に対する高い要件を伴うシナリオ。
結論
上記の比較分析に基づいて、次の結論を導き出すことができます。
したがって、分散型自己増加 ID ソリューションを実装するために Redis を選択する場合は、ビジネス シナリオの特定のニーズを考慮して、適切なソリューションを選択する必要があります。
以上がRedis によって実装された分散自己増加 ID ソリューションの比較の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。