一:事务

Redis 的事务是通过 multi exec discard watch 这四个命令来完成的,单个命令是原子性的,所以事务指的是: 确保命令集合连续执行不被打断。  事务不支持回滚。
事务命令:
multi: 开启事务。 redis会将后续命令依次放入队列( EXEC,DISCARD,WATCH,MULTI 除外)
exec: 执行命令队列
discard: 取消事务,清除队列
watch: 监视key
unwatch: 取消监视
 
举例:
 

1)正常执行

 【redis-3】redis扩展功能

(2)放弃事务

【redis-3】redis扩展功能

(3)若在事务队列中存在命令性错误(类似于java编译性错误),则执行EXEC命令时,所有命令都不会执行

【redis-3】redis扩展功能

(4)若在事务队列中存在语法性错误(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常。

 【redis-3】redis扩展功能

(5)使用watch

案例一:使用watch检测balance,事务期间balance数据未变动,事务执行成功

【redis-3】redis扩展功能

案例二:使用watch检测balance,在开启事务后,开启新的客户端执行标注2中的操作,更改balance的值,模拟其他客户端在事务执行期间更改watch监控的数据,然后再执行标注1后命令,执行EXEC后,事务未成功执行。

【redis-3】redis扩展功能

【redis-3】redis扩展功能

一但执行 EXEC 开启事务的执行后,无论事务使用执行成功, WARCH 对变量的监控都将被取消。

故当事务执行失败后,需重新执行WATCH命令对变量进行监控,并开启新的事务进行操作。

二:慢查询日志

 1、redis.conf设置慢查询:

# 执行时间超过多少微秒的命令请求会被记录到日志上 0 : 全记录 <0 不记录
slowlog-log-slower-than 10000
#slowlog-max-len 存储慢查询日志条数
slowlog-max-len 128

 还可以用命令confifig set临时设置,重启后失效。

confifig set slowlog-log-slower-than 微秒
confifig set slowlog-max-len 条数

Redis使用列表存储慢查询日志,采用队列方式(FIFO),超过条数后,先存储的先丢失。

127 .0.0.1:6379> config set slowlog-log-slower-than 0
OK
127 .0.0.1:6379> config set slowlog-max-len 2
OK
127 .0.0.1:6379> set name:001 zhaoyun
OK
127 .0.0.1:6379> set name:002 zhangfei
OK
127 .0.0.1:6379> get name:002
"zhangfei"
查看日志: slowlog get
 
127 .0.0.1:6379> slowlog get
1 ) 1 ) (integer) 7 # 日志的唯一标识符 (uid)
    2 ) (integer) 1589774302 # 命令执行时的 UNIX 时间戳
    3 ) (integer) 65 # 命令执行的时长 ( 微秒 )
    4 ) 1 ) "get" # 执行命令及参数
        2 ) "name:002"
    5 ) "127.0.0.1:37277"
    6 ) ""
2 ) 1 ) (integer) 6
    2 ) (integer) 1589774281
    3 ) (integer) 7
    4 ) 1 ) "set"
        2 ) "name:002"
        3 ) "zhangfei"
    5 ) "127.0.0.1:37277"
    6 ) ""
 
# set get 都记录,第一条被移除了。
2、日志的保存 - redisServer中保存
 
struct redisServer {

long long slowlog_entry_id;   // 下一条慢查询日志的 ID

list *slowlog;  // 保存了所有慢查询日志的链表- FIFO

long long slowlog_log_slower_than;  // 服务器配置 slowlog-log-slower-than 选项的值

unsigned long slowlog_max_len;  // 服务器配置 slowlog-max-len 选项的值

};
slowlog中每一个节点 showlogEntry就是一条慢查询日志
typedef struct slowlogEntry {

long long id;  // 日志id

time_t time;  // 命令执行时的当前时间,格式为 UNIX 时间戳

long long duration// 执行命令消耗的时间,以微秒为单位

robj **argv// 命令与命令参数

int argc;  // 命令与命令参数的数量

} slowlogEntry ;
 
3、 慢查询日志清空:slowlog reset     查看日志数量:slowlog len
 
4、定位和处理:
使用 slowlog get 可以获得执行较慢的 redis 命令,针对该命令可以进行优化:

 

1 、尽量使用短的 key和 value ,能使用 int int
2 、避免使用 keys * hgetall等全量操作。
4 、将 rdb 改为 aof 模式

rdb fork 子进程 主进程阻塞 redis大幅下降,关闭持久化 (适合于数据量较小)改aof 命令式

5 、想要一次添加多条数据的时候可以使用管道
6 、尽可能地使用哈希存储
7 、尽量限制下 redis 使用的内存大小,这样可以避免 redis 使用 swap 分区或者出现 OOM 错误 ,内存与硬盘的swap
 
三: 监控器
 
客户端执行 monitor 命令可以将自己变为监控器,实时监控并打印出:其他客户端发送到服务器的请求命令。
Redis 客户端 1
127 .0.0.1:6379> monitor
OK
1589706136 .030138 [0 127 .0.0.1:42907] "COMMAND"
1589706145 .763523 [0 127 .0.0.1:42907] "set" "name:10" "zhaoyun"
1589706163 .756312 [0 127 .0.0.1:42907] "get" "name:10"
Redis 客户端 2
127 .0.0.1:6379>
127 .0.0.1:6379> set name:10 zhaoyun
OK
127 .0.0.1:6379> get name:10
"zhaoyun"
原理:
redisServer中维护了一个monitors链表,记录所有的监视器,每次收到monitor命令后,将该客户端追加到链表末尾。 当收到其他客户端的执行命令后,调用call函数发送给所有的monitor。
 
 
 
 
 
 
 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-01-11
  • 2021-07-16
  • 2022-12-23
  • 2021-10-25
  • 2021-12-28
  • 2021-11-07
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-09-24
  • 2021-02-02
  • 2021-09-08
  • 2021-05-07
  • 2021-09-30
相关资源
相似解决方案