Redis(Remote Dictionary Server)是一個開源的內存中數據結構存儲系統,通常被用作緩存、消息隊列和實時數據處理等場景。它的簡單性、高性能以及豐富的數據結構支持使其成為了眾多開發者和企業的首選。在Redis 6.0版本中,引入了一系列令人期待的新特性和改進,本文將深入探討這些新特性,以便開發者更好地理解和利用Redis在其項目中的潛力。
1.新特性
- 深度嵌套的從復制:在Redis 6.0中,引入了深度嵌套的從復制,使得從節點可以成為其他主節點的從節點,從而構建多級的從節點拓撲結構。這一特性提高了系統的可擴展性和靈活性,使得數據在分布式環境中更加可靠。
- 線程模型改進:Redis 6.0對線程模型進行了改進,引入了新的I/O線程,使得Redis能夠更好地利用多核處理器的性能。這一改進提高了Redis在高負載環境下的性能表現,并降低了對單個CPU核心的依賴。
- 新的RDB版本:Redis 6.0引入了新的RDB版本(RDB版本 9),在處理大型數據庫時具有更好的性能和可靠性。這一改進使得Redis在備份和恢復大規模數據時更加高效,降低了與持久化相關的性能開銷。
- 慢查詢日志改進:Redis 6.0對慢查詢日志進行了改進,引入了新的命令
SLOWLOG GET
,使得開發者能夠更加靈活地檢索和分析慢查詢日志。這一改進有助于開發者更好地識別和優化性能瓶頸,提高系統的響應速度。 - TLS支持: Redis 6.0新增了對TLS(Transport Layer Security)的支持,通過加密保護數據在傳輸過程中的安全性。這一改進使得Redis在安全性方面更加強大,并能夠滿足更嚴格的安全要求。
2. 多線程模型
1. redis 6.0 提供了多線程的支持,redis 6 以前的版本,嚴格來說也是多線程,只不過執行用戶命令的請求時單線程模型,還有一些線程用來執行后臺任務, 比如 unlink 刪除 大key,rdb持久化等。
redis 6.0 提供了多線程的讀寫IO, 但是最終執行用戶命令的線程依然是單線程的,這樣,就沒有多線程數據的競爭關系,依然很高效。
redis 6.0 以前線程執行模式,如下操作在一個線程中執行完成
?
redis 6.0 線程執行模式:
可以通過如下參數配置多線程模型:
如:
io-threads 4 // 這里說 有三個IO 線程,還有一個線程是main線程,main線程負責IO讀寫和命令執行操作
默認情況下,如上配置,有三個IO線程, 這三個IO線程只會執行 IO中的write 操作,也就是說,read 和 命令執行 都由main線程執行。最后多線程將數據寫回到客戶端。
?
開啟了如下參數:
io-threads-do-reads yes // 將支持IO線程執行 讀寫任務。
?
3. client side caching
客戶端緩存:redis 6 提供了服務端追蹤key的變化,客戶端緩存數據的特性,這需要客戶端實現
?
執行流程為, 當客戶端訪問某個key時,服務端將記錄key 和 client ,客戶端拿到數據后,進行客戶端緩存,這時,當key再次被訪問時,key將被直接返回,避免了與redis 服務器的再次交互,節省服務端資源,當數據被其他請求修改時,服務端將主動通知客戶端失效的key,客戶端進行本地失效,下次請求時,重新獲取最新數據。
目前只有lettuce對其進行了支持:
<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.0.0.RELEASE</version>
</dependency>
public static void main(String[] args) throws InterruptedException {RedisClient redisClient = RedisClient.create("redis://192.168.109.200");Map<String, String> clientCache = new ConcurrentHashMap<>();StatefulRedisConnection<String, String> myself = redisClient.connect();CacheFrontend<String, String> frontend =ClientSideCaching.enable(CacheAccessor.forMap(clientCache),myself,TrackingArgs.Builder.enabled().noloop());String key="csk";int count = 0;while (true){System.out.println(frontend.get(key));TimeUnit.SECONDS.sleep(3);if (count++ == Integer.MAX_VALUE){myself.close();redisClient.shutdown();}}
}
4.Acls訪問權限控制
ACL 是對于命令的訪問和執行權限的控制,默認情況下,可以有執行任意的指令,兼容以前版本
ACL設置有兩種方式:
1. 命令方式
ACL SETUSER + 具體的權限規則, 通過 ACL SAVE 進行持久化
2. 對 ACL 配置文件進行編寫,并且執行 ACL LOAD 進行加載
ACL存儲有兩種方式,但是兩種方式不能同時配置,否則直接報錯退出進程
1.redis 配置文件: redis.conf
2.ACL配置文件, 在redis.conf 中通過 aclfile /path 配置acl文件的路徑
命令方式:
ACL SETUSER alice // 創建一個 用戶名為 alice的用戶
用如上的命令創建的用戶語義為:
- 處于 off 狀態, 它是被禁用的,不能用auth進行認證
- 不能訪問任何命令
- 不能訪問任意的key
- 沒有密碼
如上用戶alice 沒有任何意義。
創建一個對 cached: 前綴具有get命令執行權限的用戶,并且設置密碼:
acl setuser alice on >pass123 ~cached:* +get
auth alice pass123
set a a
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
get a a
(error) NOPERM this user has no permissions to access one of the keys used as arguments
get cached:name
vvv
如上,如果訪問沒有被授權的命令,或者key, 將報錯,set 命令沒有被授權, key a 沒有被授權,
cached:name 可以通過驗證。
更符合閱讀習慣的格式
ACL GETUSER alice
添加多個訪問模式,空格分隔, 注意,切換其他用戶進行登錄,alice沒有admin權限
ACL SETUSER alice ~objects:* ~items:* ~public:*
針對類型命令的約束
ACL SETUSER alice on +@all -@dangerous >密碼 ~*
這里+@all: 包含所有得命令 然后用-@ 去除在redis command table 中定義的 dangerous 命令
?
可以通過如下命令進行查看具體有哪些命令屬于某個類別
acl cat // 查看所有類別
acl cat dangerous // 查看所有的 dangerous 命令
開放子命令
ACL SETUSER myuser -client +client|setname +client|getname
禁用client 命令,但是開放 client 命令中的子命令 setname 和 getname ,只能是先禁用,后追加子命令,因為后續可能會有新的命令增加。
5. 總結
以下是使用表格對比Redis 6.0與舊版本的主要特性和改進:
特性/改進 | Redis 6.0 | 舊版本 |
---|---|---|
深度嵌套的從復制 | 支持深度嵌套的從復制,構建多級從節點拓撲結構 | 僅支持單級從節點拓撲結構 |
線程模型改進 | 引入新的I/O線程,更好地利用多核處理器性能 | 線程模型相對簡單,性能受限 |
新的RDB版本 | 引入RDB版本 9,處理大型數據庫性能更優 | 舊版本存在性能瓶頸,處理大規模數據效率低 |
慢查詢日志改進 | 引入新的命令SLOWLOG GET ,更靈活地檢索和分析慢查詢日志 | 慢查詢日志功能相對簡單,缺乏靈活性 |
TLS支持 | 新增對TLS的支持,保護數據在傳輸過程中的安全性 | 缺乏對傳輸層安全性的支持 |
?
更多文章
Redis為何如此快速?-CSDN博客
Redis持久化、主從與哨兵架構詳解-CSDN博客
Redis集群選舉流程詳解-CSDN博客
ZAB 協議解析:ZooKeeper分布式一致性的核心-CSDN博客
MySQL8:開啟數據庫管理的新時代-CSDN博客
?
?