SpringBoot+Redis(實現處理熱點數據)


一、什么是熱點數據

在很短的時間內,許多數據要被多次查詢(像雙十一購物,查詢商品)

二、為什么要使用redis

redis是非關系型數據庫,Redis將數據存儲在內存上,避免了頻繁的IO操作,接下來,讓大家正真感受下redis的魅力

三、場景

短時間內有大量的請求來獲取用戶列表的數據,每次都需要從數據庫進行查詢

1、原思路

技術:SpringBoot+mysql

每次都從mysql數據庫中查出對應的數據

代碼如下:

entity類(實現序列化接口):

/**
 * 用戶實體類
 */
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    private int age;

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

controller層:

/**
 * 控制層
 */
@RestController
public class RedisController {
    @Autowired
    private RedisService redisService;
    @GetMapping("/queryUserList")
    public String queryUserList(){
        long start = System.currentTimeMillis();
        // 采用多線程進行模擬
     ExecutorService fixThreadPool = Executors.newFixedThreadPool(3);
     // 創建執行任務
     Runnable runnable = () -> {
         redisService.queryUserList();
     };

     // 循環執行
     for(int i = 0;i < 10000;i++){
         fixThreadPool.execute(runnable);
     }
     // 用來計算操作時間        fixThreadPool.shutdown();
        long end;
        while(true){
            if(fixThreadPool.isTerminated()) {
                end = System.currentTimeMillis() - start;
                break;
            }
        }

        return "程序運行時間為:"+ end + "毫秒";
    }

}

 

service層:

/**
 * 業務層
 */
@Service
public class RedisService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private RedisMapper redisMapper;
    public List<User> queryUserList(){
        List<User> userList = redisMapper.queryUserList();
        return userList;
    }
}

dao層:

java:

/**
 * dao層
 */
@Mapper
public interface RedisMapper {
public List<User> queryUserList();
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
                        "https://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.redis.dao.RedisMapper">
    <!-- 查找預約記錄列表 -->
    <select id="queryUserList" resultType="com.example.demo.redis.entity.User">
        select * from user
    </select>
</mapper>

運行:

打開瀏覽器:輸入訪問地址:http://localhost:8081/queryUserList

查看結果:

 

 

 嗯。。。。。50s,用戶體驗應該不算太好

 

2、整合redis

思路:

SpringBoot集成redis不再多說,基本思路就是用戶首次訪問從數據庫中取值,之后每次進行判斷只要redis中有數據,就從redis中取值,其中涉及到多線程訪問早造成的內存穿透問題,采用雙重檢查的形式解決。

其他層沒有變化,業務層的新代碼如下:

/**
 * 業務層
 */
@Service
public class RedisService {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private RedisMapper redisMapper;
    public List<User> queryUserList(){
        // 設置序列化
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);
        List<User> userList = (List<User>)redisTemplate.opsForValue().get("userList");
        // 防止首次訪問該接口有大量用戶,造成內存穿透,使redis沒有效果
        if(null == userList){
            synchronized (this){
                if(null == userList){
                    System.out.println("從mysql中查詢數據中。。。。。。");
                    // 從數據庫中查詢數據
                    userList = redisMapper.queryUserList();
                    System.err.println(userList);
                    // 放入redis
                    redisTemplate.opsForValue().set("userList",userList);
                }
            }
        }else{
            System.out.println("從redis中查詢數據中。。。。。。");
        }
        return userList;
    }

再次訪問結果如下:

 

 

 比原來的快:18倍左右

這是首次訪問呦(需要查一次mysql)

再來訪問一次:

 

 

不得不說redis果然快(快了75倍)

四、總結

redis集成SpringBoot用於查詢熱點數據果然好用,接下來在看看redis的其他應用場景。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM