缓存击穿之布隆过滤器bloom Filter实现方式

原文:https://blog.csdn.net/ocean_fan/article/details/78350431
一、什么是缓存击穿

查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查询,这样缓存就失去了意义。如果在大流量下数据库可能挂掉。缓存击穿是黑客攻击系统的常用手段。

二、怎么解决缓存击穿问题?

采用布隆过滤器来实现。

什么是布隆过滤器?

它是一种空间效率极高的概率型算法和数据结构,用于判断一个元素是否在集合中(类似Hashset)。它的核心是一个很长的二进制向量和一系列的hash函数。

java中如何使用布隆过滤器?

使用谷歌的guava实现布隆过滤器。

bloom Filter布隆过滤器优劣势?

优势:
1)全量存储但不存储元素本身,在某些保密要求非常严格的场合有优势
2)空间效率高
3)插入/查询时间都是常数,远远超过一般算法

劣势:
1)存在误算率,随着存入的元素数量增加,误算率也随着增加
2)一般情况下不能从布隆过滤器删除元素
3)数组长度以及hash函数个数确定过程复杂

布隆过滤器的使用场景?
1)垃圾邮件地址过滤(地址数量很庞大)
2)爬虫URL地址去重

  1. 解决缓存击穿问题

4)浏览器安全浏览网址提醒
5)google 分布式数据库Bigtable以及Hbase使用布隆过滤器来查找不存在的行或列,以减少磁盘查找的IO次数
6)文档存储检索系统也可以采用布隆过滤器来检测先前存储的数据

三、java中使用guava中的bloom Filter解决缓存击穿问题
工程目录结构图:


@PostConstruct和@PreDestroy

从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法 。写法有如下两种方式:

@PostConstruct
Public void someMethod() {}
或者
public @PostConstruct void someMethod(){}

被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行执行之后执行

@PostConstruct和@PreDestroy

模拟100个线程同时查询缓存中必不存在的情况。

package com.ocean.cache;
 
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
 
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import com.google.common.base.Charsets;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import com.ocean.dao.UserDao;
import com.ocean.dto.UserDto;
 
/**
 * 缓存击穿
 * @author 
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config/spring/spring-dao.xml",
        "classpath:config/spring/spring-bean.xml",
        "classpath:config/spring/spring-redis.xml"})
public class CacheBreakDownTest {
    private static final Logger logger = LoggerFactory.getLogger(CacheBreakDownTest.class);
    
    private static final int THREAD_NUM = 100;//线程数量
    
    @Resource
    private UserDao UserDao;
    
    @Resource
    private RedisTemplate redisTemplate;
    
    private int count = 0;
    
    //初始化一个计数器
    private CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUM);
    
    private BloomFilter bf;
    
    List allUsers;
    
    @PostConstruct
    public void init(){
        //将数据从数据库导入到本地
        allUsers = UserDao.getAllUser();
        if(allUsers == null || allUsers.size()==0){
            return;
        }
        //创建布隆过滤器(默认3%误差)
        bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), allUsers.size());
        //将数据存入布隆过滤器
        for(UserDto userDto : allUsers){
            bf.put(userDto.getUserName());
        }
    }
    
    @Test
    public void cacheBreakDownTest(){
        for(int i=0;i operation = (ValueOperations) redisTemplate.opsForValue();
            synchronized (countDownLatch) {
                Object cacheUser = operation.get(key);
                if(cacheUser!=null){
                    System.out.println("return user from redis");
                    return;
                }
                //如果缓存不存在查询数据库
                List user = UserDao.getUserByUserName(randomUser);
                if(user == null || user.size() == 0){
                    return;
                }
                //将mysql数据库查询到的数据写入到redis中
                System.out.println("write to redis");
                operation.set("Key:"+user.get(0).getUserName(), user.get(0).getUserName());
            }
        }
        
    }
}

maven配置文件pom.xml

  
     4.0.0
  manager
  manager
  war
  0.0.1-SNAPSHOT
  manager Maven Webapp
  http://maven.apache.org
  
        21.0
    
      
          
            junit  
            junit  
            4.9  
         
        
        
            org.mockito
            mockito-all
            1.10.19
            test
         
          
          
            org.springframework  
            spring-webmvc  
            4.2.0.RELEASE  
          
          
          
            jstl  
            jstl  
            1.2  
          
          
          
            log4j  
            log4j  
            1.2.17  
          
          
            org.apache.logging.log4j  
            log4j-core  
            2.0  
          
          
            org.apache.logging.log4j  
            log4j-api  
            2.0  
          
          
          
            com.fasterxml.jackson.core  
            jackson-core  
            2.6.1  
          
          
            com.fasterxml.jackson.core  
            jackson-databind  
            2.6.1  
          
          
            com.fasterxml.jackson.core  
            jackson-annotations  
            2.6.1  
          
          
          
            org.mybatis  
            mybatis  
            3.2.8  
          
          
          
            org.mybatis  
            mybatis-spring  
            1.2.2  
          
          
          
            commons-dbcp  
            commons-dbcp  
            1.4  
          
          
            org.springframework  
            spring-jdbc  
            4.2.0.RELEASE  
          
          
          
            org.springframework  
            spring-tx  
            4.2.0.RELEASE  
          
  
          
        
            mysql
            mysql-connector-java
            5.1.39
         
          
            commons-io  
            commons-io  
            2.2  
          
        
        
        
            dom4j
            dom4j
            1.6.1
        
           
            jaxen  
            jaxen  
            1.1.6  
        
        
        
            com.google.guava
            guava
            ${guava.version}
        
        
        
            org.slf4j
            slf4j-api
            1.7.21
        
        
        
    
        org.springframework
        spring-test
        4.2.9.RELEASE
        test
    
    
     
            redis.clients 
            jedis
            2.6.2
    
    
    
    
        org.springframework.data
        spring-data-redis
        1.2.0.RELEASE
    
        
      
      
        manager  
      

spring-bean.xml文件

  
    
    
    
    
    
        
        
        
      

spring-dao.xml文件

  
      
      
      
      
          
          
          
          
          
          
      
  
      
      
          
          
          
          
      
      
      
   
    
    
        
        
     
  

spring-redis.xml文件

 
  
    
    
    
    
 
 
    
    
        
    
    
    
    
    
    
    
   
    
    
 
 
    
        
        
          
              
          
          
              
          
          
              
          
          
              
          
     

mybatisconfig.xml文件

  
  
  
      
          
       
      
  
  
        
          
  
 

user.xml文件




    
    
    
    
    

你可能感兴趣的:(缓存击穿之布隆过滤器bloom Filter实现方式)