本文內容主要基於 Salvatore Sanfilippo 在今年六月26-27日 Redis Day New York 上關於 Redis 6 新功能的分享,加上目前在官方(博客、Twitter等)已經公開內容做爲補充,並經過 Github 上的 unstable 分支(截至本文時間2019年8月2日)進行測試驗證。git
Salvatore Sanfilippo(如下均簡稱爲做者)在 Redis Day New York 上的分享在YouTube 上已經發布,原連接請見連接(固然,你須要科學的上網工具)。
啥也不說,先上原圖。github
嗯,至關魔性。這個就是做者分享的原圖。別人都是帶個精心準備好的PPT,他就帶個白板上來畫畫畫,有技術就能夠隨心所欲?>_<redis
做者先簡單介紹 Redis 6 會給你們提供的新功能,包括:算法
1、對用戶使用有直接影響的功能數據庫
2、Redis 內部的優化數組
3、外部工具緩存
做者分享着重介紹了(一)裏面的1-3點,其餘幾點有所說起。本文也按照這個內容進行分享。服務器
目前的 Redis(5及如下版本),沒有用戶權限管理這個概念,只有一個AUTH
密碼驗證功能,基本上可以接入的用戶就是root
用戶。
ACL 就是爲了不接入的用戶進行危險命令的操做開發的功能,這類命令如 FLUSHALL
,DEBUG
等。還記得我以前分享過的一篇文章《從清檔到二級索引》
多年來 Redis 管理員經過RENAME
命令來進行限制。另外一方面,開發人員有時候不清楚一些Redis 驅動的內部實現,可能無心中觸發一些危險命令,因此也須要進行限制。
Redis 6 中加入ACL的功能,可以對接入的用戶進行三個層面的權限控制:
(1)接入權限:用戶名和密碼;
(2)能夠執行的命令;
(3)能夠操做的 KEY。
下面咱們實際代碼中看看效果,下面展現我建立一個用戶aaron,設置他的密碼,容許執行全部命令,針對全部KEY。session
127.0.0.1:6380> ACL WHOAMI "default" 127.0.0.1:6380> ACL setuser aaron on >mypasswd +@all ~* OK 127.0.0.1:6380> AUTH aaron mypasswd OK 127.0.0.1:6380> ACL WHOAMI "aaron" 127.0.0.1:6380> GET foo (nil) 127.0.0.1:6380> SET foo bar OK
而後我嘗試將 aaron 這個用戶去掉SET
命令的權限。多線程
127.0.0.1:6380> ACL setuser aaron -SET OK 127.0.0.1:6380> SET foo 123 (error) NOPERM this user has no permissions to run the 'set' command or its subcommand
咱們也能夠控制用戶能夠對哪些 KEY 進行操做,好比下面演示一個叫作 Ben 的用戶,他只能建立以 ben
爲前綴的 KEY。
127.0.0.1:6380> ACL setuser ben on >mypasswd +@all ~ben* OK 127.0.0.1:6380> set foo bar (error) NOPERM this user has no permissions to access one of the keys used as arguments 127.0.0.1:6380> set benfoo bar OK
"default" 用戶是咱們默認鏈接入 Redis 時的用戶,默認狀況下這個用戶有全部的權限,固然了,咱們也能夠像之前那樣給默認用戶設置權限。經過ACL list
能夠查看當前有哪些用戶和他們的權限和密碼(前提是該用戶有ACL命令的權限)。
127.0.0.1:6380> ACL list 1) "user aaron on >mypasswd ~* +@all -set" 2) "user default on nopass ~* +@all"
做者提到ACL功能是基於 bitmap 實現的,對性能幾乎沒有影響。
關於ACL功能就介紹到這裏,有興趣的做者能夠看官方文檔:
https://redis.io/topics/acl
RESP 全稱 REdis Serialization Protocol,是 Redis 服務端與客戶端之間通訊的協議。Redis 5 使用的是 RESP2,而 Redis 6 開始在兼容 RESP2 的基礎上,開始支持 RESP3。其實一開始做者是打算徹底放棄 RESP2的,後來被勸退了。詳情見連接(http://antirez.com/news/125)。
那麼 RESP3 有哪些改進的地方呢?
照例上個原圖:
這個圖中,做者分享的是,在 RESP2 中,全部的返回內容,都是一個字符串數組的形式,不論是 list 仍是 sorted set。所以客戶端須要自行去根據類型進行解讀,增長了客戶端實現的複雜性。
下面以具體的命令展現 RESP3 中的具體變化。
127.0.0.1:6380> HSET myhash a 1 b 2 c 3 (integer) 3 127.0.0.1:6380> HGETALL myhash 1) "a" 2) "1" 3) "b" 4) "2" 5) "c" 6) "3" 127.0.0.1:6380> HELLO 3 #轉換成RESP3的命令 1# "server" => "redis" 2# "version" => "999.999.999" 3# "proto" => (integer) 3 4# "id" => (integer) 5 5# "mode" => "standalone" 6# "role" => "master" 7# "modules" => (empty array) 127.0.0.1:6380> HGETALL myhash 1# "a" => "1" 2# "b" => "2" 3# "c" => "3"
其實從 redis-cli 來看意義不大,由於顯示出來的信息已經通過處理,最直接的方式是直接telnet
以後進行操做看返回結果:
$ telnet 127.0.0.1 6380 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. AUTH aaron mypasswd +OK HGETALL myhash *4 $1 a $1 1 $1 b $1 2 HELLO 3 (此處省略) HGETALL myhash %2 $1 a $1 1 $1 b $1 2
能夠看到,之前返回兩個field的hash,就是直接無差異地返回4個值,而新的RESP3就會告訴客戶端返回兩個key-value,經過%
表示鍵值對(也成爲map類型)的個數。
另外做者也對空字符串進行了定義:
(RESP2) GET null_key $-1 (RESP3) GET null_key _
其餘新的定義還有很多,好比支持 Boolean 類型,set集合類型等等,有興趣的讀者,也是能夠去詳細看看 RESP3 的設計稿:
https://github.com/antirez/RE...
除了具體的數據類型,RESP3 開始支持KEY屬性類型(Attribute type),使服務器和客戶端之間能夠實現更復雜的功能,好比返回信息裏帶上一個Key的訪問頻率,使客戶端能實現更智能的緩存功能(http://antirez.com/news/130)。話說,客戶端緩存功能,能夠說是在提高 Redis 做爲緩存的讀寫能力有了質的飛躍,值得期待。
其餘方面做者沒有做太深刻的分享,所以我下面也只是簡單提一下,而且附上相關的資料,若是讀者有興趣想了解,歡迎留言給我,我下次分享相關主題。
做者分享說redis-trib.rb
的功能集成到redis-cli
,但這個不是 Redis 5 就已經作了的事情嗎?看了一圈,也並無太大的變化,就增長了一個backup
命令。
除了redis-cli
,其實另外一個工具的優化更讓人喜聞樂見,就是redis-benchmark
。
$ src/redis-benchmark --help Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests>] [-k <boolean>] (省略部分輸出結果……) --threads <num> Enable multi-thread mode. --cluster Enable cluster mode. --enable-tracking Send CLIENT TRACKING on before starting benchmark.
官方benchmark工具總算支持cluster了,經過多線程的方式對多個分片進行壓測。
Amazon 提供的一個功能,在 Redis 6 中 merge 進來。沒有說起細節,不清楚對性能有多大影響。
Redis 終於實現多線程了!?先打住,多線程是不可能多線程的,這輩子都不可能多線程(後面這句是我加的)。
做者先簡單解釋了爲何不能多線程(複雜性、鎖的效率等等),而後提到就是有一個事情能夠作成多線程,就是針對客戶端的這部分。這個操做經過系統調用寫操做,將客戶端的輸入輸出緩衝中的數據經過多線程IO與客戶端交互。做者說這部分一般可以佔到CPU負載的50%,將這部分經過其餘線程進行處理,核心流程仍是單線程,實現起來也比較簡單,性價比超高,因此就作了。
這樣能進一步提高單實例的性能,使用4核、8核等來分散寫壓力,不過再多幾個核估計收益比不高了。若是真正想發揮多核性能,仍是老路子——Cluster。
新的Modules API,讓Module功能能夠作更多的事情,但做者沒有展開講。
這部分由於涉及到的背景和算法比較多,因此會另外開一個 session 來分享。(視頻也能夠在YouTube上看了)
針對 Cluster 的代理,這麼多年了,仍然有很多人在Cluster的接入方式上掙扎,由於缺乏合適的驅動而沒法使用Cluster。因此開發了這個Proxy功能。做者也強調,雖然這個Proxy 讓 Cluster 擁有了像單實例同樣的接入方式,可是本質上仍是 Cluster,不支持的命令仍是不會支持,好比跨 slot 的多Key操做。
其實社區早已有過很多 Proxy 方面的嘗試,並且有些作的還不錯。那麼這個官方的 Proxy 究竟會給咱們帶來什麼驚喜呢?仍是讓咱們拭目以待吧。
這個原本是做者幾年前開發的一個基於 Redis 的消息隊列工具,但多年來做者發現 Redis 在持續開發時,他也要持續把新的功能合併到這個Disque 項目裏面,這裏有大量無用的工做。所以此次他在 Redis 的基礎上經過 Modules 功能實現 Disque。
若是業務並不須要保持嚴格消息的順序,這個 Disque 能提供足夠簡單和快速的消息隊列功能。
對我來講,這個版本能夠說有史以來變化最大的一次升級(若是不是最大也是之一了)。不論是從使用者,DBA,客戶端工具開發者,仍是運維的角度來看,都有了很多的變化。此次升級使得 Redis 從總體上更接近一個完整的數據庫(對比 MongoDB)。另外一方面,此次升級給全部相關的人員帶來了不少變化,恐怕後面要忙好一陣子了。
不知道你們看完 Redis 6 的新功能以後有什麼感想?限於篇幅,本文只是按做者重點分享的內容進行整理,其實每一項變化彷佛均可以新寫一篇文章來分享。若是有你感興趣的內容,也能夠留言一下,有機會下次我能夠分享。
更多資訊,歡迎關注公衆號:最簡實踐