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 的新功能以后有什么感想?限于篇幅,本文只是按做者重点分享的内容进行整理,其实每一项变化彷佛均可以新写一篇文章来分享。若是有你感兴趣的内容,也能够留言一下,有机会下次我能够分享。


更多资讯,欢迎关注公众号:最简实践

相关文章
相关标签/搜索