redis的使用-3
-
基数统计(HyperLogLog)
PFADD myredis1 'xiaowang' 'xiaozang' 'll' # 1、添加指定元素到 HyperLogLog 中。 PFCOUNT myredis1 # 2、返回给定 HyperLogLog 的基数估算值 PFMERGE myredis2 myredis myredis1 #3、将多个 HyperLogLog 合并为一个 HyperLogLog
-
发布订阅
SUBSCRIBE server server #1、订阅一个频道或多个频道 PUBLISH server 'hello' # 2、发布消息 PUBSUB CHANNELS # 3、查看订阅与发布系统状态。 UNSUBSCRIBE server # 4、退订一个或多个频道
-
事务
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
-
开始事务。
-
命令入队。
-
执行事务
**所以:**单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
###### 1、正常执行 127.0.0.1:6379[1]> MULTI # 开始事务 OK 127.0.0.1:6379[1]> SET k1 v1 # 命令入队列 QUEUED 127.0.0.1:6379[1]> SET k2 v2 # 命令入队列 QUEUED 127.0.0.1:6379[1]> GET k1 # 命令入队列 QUEUED 127.0.0.1:6379[1]> GET k2 # 命令入队列 QUEUED 127.0.0.1:6379[1]> EXEC # 执行事务 1) OK 2) OK 3) "v1" 4) "v2" ###### 2、取消事务 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> SET k1 v1 QUEUED 127.0.0.1:6379[1]> SET k2 v2 QUEUED 127.0.0.1:6379[1]> keys * QUEUED 127.0.0.1:6379[1]> DISCARD OK 127.0.0.1:6379[1]> EXEC (error) ERR EXEC without MULTI 127.0.0.1:6379[1]> keys * (empty array) ###### 3、事务错误 ################### 代码语法错误(编译时异常)所有的命令都不执行 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> SET k1 v1 QUEUED 127.0.0.1:6379[1]> SET k2 v2 QUEUED 127.0.0.1:6379[1]> keys * QUEUED 127.0.0.1:6379[1]> error k3 # 编译错误代码 (error) ERR unknown command `error`, with args beginning with: `k3`, 127.0.0.1:6379[1]> GET k1 QUEUED 127.0.0.1:6379[1]> EXEC (error) EXECABORT Transaction discarded because of previous errors. ################### 代码逻辑错误 (运行时异常) 其他命令可以正常执行,所以不保证事务原子性 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> set k1 v1 QUEUED 127.0.0.1:6379[1]> set k2 v2 QUEUED 127.0.0.1:6379[1]> INCR k1 # 逻辑错误代码,字符串无法自增 QUEUED 127.0.0.1:6379[1]> get k2 QUEUED 127.0.0.1:6379[1]> EXEC 1) OK 2) OK 3) (error) ERR value is not an integer or out of range 4) "v2" ######4、监控 watch(乐观锁) ###悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,当其他线程想要访问数据时,都需要阻塞挂起。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁、表锁,读锁,写锁等,都是在操作之前先上锁。 在Java中,synchronized的思想也是悲观锁。 ###乐观锁:【冲突检测和数据更新】 乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候回判断一下再次期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。 乐观锁策略:提交版本必须大于记录当前版本才能执行更新 ############正常执行 127.0.0.1:6379[1]> SET money 100 OK 127.0.0.1:6379[1]> SET use 0 OK 127.0.0.1:6379[1]> WATCH money OK 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> DECRBY money 20 QUEUED 127.0.0.1:6379[1]> INCRBY money 20 QUEUED 127.0.0.1:6379[1]> EXEC ############多线程去执行: #当事务未执行前,监视数据被修改时,之前那的事务执行会失败,此时要Unwatch放弃原来的锁,重新watch来监视最 #新数据,再去执行之前的队列(如JUC中的自旋锁) #注意:每次提交执行exec后都会自动释放锁,不管是否成功 #客户端-1 #客户端-2 127.0.0.1:6379[1]> SET money 100 127.0.0.1:6379[1]> SET money 300 OK OK 127.0.0.1:6379[1]> SET use 0 127.0.0.1:6379[1]> GET money OK "300" 127.0.0.1:6379[1]> WATCH money OK 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> DECRBY money 20 QUEUED 127.0.0.1:6379[1]> INCRBY money 20 QUEUED 127.0.0.1:6379[1]> EXEC (nil) 127.0.0.1:6379[1]> UNWATCH OK 127.0.0.1:6379[1]> WATCH money OK 127.0.0.1:6379[1]> MULTI OK 127.0.0.1:6379[1]> DECRBY money 20 QUEUED 127.0.0.1:6379[1]> INCRBY use 20 QUEUED 127.0.0.1:6379[1]> EXEC 1) (integer) 280 2) (integer) 20
-
安全
CONFIG get requirepass #1、查看是否设置密码 CONFIG set requirepass "runoob" # 2、设置登录密码 AUTH password # 3、认证密码进入redis