天天看点

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

一、多线程

redis 6.0 提供了多线程的支持,redis 6 以前的版本,严格来说也是多线程,只不过执行用户命令的请求时单线程模型,还有一些线程用来执行后台任务, 比如 unlink 删除 大key,rdb持久化等。

redis 6.0 提供了多线程的读写IO, 但是最终执行用户命令的线程依然是单线程的,这样,就没有多线程数据的竞争关系,依然很高效。

redis 6.0 以前线程执行模式,如下操作在一个线程中执行完成:

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

redis 6.0 线程执行模式:

可以通过如下参数配置多线程模型:

# 这里说 有三个IO 线程,还有一个线程是main线程,main线程负责IO读写和命令执行操作
io-threads 4  
           

默认情况下,如上配置,有三个IO线程, 这三个IO线程只会执行 IO中的write 操作,也就是说,read 和 命令执行 都由main线程执行。最后多线程将数据写回到客户端。

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

开启了如下参数:

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

总结: 最终执行命令的依然只有主线程。其他的IO线程可以帮忙解析命令,以及将结果写入到客户端中去而已!

二、客户端缓存 client side caching

redis 6 提供了服务端追踪key的变化,客户端缓存数据的特性,这需要客户端实现。

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

一些不变化的key,不需要从Redis中拿,第一次访问Redis后将其缓存到本地缓存,后面的请求直接从本地缓存获取。

如果其他客户端修改了数据,会将更新信息直接推动到客户端,通知过期。

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

执行流程为, 当客户端访问某个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();
        }
    }
}
           

三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

之前的的Redis授权功能没有用户和权限这些概念,虽然有密码认证,但是一旦用户登录进来后,有可能会执行flushdb等比较危险的操作。

所以Redis增建了ACL,可以对一些命令或者一些key进行特殊的权限管理。

查看所有的ACL

acl list
           

ACL使用

ACL设置有两种方式:

  1. 命令方式

    ACL SETUSER + 具体的权限规则, 通过 ACL SAVE 进行持久化## 命令方式

    1、创建一个 用户名为 alice的用户

用如上的命令创建的用户语义为:

  1. 处于 off 状态, 它是被禁用的,不能用auth进行认证
  2. 不能访问任何命令
  3. 不能访问任意的key
  4. 没有密码
  1. 对 ACL 配置文件进行编写,并且执行 ACL LOAD 进行加载
127.0.0.1:6380> acl list
1) "user default on nopass sanitize-payload ~* &* [email protected]"
2) "user test off &* [email protected]"
127.0.0.1:6380> 
           

ACL设置存储方式

ACL存储有两种方式,但是两种方式不能同时配置,否则直接报错退出进程

  1. redis 配置文件: redis.conf
    Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本
  2. ACL配置文件, 在redis.conf 中通过 aclfile /path 配置acl文件的路径

    如果我们有较多的用户且希望有一个单独的配置文件时,可以使用aclifile这种方式:

    Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本
    注意:配置文件redis.conf和users.acl这两种只能存在一种方式!

测试

1、我们新建一个文件夹acl,然后新建一个文件users.acl,然后将用户权限相关的配置拷贝到users.acl中

mkdir acl

cd acl

vim users.acl
           

然后将信息写入到配置文件中

user alice on #9847a022cf46bb779cdb7c316f52437935a9bb6b62bb4ee81a45cec18d4b8cb0 ~cached:* &* [email protected] +get
user default on nopass sanitize-payload ~* &* [email protected]
user test off &* -@all
           

2、首先修改redis中acl相关的配置文件路径:

aclfile /usr/local/redis/redis-6.2.3/acl/users.acl
``

3、将原来存在于redis.conf中的用户信息删除掉,两者只能存在一个;

4、加载配置:

```cpp
acl load
           

5、查看新的acl list:

127.0.0.1:6380> acl list
1) "user alice on #9847a022cf46bb779cdb7c316f52437935a9bb6b62bb4ee81a45cec18d4b8cb0 ~cached:* &* [email protected] +get"
2) "user default on nopass sanitize-payload ~* &* [email protected]"
3) "user test off &* [email protected]"
127.0.0.1:6380> 

           

如上用户alice 没有任何意义。

2、创建一个对 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权限:

针对类型命令的约束:

这里[email protected]: 包含所有得命令 然后用-@ 去除在redis command table 中定义的 dangerous 命令

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

可以通过如下命令进行查看具体有哪些命令属于某个类别:

acl cat // 查看所有类别
acl cat dangerous // 查看所有的 dangerous 命令
           
127.0.0.1:6380> 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:6380>
           
127.0.0.1:6380> acl cat dangerous
 1) "bgrewriteaof"
 2) "swapdb"
 3) "shutdown"
 4) "pfselftest"
 5) "sort"
 6) "migrate"
 7) "restore"
 8) "config"
 9) "client"
10) "slowlog"
11) "flushall"
12) "slaveof"
13) "debug"
14) "bgsave"
15) "psync"
16) "lastsave"
17) "cluster"
18) "flushdb"
19) "module"
20) "sync"
21) "pfdebug"
22) "keys"
23) "role"
24) "monitor"
25) "save"
26) "acl"
27) "replconf"
28) "info"
29) "restore-asking"
30) "replicaof"
31) "failover"
32) "latency"
127.0.0.1:6380> 
           

开放子命令:

ACL SETUSER myuser -client +client|setname +client|getnam
           

禁用client 命令,但是开放 client 命令中的子命令 setname 和 getname ,只能是先禁用,后追加子命令,因为后续可能会有新的命令增加。

持久化修改

注意,上面的acl配置目前只是在内存中,如果服务重启就会消失,如果要持久化,可以使用命令:

config rewrite
           

此时会将修改持久化到配置文件中,当然,我们也可以直接在配置文件redis.conf中配置。

Redis6 新特性一、多线程二、客户端缓存 client side caching三、ACL 是对于命令的访问和执行权限的控制,默认情况下,可以有执行任意的指令,兼容以前版本

继续阅读