文章目錄
- “緩存預熱” 是什么?
- 項目環境搭建
- 創建數據訪問層
- 預熱數據到 Redis 中
- 創建緩存服務類
- 測試緩存預熱
“緩存預熱” 是什么?
緩存預熱是一種優化策略,在系統啟動或者流量高峰來臨之前,將一些經常訪問的數據提前加載到緩存中。這樣做的好處是,當用戶實際請求這些數據時,能夠直接從緩存中獲取,避免了從數據庫等慢速數據源中查詢數據,從而提高系統的響應速度和吞吐量,減少數據庫的壓力。
緩存預熱通常發生在以下情況下:
-
系統投入使用前:
在系統正式投入使用之前,可以對一些初始化數據進行預熱,以避免系統上線初期因為大量數據未被緩存而導致的性能問題。
-
數據訪問熱度周期性變化較高的情況下:
對于有些數據,其訪問熱度可能會隨著時間變化而變化,可以在預計到達高峰期之前預熱這些數據,以確保在高峰期能夠直接從緩存中獲取,提高系統性能。
實際上,緩存預熱是一種以時間換空間的策略,通過預先將需要頻繁訪問的數據加載到緩存中,來減少后續訪問時因為緩存未命中而導致的性能損失。
例如,一個電商網站準備舉辦大型促銷活動,預計將有大量用戶訪問某一特定類別的商品頁面。為了避免在活動期間因為商品數據緩存未命中而導致系統性能下降,可以提前對這一類別的商品信息進行緩存預熱。即在活動開始之前,系統可以將這類商品的信息提前加載到緩存中,以確保在活動期間可以直接從緩存中獲取數據,提高系統的響應速度。
以下是一個基于 SpringBoot 與 Redis 的緩存預熱案例。
項目環境搭建
-
引入依賴:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
定義啟動類:
package test;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class SpringBootApp {public static void main(String[] args) {SpringApplication.run(SpringBootApp.class, args);}}
-
定義配置:
spring:redis:# Redis主機IPhost: localhost# Redis主機端口port: 6379# Redis主機密碼password:# 使用Redis的8號庫database: 8# 使用lettuce客戶端lettuce:# 連接池配置pool:# 最大連接數max-active: 8# 最大空閑連接max-idle: 8# 最小空閑連接min-idle: 0# 連接等待時間max-wait: 100
創建數據訪問層
模擬從數據庫中獲取用戶數據。
package test;import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.List;@Repository
public class UserDao {/*** 模擬從數據庫中獲取所有用戶** @return 所有用戶*/public List<User> getAllUsers() {List<User> users = new ArrayList<>();users.add(new User(1L, "Alice"));users.add(new User(2L, "Bob"));users.add(new User(3L, "Charlie"));return users;}}
預熱數據到 Redis 中
實現 CommandLineRunner
接口,在 Spring Boot 應用啟動時執行緩存預熱操作。
package test;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.util.List;@Component
@Slf4j
public class CachePreheater implements CommandLineRunner {@Autowiredprivate UserDao userDao;@Autowiredprivate UserCacheService userCacheService;@Overridepublic void run(String... args) {// 從數據庫獲取所有用戶數據List<User> users = userDao.getAllUsers();// 將用戶數據緩存到 Redis 中userCacheService.cacheUsers(users);log.info("Cache preheating completed.");}}
啟動 SpringBoot 應用,控制臺輸出如下結果:
以上結果說明,數據已經成功被預熱到緩存(Redis)中。
創建緩存服務類
負責將用戶數據緩存到 Redis 中,并從 Redis 中獲取用戶數據。
package test;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class UserCacheService {@Resourceprivate RedisTemplate<String, User> redisTemplate;public void cacheUsers(List<User> users) {for (User user : users) {redisTemplate.opsForValue().set("user:" + user.getId(), user);}}public User getUserFromCache(Long userId) {return redisTemplate.opsForValue().get("user:" + userId);}}
測試緩存預熱
創建一個控制器來測試緩存是否預熱成功。
package test;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserCacheService userCacheService;@GetMapping("/users/{userId}")public User getUser(@PathVariable Long userId) {return userCacheService.getUserFromCache(userId);}}
在瀏覽器中訪問 http://localhost:8080/users/1
,得到的響應結果:
以上結果說明,成功從緩存中獲取到了預熱到的數據。