Redis 賦能!Spring Boot 實現高性能分頁+多條件模糊查詢
Redis 作為一款高性能的內存數據庫,支持多種數據結構,包括 String、List、Set、SortedSet 和 Hash 等。通常,我們在 Redis 中根據 key 來檢索相應的值,但 Redis 并不原生支持模糊查詢功能。因此,在需要進行分頁、排序以及復雜條件檢索(如評論管理、時間線排序、搜索等)的場景下,直接使用 Redis 可能無法滿足需求。
本文將基于 Redis 設計一種高效的分頁與模糊查詢方案,結合 Spring Boot 3.4,提供思路和實踐方法,幫助大家更好地利用 Redis 提升查詢性能。
方案設計
Redis 實現分頁查詢
在傳統關系型數據庫(如 MySQL、Oracle)中,分頁通常依賴 LIMIT 和 OFFSET 進行查詢。但在 Redis 中,我們可以借助 SortedSet(ZSet)來高效實現分頁。
關鍵指令解析
- ZADD key score member向有序集合中添加元素,并指定排序權重 score。
- ZREVRANGE key start stop按照 score 逆序返回指定范圍的元素,用于分頁。
- ZREM key member從有序集合中移除某個元素,適用于刪除操作。
通常,我們會將數據的時間戳作為 score 進行排序,從而實現基于時間的分頁檢索。SortedSet 相較于 List 具有自動排序的能力,并且可以根據 score 進行篩選,使其成為更適合分頁查詢的數據結構。
Redis 實現模糊查詢
由于 Redis 是基于 key-value 存儲的數據庫,并不具備 SQL 級別的查詢能力,因此我們需要利用 Redis 提供的 Hash 結構自行實現模糊查詢。
HSCAN 指令實現模糊匹配
Redis 的 HSCAN 指令允許遍歷 Hash 結構中的 key,并支持模式匹配。
示例存儲格式:
field: <id>:<姓名>:<性別>
value: {"id": 1001, "name": "張三", "gender": "男"}
查詢示例:
- HSCAN user_data 0 MATCH *:*:男 —— 獲取所有性別為“男”的用戶。
- HSCAN user_data 0 MATCH 100*:*:* —— 獲取所有 ID 以 100 開頭的用戶。
分頁+多條件模糊查詢的組合實現
分頁和模糊查詢各自獨立實現后,我們需要將它們結合,支持在模糊查詢的基礎上進行分頁。
方案思路
- 模糊查詢階段使用 HSCAN 遍歷 Hash,篩選符合條件的 field,將匹配的 key 存入 Redis 的一個臨時 ZSet 集合。
- 分頁階段在 Redis 中查詢該 ZSet 集合,并使用 ZREVRANGE 進行分頁。
- 緩存優化為 ZSet 集合設置 TTL,避免 Redis 負載過高。
性能優化策略
- 設置過期時間
- 生成的 ZSet 結果集合可設置短時間 TTL,避免緩存過載。
- 在訪問集合時重置 TTL,延長熱點數據的生命周期。
- 實時性保障
插入新數據時,需同步更新 ZSet 相關集合。
或者,定期觸發批量更新,減少實時更新的開銷。
代碼示例
1. 在 Redis 中存儲數據
@Autowired
private StringRedisTemplate redisTemplate;
public void saveData(String key, String value, double score) {
redisTemplate.opsForZSet().add("data_zset", value, score);
}
2. 分頁查詢
public Set<String> getPaginatedData(int page, int pageSize) {
int start = (page - 1) * pageSize;
int end = start + pageSize - 1;
return redisTemplate.opsForZSet().reverseRange("data_zset", start, end);
}
3. 模糊查詢
public List<String> fuzzySearch(String pattern) {
List<String> result = new ArrayList<>();
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan("user_data", ScanOptions.scanOptions().match(pattern).build());
while (cursor.hasNext()) {
result.add(cursor.next().getKey().toString());
}
return result;
}
結論
本文介紹了一種基于 Redis 實現高性能分頁+多條件模糊查詢的思路。通過 SortedSet 進行分頁,結合 Hash 結構與 HSCAN 實現模糊匹配,并優化查詢效率,能夠大幅提升查詢性能。希望本文的方案能夠幫助大家更高效地使用 Redis 進行復雜查詢優化。