【Javaプロジェクト】ブルームフィルターでキャッシュ侵入問題とブルームフィルター削除困難問題を解決

キャッシュペネトレーションの問題とは何ですか

ブラウザにアクセスした際、Redisやデータベースに存在するデータにアクセスする場合は通常通り結果を返すことができますが、Redisやデータベースに存在しないデータに対してクエリを行うと、意味のないクエリが多くなると、 Redis を通過してデータベースに接続すると、データベースへの負荷が増大し、ダウンタイムが発生します。

したがって、キャッシュの侵入とは、ユーザーがデータベースや Redis に存在しないデータにアクセスすることを指します。たとえば、ID は自己インクリメント戦略を採用していることがわかっているため、負の ID を持つことは不可能であり、犯罪者が負の ID を使用した場合、クエリを実行すると、これらのリクエストは Redis 経由でデータベースに直接送信され、データベースへの負荷が急激に増加し、データベースがダウンする原因になります。(通常は悪意のある行為)

では、キャッシュ侵入の問題を解決するにはどうすればよいでしょうか?

  • 空のオブジェクトをキャッシュし、クエリできない ID を送信するたびにこれらの ID を Redis にキャッシュし、値を null (null) に設定すると、次回同じ ID がクエリされた場合に直接空のオブジェクトが返されます。
    利点は実装が簡単で保守が簡単なことですが、欠点はメモリを無駄に消費することです。
  • 悪意のあるリクエストのIPを直接ブロックし、相手はIPを常に変更する可能性があります
  • パラメータの正当性を検証する
  • ブルームフィルターは、メモリ使用量が少なく、キーが重複しないのがメリットですが、実装が容易ではなく、誤判定の可能性があるのがデメリットです。

ブルームフィルターとは何ですか

ブルームフィルター(英語: Bloom Filter)は、1970年にブルームによって提案されました。これは実際には長いバイナリ ベクトルと一連のランダム マッピング関数です。

ブルーム フィルターを使用すると、要素がセット内にあるかどうかを取得できます。メリットとしては、空間効率やクエリ時間が一般的なアルゴリズムを大きく上回っていること、デメリットとしては、異なるデータに対して同じハッシュ関数を使用しても、一定の確率で誤認識が発生し、削除が困難であることが挙げられます。同じ値であり、ビットが 1 に設定されます。誤審が起きる。
つまり、ブルーム フィルターは正確ではなく、純粋にエラーが発生しています。

ブルーム フィルターの原理: 要素がセットに追加されると、その要素は K 個のハッシュ関数を通じてビット配列内の K 個の点にマッピングされ、それらは 1 に設定されます。取得するとき、コレクション内にあるかどうかを (おおよそ) 知るには、これらのポイントがすべて 1 であるかどうかだけを確認する必要があります。これらのポイントのいずれかが 0 の場合、チェックされた要素は存在してはなりません。すべて 1 の場合、チェックされた要素は存在しません。要素 おそらく入っています。

簡単に言うと、length の長さのビット配列を用意し、すべての要素を 0 に初期化し、k 個のハッシュ関数を使用して要素に対して k 個のハッシュ演算を実行し、length の余りを取得して k 個の位置を取得し、対応する位置を に設定します。ビット配列を 1 にします。

ブルームフィルターがより多くの要素を保存すると、より多くのビットが1に設定されます。要素xが保存されていなくても、ハッシュ関数によってビット配列にマッピングされた特定のビットが他の値によって1に設定されると想定されます。はい、ブルームフィルターの仕組み上、要素xの値も存在しており、ブルームフィルターには一定の誤判定率があります。

上記から、ブルーム フィルターの空間複雑度は O(長さ)、クエリと挿入のイベント複雑度は O(k) であることがわかります。ここで、k はハッシュ関数の数です。
もう 1 つの特徴は、データのビットを削除すると、このビットにもマップされている他のデータに影響を与える可能性があるため、ブルーム フィルターがデータの削除をサポートしていないことです。したがって、ブルームフィルタを使用すると誤り率がどんどん大きくなってしまうため、これを解決する方法を検討する必要がある。

ブルームフィルターの実装

上記の理解によると、ブルーム フィルターの実装はバイナリ ベクトルと複数のハッシュ関数に依存しているため、ブルーム フィルターの精度に影響を与える要因には、ハッシュ関数のランダム性とバイナリ ベクトルのサイズが含まれます。
現在、一般的に使用されているブルーム フィルターの実装は、Guava と Redisson です。
グアバを使用する場合の方法は次のとおりです。

1、添加Maven依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre<</version>
</dependency>


2、创建布隆过滤器
BloomFilter<Integer> filter = BloomFilter.create(
  //Funnel 是一个接口,用于将任意类型的对象转换为字节流,
  //以便用于布隆过滤器的哈希计算。
  Funnels.integerFunnel(), 
  10000,  // 插入数据条目数量
  0.001  // 误判率
);

リディションを使用する場合

1、添加Maven依赖

<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.16.1</version>
</dependency>
2、配置 Redisson 客户端

@Configuration
public class RedissonConfig {
    
    

 Bean
 public RedissonClient redissonClient() {
    
    
    Config config = new Config();
    config.useSingleServer().setAddress("redis://localhost:6379");
    return Redisson.create(config);
 }
 
}
3、初始化

RBloomFilter<Long> bloomFilter = redissonClient.
                                      getBloomFilter("myBloomFilter");
//10000表示插入元素的个数,0.001表示误判率
bloomFilter.tryInit(10000, 0.001);
//插入4个元素
bloomFilter.add(1L);
bloomFilter.add(2L);
bloomFilter.add(3L);
bloomFilter.add(4L);
4、判断数据是否存在

public boolean mightcontain(Long id) {
    
    
    return bloomFilter.contains(id);
}

実は、Java にはブルーム フィルタの実装もネイティブで提供されており、Java にはビット演算用のセット BitSet が用意されており、BitSet を使用してハッシュ関数を自分で実装することでブルーム フィルタを実装できます。

削除がサポートされていない問題を解決する

前述したように、ブルームフィルターを使用するとクエリの誤差がどんどん大きくなってしまうのですが、この問題を解決する方法はあるのでしょうか?

まず簡単な方法について説明します。それは、このブルーム フィルターを直接置き換えるというものです。
時間指定タスクを作成し、特定のイベントの後に新しいブルーム フィルターを作成し、データベース内の全データをクエリし、マッピングを使用して新しいブルーム フィルターにマッピングし、元のブルーム フィルターを更新できます。ブルーム フィルターへのポインターがあります。 。この方法は実装が簡単です。

もう 1 つの方法は、カウントを使用することです。ブルーム フィルターの最下層がバイナリ ベクトルを使用していることがわかっています。つまり、このベクトルには 01 の値が 2 つしかないため、複数の要素がこの位置にマッピングされている場合は、次のように設定します。 0だと誤判定が大きくなるため、このビットの値が01だけではなく、バイナリベクトルをカウント対応のByte型に置き換えることを考えると、このビットにマッピングする際に使用します。 Position ++ メソッドでインクリメントし、削除したい場合は – するので、このビットが 0 であればデータが存在するかどうかも判断できます。
大きなデメリットは、スペースの無駄が増えて効率が低下することです。同時に、同時修正の問題も考えなければなりません。

おすすめ

転載: blog.csdn.net/Zhangsama1/article/details/131590267