導致Redis訪問慢的原因通常有2個方面:
第一,Redis本身性能出現了瓶頸,如:內存使用率過高,並發過大等
第二,存在大KEY,或者客戶端訪問命令使用不當引起的阻塞
在此,只列舉因為的客戶端命令使用不當導致訪問Redis慢的操作,表現出來的現象就是:某些接口的訪問耗時不穩定,時好時壞。
無序集合“SMEMBERS”命令
當無序集合(SET)中的元素個數很多時,使用“SMEMBERS”命令訪問可能會引起Redis訪問阻塞。
替代方案:使用SSCAN
命令代替SMEMBERS
命令。
使用示例:
// 使用SMEMBERS命令訪問集合所有元素
Set<String> set = redisTemplate.opsForSet().members(key);
// 使用SSCAN命令訪問集合所有元素
Set<String> set = new HashSet<>();
Cursor<String> cursor = this.redisTemplate.opsForSet().scan(key, ScanOptions.NONE);
try {
while (cursor.hasNext()) {
String value = cursor.next();
set.add(value)
}
} finally {
try {
cursor.close();
} catch (Exception e) {}
}
哈希集合“HGETALL”命令
當哈希集合(HASH)中的元素很多時,使用“HGETALL”命令獲取所有元素可能會引起Redis訪問阻塞。
替代方案:使用HSCAN
命令替代HGETALL
命令。
使用示例:
// 使用HGETALL命令獲取集合所有元素
Map<String, Object> map = redisTemplate.opsForHash().entries(key);
// 使用HSCAN命令訪問集合所有元素
Map<String, Object> map = new HashMap<>();
Cursor<Map.Entry<String, Object>> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE);
try {
while (cursor.hasNext()) {
Map.Entry<String, Object> entry = cursor.next();
if (entry.getKey() == null || entry.getValue() == null) {
continue;
}
map.put(entry.getKey(), entry.getValue());
}
} finally {
try {
cursor.close();
} catch (Exception e) {}
}
【參考】
http://kaito-kidd.com/2021/01/23/redis-slow-latency-analysis/ Redis為什么變慢了?一文講透如何排查Redis性能問題 | 萬字長文
http://xiaoyue26.github.io/2020/03/23/2020-03/redis大key問題/ redis大key問題