Redis 6 新功能提早看!

本文內容主要基於 Salvatore Sanfilippo 在今年六月26-27日 Redis Day New York 上關於 Redis 6 新功能的分享,加上目前在官方(博客、Twitter等)已經公開內容做爲補充,並經過 Github 上的 unstable 分支(截至本文時間2019年8月2日)進行測試驗證。git

Overview

Salvatore Sanfilippo(如下均簡稱爲做者)在 Redis Day New York 上的分享在YouTube 上已經發布,原連接請見連接(固然,你須要科學的上網工具)。
啥也不說,先上原圖。github

嗯,至關魔性。這個就是做者分享的原圖。別人都是帶個精心準備好的PPT,他就帶個白板上來畫畫畫,有技術就能夠隨心所欲?>_<redis

做者先簡單介紹 Redis 6 會給你們提供的新功能,包括:算法

1、對用戶使用有直接影響的功能數據庫

  1. ACL用戶權限控制功能
  2. RESP3:新的 Redis 通訊協議
  3. Cluster 管理工具
  4. SSL 支持

2、Redis 內部的優化數組

  1. IO多線程支持
  2. 新的Module API
  3. 新的 Expire 算法

3、外部工具緩存

  1. Redis Cluster Proxy
  2. Disque

做者分享着重介紹了(一)裏面的1-3點,其餘幾點有所說起。本文也按照這個內容進行分享。服務器

ACL

目前的 Redis(5及如下版本),沒有用戶權限管理這個概念,只有一個AUTH密碼驗證功能,基本上可以接入的用戶就是root用戶。
ACL 就是爲了不接入的用戶進行危險命令的操做開發的功能,這類命令如 FLUSHALLDEBUG等。還記得我以前分享過的一篇文章《從清檔到二級索引》
多年來 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

RESP3

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 做爲緩存的讀寫能力有了質的飛躍,值得期待。

其餘

其餘方面做者沒有做太深刻的分享,所以我下面也只是簡單提一下,而且附上相關的資料,若是讀者有興趣想了解,歡迎留言給我,我下次分享相關主題。

Cluster 管理工具

做者分享說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了,經過多線程的方式對多個分片進行壓測。

支持 SSL 鏈接

Amazon 提供的一個功能,在 Redis 6 中 merge 進來。沒有說起細節,不清楚對性能有多大影響。

IO多線程

Redis 終於實現多線程了!?先打住,多線程是不可能多線程的,這輩子都不可能多線程(後面這句是我加的)。

做者先簡單解釋了爲何不能多線程(複雜性、鎖的效率等等),而後提到就是有一個事情能夠作成多線程,就是針對客戶端的這部分。這個操做經過系統調用寫操做,將客戶端的輸入輸出緩衝中的數據經過多線程IO與客戶端交互。做者說這部分一般可以佔到CPU負載的50%,將這部分經過其餘線程進行處理,核心流程仍是單線程,實現起來也比較簡單,性價比超高,因此就作了。
這樣能進一步提高單實例的性能,使用4核、8核等來分散寫壓力,不過再多幾個核估計收益比不高了。若是真正想發揮多核性能,仍是老路子——Cluster。

Modules API

新的Modules API,讓Module功能能夠作更多的事情,但做者沒有展開講。

新Expire過時算法

這部分由於涉及到的背景和算法比較多,因此會另外開一個 session 來分享。(視頻也能夠在YouTube上看了)

Proxy

針對 Cluster 的代理,這麼多年了,仍然有很多人在Cluster的接入方式上掙扎,由於缺乏合適的驅動而沒法使用Cluster。因此開發了這個Proxy功能。做者也強調,雖然這個Proxy 讓 Cluster 擁有了像單實例同樣的接入方式,可是本質上仍是 Cluster,不支持的命令仍是不會支持,好比跨 slot 的多Key操做。
其實社區早已有過很多 Proxy 方面的嘗試,並且有些作的還不錯。那麼這個官方的 Proxy 究竟會給咱們帶來什麼驚喜呢?仍是讓咱們拭目以待吧。

Disque

這個原本是做者幾年前開發的一個基於 Redis 的消息隊列工具,但多年來做者發現 Redis 在持續開發時,他也要持續把新的功能合併到這個Disque 項目裏面,這裏有大量無用的工做。所以此次他在 Redis 的基礎上經過 Modules 功能實現 Disque。

若是業務並不須要保持嚴格消息的順序,這個 Disque 能提供足夠簡單和快速的消息隊列功能。

總結

對我來講,這個版本能夠說有史以來變化最大的一次升級(若是不是最大也是之一了)。不論是從使用者,DBA,客戶端工具開發者,仍是運維的角度來看,都有了很多的變化。此次升級使得 Redis 從總體上更接近一個完整的數據庫(對比 MongoDB)。另外一方面,此次升級給全部相關的人員帶來了不少變化,恐怕後面要忙好一陣子了。

不知道你們看完 Redis 6 的新功能以後有什麼感想?限於篇幅,本文只是按做者重點分享的內容進行整理,其實每一項變化彷佛均可以新寫一篇文章來分享。若是有你感興趣的內容,也能夠留言一下,有機會下次我能夠分享。


更多資訊,歡迎關注公衆號:最簡實踐

相關文章
相關標籤/搜索