【Android免費音樂下載app】【佳語音樂下載】建議最少2.0.3版本。最新版本:
https://gitlab.com/gaopinqiang/checkversion/raw/master/Music_Download.apk
Redis Window版本下載地址:https://github.com/microsoftarchive/redis/releases
當前下載的是最新 3.2.100 版本,比linux要落後好多。(沒有折騰VM下裝linux,有時間可以搞個linux虛擬機)
Redis可視化工具:Redis Desktop Manager
下載地址:https://github.com/qishibo/AnotherRedisDesktopManager/releases
如果只是簡單的查看,直接用自帶的redis-cli.exe就可以。也可以使用Redis自帶命令查看
啓動redis服務(2種方式):
-
a.在redis解壓目錄運行cmd,啓動redis命令(cmd關閉,服務停止)
【redis-server.exe】默認配置啓動
【redis-server.exe redis.windows-service.conf】配置文件啓動
-
b.將redis服務安裝到系統,安裝服務後啓動
【redis-server.exe --service-install redis.windows-service.conf】(會安裝到系統的服務中)
【redis-server.exe --service-start】(啓動服務)
【redis-server --service-stop】(停止服務)
設置redis密碼:
將redis.windows-service.conf文件中的配置修改下。
# requirepass foobared
修改成:
requirepass 123456
在通過加載配置文件啓動,通過redis-cli.exe查看是否生效
【auth 123456】輸入密碼連接
Redis服務啓動好,SpringBoot可以集成Redis開發了。
一、SpringBoot 集成 Redis 的步驟如下:(前提啓動了Redis服務)
1、在pom.xml中配置相關的jar依賴;
<!-- 加載spring boot redis包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、在Springboot核心配置文件application.properties中配置redis連接信息:
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=123456
3、配置了上面的步驟,Spring boot將自動配置RedisTemplate,在需要操作redis的類中注入redisTemplate;
在使用的類中注入:(ServiceImpl中)
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
StudentServiceImpl.java
package com.example.mybatis.service.impl;
import com.example.mybatis.mapper.StudentMapper;
import com.example.mybatis.model.Student;
import com.example.mybatis.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
/** 注入springboot自動配置好的RedisTemplate */
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Override
public List<Map<String, Object>> getStudent(String id) {
return studentMapper.getStudent(id);
}
@Override
public List<Student> getStudent1(String id) {
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
if(null == studentList){
studentList = studentMapper.getStudent1(id);
redisTemplate.opsForValue().set("allStudents",studentList);
System.out.println("查詢數據庫,將數據存入redis緩存");
}else{
System.out.println("查詢Redis緩存");
}
return studentList;
}
@Override
public int updateById(Student student) {
return studentMapper.updateById(student);
}
}
SpringBoot幫我們注入的redisTemplate類,泛型裏面只能寫 <String, String>、<Object, Object>
測試運行截圖如下:
這個時候通過Redis的可視化工具,看到已經存入緩存數據。但是鍵值會出現Unicode編碼
//字符串序列化器
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
二、Redis高併發條件下的緩存穿透問題。
在一個方法中,有很多人同時請求時候,都會去操作數據庫,並沒有讀取到緩存。比如10000人同時請求,就會請求10000次數據庫。而我們只希望請求一次數據庫。
出現緩存穿透問題截圖如下:
解決的方式就是使用syncronized同步鎖。
可以直接在方法上加鎖。但是這樣會犧牲效率,每次多個請求同時過來,只能一個一個處理。(不推薦)
下面介紹推薦的方式(雙重檢測鎖),代碼如下:
StudentServiceImpl:
@Override
public List<Student> getStudent1(String id, String name) {
// return studentMapper.getStudent1("1","qiang");
// List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
//字符串序列化器
RedisSerializer redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
List<Student> studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
//雙重檢測鎖
if(null == studentList){//第一次請求才會爲空,後面不管多少個人同時請求,都不會走到syncronized代碼處。
synchronized (this){
//從redis獲取下
studentList = (List<Student>) redisTemplate.opsForValue().get("allStudents");
if(null == studentList){//比如1w人同時請求,第一個人才會使用數據庫,後面的9999人都是使用緩存數據
studentList = studentMapper.getStudent1(id,"qiang");
redisTemplate.opsForValue().set("allStudents",studentList);
System.out.println("查詢數據庫,將數據存入redis緩存");
}else{
System.out.println("查詢Redis緩存");
}
}
}
return studentList;
}
測試:
StudentController:
@RequestMapping("/getStudent1")
public @ResponseBody String getStudent1(){
//測試Redis緩存
Runnable runnable = new Runnable() {
@Override
public void run() {
studentService.getStudent1("1","qiang");
}
};
//多線程測試下Redis緩存穿透問題
ExecutorService executorService = Executors.newFixedThreadPool(25);
for (int i = 0; i < 10000; i++) {
executorService.submit(runnable);
}
List<Student> student = studentService.getStudent1("1","qiang");
return student.toString();
}
成功截圖如下:
哨兵模式redis集羣配置:(瞭解下即可,實際開發中再深入研究)
redis:
password: 123456
sentinel:
master: mymaster
nodes: 127.0.0.1:26380,127.0.0.1:26382,127.0.0.1:26384