分散型電流制限を実現するRedisの原理と実装方法

WBOY
リリース: 2023-05-11 16:40:59
オリジナル
1887 人が閲覧しました

インターネットの発展に伴い、多くのアプリケーションはさまざまなリクエストのフローを制限する必要があります。これは、同時実行性が高いと、アプリケーションが多数のリクエストの圧力にさらされ、サービスがクラッシュしたり、応答が遅くなったりするためです。この問題を解決するために、開発者は通常、分散型電流制限テクノロジーを使用してリクエストのフローを制御し、サービスの高可用性と安定性を確保します。 Redis は、高性能メモリ データ ストレージ システムとして、一般的に使用される分散型電流制限ソリューションの 1 つです。この記事では、Redisにおける分散型電流制限の原理と実装方法を紹介します。

1. 分散型電流制限とは何ですか?

分散型電流制限とは、複数のサーバー間の連携を通じてリクエスト トラフィックを制御するプロセスを指します。レート リミッターはリクエストの数をカウントし、受信リクエストのレートを許可されたレートと比較し、その比率に基づいてリクエストを受け入れるか拒否します。分散スロットリングでは、各ノードがリクエスト レートとリクエスト カウンタを共有するため、レートがすべてのノードで均等になり、ノードの過負荷が回避されます。

2. 分散型電流制限を実装する Redis の原理

Redis は、組み込みのデータ構造、特に zset (ソート セット) を使用して分散型電流制限を実装します。 zset は、各要素が一意であり、スコアを持つソートされたセットです。スコアは、要素 (通常は数値または時刻) を並べ替えるために使用されます。分散型電流制限では、各ユーザー (または IP アドレス) に zset を設定し、この zset を使用してユーザーのリクエスト カウンタを保存できます。各リクエストが到着すると、それを zset に保存し、Redis の INCRBY コマンドを使用してカウンターをインクリメントします。次に、リクエスト スコアと現在のタイムスタンプをパラメーターとして zrangebyscore コマンドに渡し、特定の時間範囲内のリクエストの割合を計算します。レートが許容レートを超える場合、リクエストは拒否されます。

3. Redis による分散型電流制限の実装方法

分散型電流制限を実装する Redis の具体的な実装は次のとおりです:

  1. レートの保存に使用されるグローバル Zset の作成リミッター (1 つのレート リミッターはユーザーまたは IP アドレスを表します) と各レート リミッターのリクエスト カウンタ。
  2. リクエストが到着するたびに、それをこのレート リミッターの zset に保存し、INCRBY コマンドを使用してカウンターをインクリメントします。デフォルトでは、このコマンドは毎回カウンターを 1 ずつ増分しますが、コマンドの引数をより高い値に設定することで増分を増やすことができます。
  3. zrangebyscore コマンドを使用して、指定された時間範囲内のリクエスト カウンタを持つすべてのリクエストを検索し、リクエスト レートを計算します。
  4. リクエスト レートが許容レートを超える場合、リクエストは拒否され、エラー メッセージが返されます。
  5. リクエスト レートが許容レートを超えない場合、リクエストは受け入れられ、zset のリクエスト カウンタが更新されます。

以下は、Redis を使用して分散電流制限を実装する方法を示すサンプル コードです。このうち、グローバル zset を使用して IP アドレスごとのリクエスト カウンタを保存し、zrangebyscore コマンドを使用して 1 秒あたりのリクエスト レートを計算しました。

import redis
import time

class RateLimiter(object):
    def __init__(self, redis_client, rate, key_prefix='limiter'):
        self.redis = redis_client
        self.rate = rate
        self.key_prefix = key_prefix

    def allow_request(self, ip):
        key = '%s:%s' % (self.key_prefix, ip)
        now = time.time()
        count = self.redis.zcount(key, now - 1, now)
        if count < self.rate:
            self.redis.zadd(key, now, now)
            return True
        return False

if __name__ == '__main__':
    redis_client = redis.Redis()
    limiter = RateLimiter(redis_client, 5)
    for i in range(10):
        print(limiter.allow_request('192.168.1.1'))
        time.sleep(1)
ログイン後にコピー

上記のコードでは、まず、バックエンド ストレージとして Redis を使用する RateLimiter というクラスを作成します。コンストラクターは、R​​edis クライアント インスタンスとレート制限の 2 つのパラメーターを受け入れます。 allow_request メソッドを呼び出すたびに、IP アドレスを表すパラメータを受け取り、その IP アドレスに対するリクエストの数がレート制限を超えているかどうかを確認します。それを超えていない場合はリクエストを収集して True を返し、それ以外の場合はリクエストを拒否して False を返します。

メイン関数では、limitter という名前のインスタンスを作成し、レート制限を 5 に設定し (つまり、1 秒あたり最大 5 つのリクエストを受け入れます)、その後 10 回の連続したリクエストをシミュレートしました。各リクエストの間隔は 1 秒です。 。 6 番目のリクエストの開始時に、レート制限に達したため、すべてのリクエストが拒否され、False が返されます。

4. 概要

Redis は、さまざまなデータ構造、特に分散型電流制限の実装に最適な zset (Sorted Set) を提供する高性能メモリ データ ストレージ システムです。 . . Redis の zset、INCRBY、zrangebyscore コマンドなどの機能を使用すると、分散型電流制限を簡単に実装してリクエストのフローを制御し、サービスの高可用性と安定性を確保できます。

以上が分散型電流制限を実現するRedisの原理と実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!