Redis 性能優化 18 招
前言
Redis 在我們的日常開發工作中,使用頻率非常高,已經變成了必不可少的技術之一。
Redis 的使用場景也很多。
比如:保存用戶登錄態,做限流,做分佈式鎖,做緩存提升數據訪問速度等等。
那麼問題來了,Redis 的性能要如何優化?
爲了提升 Redis 的性能,這篇文章跟大家一起聊聊 Redis 性能優化的 18 招,希望對你會有所幫助。
- 選擇合適的數據結構
Redis 支持多種數據結構,如字符串、哈希、列表、集合和有序集合。根據實際需求選擇合適的數據結構可以提高性能。
如果要存儲用戶信息,考慮使用哈希而不是多個字符串:
jedis.hset("user:1001", "name", "Alice");
jedis.hset("user:1001", "age", "30");
這樣可以高效地存儲和訪問多個屬性。
- 避免使用過大的 key 和 value
較長的 key 和 value 會佔用更多內存,還可能影響性能。
保持 key 簡短,並使用簡潔的命名約定。
比如:將 “user:1001:profile” 簡化爲“u:1001:p”。
還可以做壓縮等其他優化。
- 使用 Redis Pipeline
對多個命令的批量操作,使用 Pipeline 可以顯著降低網絡延遲,提升性能。
比如,批量設置 key 可以這樣做:
Pipeline p = jedis.pipelined();
for (int i = 0; i < 1000; i++) {
p.set("key:" + i, "value:" + i);
}
p.sync();
這樣一次性可以發送多個命令,減少了網絡往返時間,能夠提升性能。
- 控制連接數量
過多的連接會造成資源浪費,使用連接池
可以有效管理連接數量。
比如,使用 JedisPool:
JedisPool pool = new JedisPool("localhost");
try (Jedis jedis = pool.getResource()) {
jedis.set("key", "value");
}
有了連接池,這樣連接就會被複用,而不是每次都創建新連接,使用完之後,又放回連接池。
能有效的節省連接的創建和銷燬時間。
- 合理使用過期策略
設置合理的過期策略,能防止內存被不再使用的數據佔滿。
例如,緩存熱點數據可以設置過期時間。
比如,對會話數據設置過期時間:
jedis.setex("session:12345", 3600, "data");
Redis 內部會定期清理過期的緩存。
- 使用 Redis 集羣
數據量增大時,使用 Redis 集羣可以將數據分散到多個節點,提升併發性能。
可以將數據哈希分片到多個 Redis 實例。
這樣可以避免單個 Redis 實例,數據太多,佔用內存過多的問題。
- 充分利用內存優化
選擇合適的內存管理策略,Redis 支持 LRU(Least Recently Used)策略,可以自動刪除不常用的數據。
比如,配置 Redis 的 maxmemory:
maxmemory 256mb
maxmemory-policy allkeys-lru
- 使用 Lua 腳本
Lua 腳本讓多條命令在 Redis 中原子性執行,減少網絡延遲。
比如,使用 Lua 防止多個命令的網絡延遲:
EVAL "redis.call('set', KEYS[1], ARGV[1]) return redis.call('get', KEYS[1])" 1 "key" "value"
使用 Lua 腳本,可以保證 Redis 的多個命令是原子性操作。
- 監控與調優
使用 INFO 命令監控 Redis 性能數據,如命令支持、內存使用等,及時調優。
比如,使用命令獲取監控信息:
INFO memory
INFO clients
- 避免熱點 key
熱點 key 會造成單一節點的壓力,通過隨機化訪問來避免。
比如,可以爲熱點 key 加隨機後綴:
String key = "hotkey:" + (System.currentTimeMillis() % 10);
jedis.incr(key);
- 使用壓縮
存儲大對象時,考慮使用壓縮技術來節省內存。
比如,可以使用GZIP
壓縮 JSON 數據:
byte[] compressed = gzipCompress(jsonString);
jedis.set("data", compressed);
- 使用 Geo 位置功能
Redis 支持地理位置存儲和查詢,使用GEOADD
可以高效管理地理數據。
比如,存儲地點信息:
jedis.geoadd("locations", longitude, latitude, "LocationName");
- 控制數據的持久化
合理設置RDB
和AOF
的持久化策略,避免頻繁寫盤造成性能下降。
示例:設置持久化的時間間隔:
save 900 1
appendonly yes
- 儘量減少事務使用
在高併發場景下,避免過度使用 MULTI/EXEC,因爲事務會鎖住 key。
可以直接使用單條命令替代事務。
- 合理配置客戶端
調整客戶端的連接超時和重連策略,以適應高負載場景,確保連接穩定。
例如:
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128); // 最大連接數
poolConfig.setMaxIdle(64); // 最大空閒連接
poolConfig.setMinIdle(16); // 最小空閒連接
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379, 2000); // 連接超時2000ms
- 使用 Redis Sentinel
使用Sentinel
進行監控,實現高可用性,確保系統在故障時能夠快速切換。
配置 Sentinel 進行主從複製。
- 優化網絡配置
保證 Redis 服務器有良好的網絡帶寬,避免網絡瓶頸。
使用服務器內部專線,減少延遲。
- 定期清理不必要的數據
生命週期管理很關鍵,定期刪除過期或不必要的數據,保持內存高效利用。
可以設置Cron
任務定期清理。
雖說 Redis 內部會清理過期的數據,但有些長期存在的垃圾數據,也建議及時清理。
總結
以上就是 Redis 性能優化的 18 招,靈活應用這些策略能夠爲你的項目帶來顯著的性能提升。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/znS0ogvjeMFTeD-NnIMTMA