Redis 6.0 新特性詳解


藝術致敬!
在這裏插入圖片描述

一、衆多新模塊(modules)API

  Redis 6中模塊API開發進展非常大,因爲Redis Labs爲了開發複雜的功能,從一開始就用上Redis模塊。Redis可以變成一個框架,利用Modules來構建不同系統,而不需要從頭開始寫然後還要BSD許可。Redis一開始就是一個向編寫各種系統開放的平臺。如:Disque作爲一個Redis Module使用足以展示Redis的模塊系統的強大。集羣消息總線API、屏蔽和回覆客戶端、計時器、模塊數據的AOF和RDB等。

二、更好的過期循環(expire cycle)

  Redis 6重新編寫了Redis活動到期週期,以更快地回收已到期的key。

三、支持SSL

  Redis 6連接支持SSL,更加安全。

四、ACLs 權限控制

  Redis 6開始支持ACL,該功能通過限制對命令和key的訪問來提高安全性。ACL的工作方式是在連接之後,要求客戶端進行身份驗證(用戶名和有效密碼);如果身份驗證階段成功,則連接與指定用戶關聯,並且該用戶具有限制。
  在默認配置中,Redis 6的工作方式與Redis的舊版本完全相同,每個新連接都能夠調用每個可能的命令並訪問每個鍵,因此ACL功能與舊版本向後兼容。客戶和應用程序。依舊使用requirepass配置密碼的,但現在只是爲默認用戶設置密碼。

4.1 ACL使用

 1) ACL <subcommand> arg arg ... arg. Subcommands are:
 2) LOAD                             -- Reload users from the ACL file.
 3) SAVE                             -- Save the current config to the ACL file.
 4) LIST                             -- Show user details in config file format.
 5) USERS                            -- List all the registered usernames.
 6) SETUSER <username> [attribs ...] -- Create or modify a user.
 7) GETUSER <username>               -- Get the user details.
 8) DELUSER <username> [...]         -- Delete a list of users.
 9) CAT                              -- List available categories.
10) CAT <category>                   -- List commands inside category.
11) GENPASS [<bits>]                 -- Generate a secure user password.
12) WHOAMI                           -- Return the current connection username.
13) LOG [<count> | RESET]            -- Show the ACL log entries.

  Redis6中auth命令在Redis 6中進行了擴展,因此現在可以在兩個參數的形式中使用它:

  #before Redis 6
  AUTH <password>
  #Redis 6
  AUTH <username> <password>

  默認情況下,有一個用戶定義,稱爲default。可以使用ACL LIST命令來查看,默認配置的Redis實例的配置是:

#無密碼
127.0.0.1:6379> ACL LIST
1) "user default on nopass ~* +@all"
#有密碼
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3
127.0.0.1:6379> ACL WHOAMI
"default"
127.0.0.1:6379> ACL USERS
1) "default"

  每行的開頭都是“ user”,後面跟用戶名,on表示用戶是啓用的,否則是禁用的。nopass表示無密碼,否則表示有密碼認證。(~*)表示能夠訪問所有的key,+ @ all表示能夠調用所有可能的命令。

4.2 ACL規則

啓用和禁止用戶

  • on:啓用用戶:可以以該用戶身份進行認證。
  • off:禁用用戶:不再可以與此用戶進行身份驗證,但是已經過身份驗證的連接仍然可以使用。如果默認用戶標記爲off,則無論默認用戶配置如何,新連接都將開始不進行身份驗證,並且要求用戶使用AUTH選項發送AUTH以進行身份驗證。

允許和禁止命令

  • +<command>:將命令添加到用戶可以調用的命令列表中。

  • -<command>:將命令從用戶可以調用的命令列表中刪除。

  • +@<category>:添加該類別中要由用戶調用的所有命令,有效類別爲@ admin,@ set,@ sortedset等,通過調用ACL CAT命令查看完整列表。特殊類別@all表示所有命令,包括當前在服務器中存在的命令,以及將來將通過模塊加載的命令。

127.0.0.1:6379> ACL CAT
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
  • -@<category>:從客戶端可以調用的命令列表中刪除命令。

  • +<command>|subcommand:允許使用本來禁用的命令的特定子命令。該語法不允許使用-<command>|subcommand,例如-DEBUG|SEGFAULT,只能以“ +”開頭的加法運算符。如果命令整體上已處於活動狀態,則此ACL將導致錯誤。

  • allcommands+ @ all的別名。

  • nocommands-@ all的別名。

允許或禁止訪問某些Key

  • <pattern>:添加可以在命令中提及的鍵模式。例如 allkeys 允許所有鍵。

  • resetkeys:使用當前模式覆蓋所有允許的模式。如: ~foo:* ~bar:* resetkeys ~objects:* ,客戶端只能訪問匹配 object:* 模式的 KEY。

爲用戶配置有效密碼

  • :將此密碼添加到用戶的有效密碼列表中。例如,>mypass將“mypass”添加到有效密碼列表中。該命令會清除用戶的nopass標記。每個用戶可以有任意數量的有效密碼。
  • <:從有效密碼列表中刪除此密碼。若該用戶的有效密碼列表中沒有此密碼則會返回錯誤信息。
  • :將此SHA-256哈希值添加到用戶的有效密碼列表中。該哈希值將與爲ACL用戶輸入的密碼的哈希值進行比較。允許用戶將哈希存儲在users.acl文件中,而不是存儲明文密碼。僅接受SHA-256哈希值,因爲密碼哈希必須爲64個字符且小寫的十六進制字符。
  • !:從有效密碼列表中刪除該哈希值。當不知道哈希值對應的明文是什麼時很有用。
  • nopass:移除該用戶已設置的所有密碼,並將該用戶標記爲nopass無密碼狀態:任何密碼都可以登錄。resetpass命令可以清除nopass這種狀態。
  • resetpass:情況該用戶的所有密碼列表。而且移除nopass狀態。resetpass之後用戶沒有關聯的密碼同時也無法使用無密碼登錄,因此resetpass之後必須添加密碼或改爲nopass狀態才能正常登錄。
  • reset:重置用戶狀態爲初始狀態。執行以下操作resetpass,resetkeys,off,-@all。

4.3 創建和編輯用戶

127.0.0.1:6379> ACL SETUSER zijie
OK
`SETUSER`命令採用用戶名和ACL規則列表以應用於用戶。但是在上面的示例中,沒有指定任何規則。如果用戶不存在,這將使用默認屬性來創建用戶。如果用戶已經存在,則上面的命令將不執行任何操作。
默認的用戶狀態:
127.0.0.1:6379> acl list
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"   

剛創建的用戶zijie是:

  • 處於禁用狀態,AUTH不起作用。
  • 無法訪問任何命令。
  • 無法訪問任何key。
  • 沒有設置密碼。
127.0.0.1:6379> ACL SETUSER zijie2 on >123 ~* +get
OK
127.0.0.1:6379> acl list
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~cached:* -@all +get"
127.0.0.1:6379> ACL SAVE
OK

  用戶可以執行某些操作,但是會拒絕執行其他操作,權限動態生效:

127.0.0.1:6379> auth zijie2 123
OK
127.0.0.1:6379> get name
"zijie"
127.0.0.1:6379> set name:2 a
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
#ACL LIST 查看用戶配置
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get"
#用戶名區分大小寫,ACL GETUSER 易讀性高於ACL LIST
127.0.0.1:6379> ACL GETUSER zijie2
1) "flags"
2) 1) "on"
2) "allkeys"
3) "passwords"
4) 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
5) "commands"
6) "-@all +get"
7) "keys"
8) 1) "*"
#使用RESP3易讀性更高
127.0.0.1:6379> ACL GETUSER zijie2
1# "flags" => 1~ "on"
2~ "allkeys"
2# "passwords" => 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
3# "commands" => "-@all +get"
4# "keys" => 1) "*"

  使用另一個ACL SETUSER命令向用戶添加多個模式:

127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +get
OK
127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +set
OK
127.0.0.1:6379> ACL SETUSER zijie3 on >123 ~zijie* +@read
OK
127.0.0.1:6379> ACL LIST
1) "user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all"
2) "user zijie off -@all"
3) "user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get"
4) "user zijie3 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~zijie* ~name* ~xx* -@all +@read +@hash +@bitmap +@geo -bitfield -hmset +set -geoadd -hincrby -hset -hincrbyfloat -georadiusbymember -hdel -hsetnx -bitop -georadius -setbit"
#刪除用戶
ACL DELUSER zijie3

4.4 命令類別

  ACL有類似"資源組“的概念,給一類命令一個別名,來達到快速授權。

127.0.0.1:6379> acl cat
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"
127.0.0.1:6379> acl cat dangerous
 1) "flushdb"
 2) "sort"
 3) "swapdb"
 4) "replicaof"
 5) "shutdown"
 6) "replconf"
 7) "keys"
 8) "lastsave"
 9) "psync"
10) "cluster"
11) "module"
12) "acl"
13) "bgrewriteaof"
14) "info"
15) "debug"
16) "bgsave"
17) "sync"
18) "flushall"
19) "save"
20) "pfdebug"
21) "latency"
22) "role"
23) "slaveof"
24) "migrate"
25) "pfselftest"
26) "config"
27) "monitor"
28) "restore"
29) "slowlog"
30) "restore-asking"
31) "client"
127.0.0.1:6379> ACL SETUSER zijie4 on +@all -@dangerous >123 ~*
OK
127.0.0.1:6379> ACL GETUSER zijie4
1) "flags"
2) 1) "on"
2) "allkeys"
3) "passwords"
4) 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
5) "commands"
6) "+@all -@admin -@dangerous"
7) "keys"
8) 1) "*"

授權子命令

ACL SETUSER zijie5 -client +client|setname +client|getname 

4.5 使用外部ACL文件

  Redis6因爲引入了權限機制,會有不同分工的用戶;所以又引入了額外的配置項以及配置文件,通過ACL LOAD/ACL SAVE報錯和加載acl文件。

[root@zijie ~]# cat /etc/Redis6.conf  | grep acl
aclfile /usr/local/Redis/users.acl
acllog-max-len 128
#Redis6開始密碼加密存儲
[root@zijie ~]# cat /usr/local/Redis/users.acl
user default on #ce306e0ee195cc817620c86d7b74126d0d66c077b66f66c10f1728cf34a214d3 ~* +@all
user zijie off -@all
user zijie2 on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~* -@all +get
user zijie3 off ~zijie* ~name* -@all
#獲取安全密碼
127.0.0.1:6379> ACL GENPASS
"c550b646ef8f7f91908628db0d983b4ca061fcf36433baa770ea9ce09da64ef4"

4.6 哨兵和副本的ACL規則

  如果不想爲Redis副本和Redis Sentinel實例提供對Redis實例的完全訪問權限,則以下是一組命令,爲了使一切正常工作,必須允許這些命令。
  對於Sentinel,允許用戶在主實例和副本實例中訪問以下命令:
  Sentinel不需要訪問數據庫中的任何密鑰,因此ACL規則如下(注意:不需要AUTH,因爲始終允許使用AUTH):

ACL setuser sentinel-user >somepassword +client +subscribe +publish +ping +info +multi +slaveof +config +client +exec on

  Redis副本需要在主實例上將以下命令列入白名單:

  • PSYNC,REPLCONF,PING

  不需要訪問任何密鑰,因此這轉化爲以下規則:

ACL setuser replica-user >somepassword +psync +replconf +ping on

  無需將副本配置爲允許主服務器能夠執行任何命令集:從副本的角度來看,主服務器始終被認證爲root用戶。

4.7 ACL LOG

  記錄拒絕的命令,密鑰訪問和身份驗證。

127.0.0.1:6379> acl log
 1)  1) "count"
     2) (integer) 1
     3) "reason"
     4) "auth"
     5) "context"
     6) "toplevel"
     7) "object"
     8) "auth"
     9) "username"
    10) "default"
    11) "age-seconds"
    12) "7.3860000000000001"
    13) "client-info"
    14) "id=18 addr=127.0.0.1:51882 fd=8 name= age=2 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=auth user=default"

五、RESP3 協議

  RESP(Redis Serialization Protocol)是 Redis 服務端與客戶端之間通信的協議。
  RESP3 是 RESP version 2 的更新版本。RESP v2 大致從 Redis 2.0 開始支持(其實 1.2 就支持了,只不過 Redis 2.0 是第一個僅支持此協議的版本)。

   127.0.0.1:6379> hello 2
   1) "server"
   2) "Redis"
   3) "version"
   4) "6.0.5"
   5) "proto"
   6) (integer) 2
   7) "id"
   8) (integer) 7
   9) "mode"
    10) "standalone"
    11) "role"
    12) "master"
    13) "modules"
    14) (empty array)
    127.0.0.1:6379> hello 3
    1# "server" => "Redis" // 服務名稱
    2# "version" => "6.0.5" // 版本號
    3# "proto" => (integer) 3 // 支持的最高協議
    4# "id" => (integer) 7 // 客戶端連接 ID
    5# "mode" => "standalone" //  模式:"standalone", "sentinel", "cluster"
    6# "role" => "master" //  "master" 或 "replica"
    7# "modules" => (empty array) // 加載的模塊列表

六、客戶端緩存(Client side caching)

  Redis 客戶端緩存在某些方面進行了重新設計,特別是放棄了緩存槽(caching slot)方法而只使用 key 的名稱。在分析了備選方案之後,在其他 Redis 核心團隊成員的幫助下,這種方法最終看起來更好。
  客戶端緩存重新設計中引入了廣播模式(broadcasting mode)。在使用廣播模式時,服務器不再嘗試記住每個客戶端請求的 key。 取而代之的是,客戶訂閱 key 的前綴:每次修改匹配前綴的 key 時,這些訂閱的客戶端都會收到通知。這意味着會產生更多的消息(僅適用於匹配的前綴),但服務器端無需進行任何內存操作。

七、多線程 IO(Threaded I/O)

  Redis 6 引入多線程IO,但多線程部分只是用來處理網絡數據的讀寫和協議解析,執行命令仍然是單線程。之所以這麼設計是不想因爲多線程而變得複雜,需要去控制 key、lua、事務,LPUSH/LPOP 等等的併發問題。

io-threads 4 # 開啓 4 個 IO 線程
io-threads-do-reads yes # 請求解析也是用 IO 線程

在這裏插入圖片描述
流程簡述如下:

1、主線程負責接收建立連接請求,獲取 socket 放入全局等待讀處理隊列
2、主線程處理完讀事件之後,通過 RR(Round Robin) 將這些連接分配給這些 IO 線程
3、主線程阻塞等待 IO 線程讀取 socket 完畢
4、主線程通過單線程的方式執行請求命令,請求數據讀取並解析完成,但並不執行
5、主線程阻塞等待 IO 線程將數據回寫 socket 完畢
6、解除綁定,清空等待隊列
在這裏插入圖片描述
該設計有如下特點:
1、IO 線程要麼同時在讀 socket,要麼同時在寫,不會同時讀或寫
2、IO 線程只負責讀寫 socket 解析命令,不負責命令處理

八、其餘特性

8.1 無盤複製&PSYNC2

  現在,Redis用於複製的 RDB 文件如果不再有用,將立即被刪除。不過,在某些環境中,最好不要將數據放在磁盤上,而只放在內存中。

repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled

  複製協議 PSYNC2 現在得到了改進。Redis 將能夠更頻繁地部分重新同步,因爲它能夠修整協議中的最終 PING,從而使副本和主副本更有可能找到一個公共的偏移量。

8.2 Redis-benchmark支持集羣

  從Redis6開始Redis-benchmark支持集羣。

8.3 Redis-cli 優化、重寫 Systemd 支持

8.4 Redis 集羣代理與 Redis 6 一同發佈(但在不同的 repo)

  在 Redis 集羣中,客戶端會非常分散,Redis6爲此引入了一個集羣代理,可以爲客戶端抽象 Redis 羣集,使其像正在與單個實例進行對話一樣。同時在簡單且客戶端僅使用簡單命令和功能時執行多路複用。

8.5 RDB更快加載

  Redis 6.0,RDB 文件的加載速度比之前變得更快了。根據文件的實際組成(較大或較小的值),大概可以獲得 20-30% 的改進。除此之外,INFO 也變得更快了,當有許多客戶端連接時,這會消耗很多時間,不過現在終於消失了。

8.6 SRANDMEMBER和類似的命令具有更好的分佈

8.7 STRALGO 命令

  STRALGO 實現了複雜的字符串算法。 目前唯一實現的是 LCS(最長的公共子序列)。

127.0.0.1:6379> STRALGO LCS keys name zijie
"1"
127.0.0.1:6379> STRALGO LCS keys name zijie  len
(integer) 1

8.8 帶有超時的 Redis 命令更易用

  除了 BLPOP 命令,其他用於接受秒的命令現在都接受十進制數字,而且實際分辨率也得到了改進,以使其永遠不會比當前的“HZ”值更差,因爲其不管連接客戶端的數量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章