分散キャッシュ・セキュリティ・アプリケーション(redis透過性の問題)
キャッシュの透過
キャッシュスルーとは?キャッシュにはデータが存在せず、データベースにも存在しないデータ.新しいリクエスト(ハッカーの悪意のある攻撃など):https://item.jd.com/6729892714444444.html商品が存在しない)を検索すると、データベースが検索され続け、データベース・サービスが停止する可能性があります.
Null値はソリューションを返します.
データベースがデータをクエリできない場合、Null値をキャッシュしたオブジェクトが返されます.
ブロンフィルタ
Null値スキームに問題があることは明らかです.クエリ符号化にデータが存在しない場合、その後、この番号のデータが追加されると、このデータは永遠に検出されません.ブロンフィルタ(性能の問題は心配しないで、自分で資料を調べることができます)、例えば商品のすべてのIdをブロンフィルタに追加し、後続のアクセスはbloomブロンフィルタを経て存在するかどうかを判断し、存在しない場合は直接戻ります.そうしないと放行します.以下にbloomフィルタのredis実装を示す.
実戦応用
キャッシュスルーとは?キャッシュにはデータが存在せず、データベースにも存在しないデータ.新しいリクエスト(ハッカーの悪意のある攻撃など):https://item.jd.com/6729892714444444.html商品が存在しない)を検索すると、データベースが検索され続け、データベース・サービスが停止する可能性があります.
Null値はソリューションを返します.
データベースがデータをクエリできない場合、Null値をキャッシュしたオブジェクトが返されます.
ブロンフィルタ
Null値スキームに問題があることは明らかです.クエリ符号化にデータが存在しない場合、その後、この番号のデータが追加されると、このデータは永遠に検出されません.ブロンフィルタ(性能の問題は心配しないで、自分で資料を調べることができます)、例えば商品のすべてのIdをブロンフィルタに追加し、後続のアクセスはbloomブロンフィルタを経て存在するかどうかを判断し、存在しない場合は直接戻ります.そうしないと放行します.以下にbloomフィルタのredis実装を示す.
bloom.filter.expectedInsertions=10000000
bloom.filter.fpp=0.001F
// Java
@ConfigurationProperties("bloom.filter")
@Component
public class RedisBloomFilter {
private static final String BLOOM_NAME = "bf.name";
//
@Getter @Setter
private long expectedInsertions;
//
@Getter @Setter
private double fpp;
//bit
@Getter @Setter
private long numBits;
//hash
@Getter @Setter
private int numHashFunctions;
@Autowired
private RedisTemplate redisTemplate;
@PostConstruct
public void init(){
this.numBits = optimalNumOfBits(expectedInsertions, fpp);
this.numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);
}
/**
* bit
* @return
*/
private long optimalNumOfBits(long n, double p){
if (p == 0){
p = Double.MIN_VALUE;
}
return (long)(-n * Math.log(p) / (Math.log(2) * Math.log(2)));
}
/**
* hash
* @return
*/
private int optimalNumOfHashFunctions(long n, long m){
return Math.max(1, (int)Math.round((double)m / n * Math.log(2)));
}
/**
* keys
* @param key
* @return
*/
public boolean isExist(String key){
long[] indexs = getIndexs(key);
List list = redisTemplate.executePipelined(new RedisCallback
実戦応用
/*
* , ID , ID
* : ,
*/
@PostConstruct
public void init(){
List products = productService.findAll();
products.forEach(p->{
redisBloomFilter.put(String.valueOf(p.getProductId()));
});
}
// ,
public Product getProductById(Long productId){
log.debug(" id:{}", productId);
// 【 】
if (!redisBloomFilter.isExist(String.valueOf(productId))){
return null;
}
.......
}