Redis を使用した分散キャッシュペネトレーションソリューションの実装
インターネットビジネスの継続的な発展に伴い、データアクセス量も増加しています。ユーザー エクスペリエンスとキャッシュ テクノロジは徐々に不可欠な要素となり、効率的でスケーラブルなキャッシュ ミドルウェア ソリューションとして Redis が開発者に好まれています。 Redis を分散キャッシュとして使用する場合、キャッシュの侵入によって引き起こされるパフォーマンスの問題を回避するには、信頼性の高いソリューションを実装する必要があります。
この記事では、Redis を使用して分散キャッシュ侵入ソリューションを実装する方法を紹介し、具体的なコード例を示して説明します。
1. キャッシュペネトレーションとは何ですか?
キャッシュ テクノロジを使用する場合、厳密な有効性制御がキャッシュに実装されていない場合、キャッシュの侵入の問題が発生する可能性があります。つまり、リクエストに必要なデータがキャッシュに存在しない場合、すべてのリクエストが実行されるたびに、データベースに直接アクセスすると、データベース リソースが過負荷になり、システム全体のパフォーマンスが低下したり、ダウンタイムが発生したりすることがあります。
キャッシュ侵入の主な理由は、すべてのデータをキャッシュに保存できないことと、リクエスト内のデータがキャッシュに保存されない可能性があることです。効果的な制御がない場合、各リクエストは直接キャッシュに保存されます。データベースにアクセスすると、システム リソースが極度に浪費されます。
2. キャッシュ侵入問題を解決する方法
キャッシュ侵入問題を解決するには、次の 2 つの方法を使用できます:
1. ブルーム フィルター アルゴリズム
ブルーム フィルター アルゴリズムはビット ベクトルに基づく効率的なデータ構造であり、要素がセットに属しているかどうかを迅速に判断するために使用でき、空間と時間の計算量が非常に少ないという特徴があります。ブルーム フィルタ アルゴリズムを使用する場合、リクエストされたデータのハッシュ値をブルーム フィルタのビット ベクトルに格納できます。データ リクエストのハッシュ値がブルーム フィルタに存在しない場合、リクエストは直接拒否されます。これにより、リクエストが直接拒否される可能性があります。キャッシュの侵入の問題。
2. キャッシュの予熱
キャッシュの予熱とは、システムの起動時に使用するデータを事前にキャッシュにロードし、バックグラウンド システムがキャッシュに入る前にリクエストがすでに存在していることを確認することを指します。 、これによりキャッシュの侵入の問題を回避します。
3. Redis を使用して分散キャッシュ侵入ソリューションを実装する
Redis を使用して分散キャッシュを実装する場合、次の 2 つの方法を使用できます:
1. 分散ロックを使用する
キャッシュ クエリを作成するときは、分散ロックを使用して、1 つのスレッドだけがデータベースにアクセスしてキャッシュを更新できるようにすることができます。複数のスレッドが同時に同じデータにアクセスする場合、1 つのスレッドだけがロックを取得できるため、キャッシュの侵入の問題が回避されます。
次は、分散ロックを使用して実装されたコード例です:
def query_data(key): #先尝试从缓存中读取数据 data = cache.get(key) #如果缓存中没有该数据,则获取分布式锁 if not data: lock_key = 'lock:' + key #尝试获取锁 if cache.setnx(lock_key, 1): #若获取到锁,则从数据库中读取数据,并更新到缓存中 data = db.query(key) cache.set(key, data) #释放锁 cache.delete(lock_key) else: #如果未获取到锁,则等待一段时间后重试 time.sleep(0.1) data = query_data(key) return data
2. ブルーム フィルターの使用
クエリをキャッシュする前に、まずデータをハッシュします。ハッシュ値は次のとおりです。ハッシュ値に対応するデータが存在しない場合には、リクエストを直接拒否することができるため、キャッシュ侵入の問題を回避できます。
以下は、ブルーム フィルターを使用して実装されたコード例です。
import redis from pybloom_live import BloomFilter #初始化布隆过滤器 bf = BloomFilter(capacity=1000000, error_rate=0.001) #初始化Redis连接池 pool = redis.ConnectionPool(host='127.0.0.1', port=6379) cache = redis.Redis(connection_pool=pool) def query_data(key): #先尝试从缓存中读取数据 data = cache.get(key) #如果缓存中没有该数据,则检查布隆过滤器,如果布隆过滤器中不存在该数据,则直接返回None if not data and (key not in bf): return None #如果缓存中没有该数据,但是存在于布隆过滤器中,则获取分布式锁 if not data: lock_key = 'lock:' + key #尝试获取锁 if cache.setnx(lock_key, 1): #若获取到锁,则从数据库中读取数据,并更新到缓存中 data = db.query(key) cache.set(key, data) #将哈希值添加到布隆过滤器中 bf.add(key) #释放锁 cache.delete(lock_key) else: #如果未获取到锁,则等待一段时间后重试 time.sleep(0.1) data = query_data(key) return data
上記は、Redis を使用して分散キャッシュ ペネトレーション ソリューションを実装する具体的な実装コード例です。
概要:
Redis を分散キャッシュ ミドルウェア ソリューションとして使用する場合、キャッシュの侵入によって引き起こされるパフォーマンスの問題を回避するために、分散ロックまたはブルーム フィルターを使用して解決できます。ブルームフィルターを使用する際に、キャッシュの予熱方法を組み合わせて、使用するデータを事前に Redis キャッシュにロードして、バックグラウンド システムに入る前にリクエストがキャッシュにすでに存在していることを確認することで、キャッシュの侵入の問題を回避することもできます。
以上がRedis を使用して分散キャッシュ侵入ソリューションを実装するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。