一 慢查询分析
通过慢查询分析,可以扎到有问题命令,然后进行分析。一般而言都是设置一个阀值,当查询时间超过这个阀值,就会将这个语句或者命令记录下来。
而且需要注意的是,慢查询只是针对命令执行阶段,而不是针对发送命令,命令排队阶段。
1.1 慢查询的两个配置参数
slowlog-log-slower-than 10000 超过10毫秒就是慢查询
slowlog-max-len 128 慢查询日志长度,如果慢日志耗费的内存超过了128。当一个新的命令被写进日志的时候,最老的那个记录会被删掉。只要有足够的内存就行。你可以通过 SLOWLOG RESET 来释放内存。
线上可以设置成1000
slowlog len显示慢日志产长度
slowlog reset: 慢查询日志重置
1.2 最佳实践
# 线上可以设置slowlog-max-len成1000,并不会占用大量内存。
# 另外如果客户端出现请求超时,需要先检查该时间点是否有对应的慢查询
# 由于慢查询是一个先进先出的队列,所以慢查询比较多的情况下,可能会丢失部分部分慢查询命令,为了防止这种情况发生,可以定期执行slow get命令将慢查询日志持久化到其他存储中,然后可以制作可视化界面进行查询
二 Redis Shell
2.1 redis-cli
-h: 指定要连接的主机
-p: 端口
-r: 重复执行命令
-i: 指定时间间隔执行一次命令
-x: 标准输入读取数据作为redis-cli的最后一个参数
-c: 指定连接集群
-a: 指定密码
--scan | --pattern: 指定扫描key的模式
--slave: 把当前客户端模拟成Redis的从节点
--rdb: 请求redis生成RDB持久化文件,保存在本地
--binkeys: 使用scan命令对Redis的key进行采样,从中找到内存占用比较大的键值
--latency: 测试客户端到目标redis服务器的网络延迟
--latency-dist:以图表的形式从控制台输出统计信息
--stat实时获取Redis的重要统计信息
--raw 和 --no-raw: 是否以原始格式化结果返回
2.2 redis-server
--test-memory: 检测当前操作系统能否稳定的分配指定容量的内存给Redis,通过这种检测可以有效避免因为内存问题造成Redis崩溃
redis-server –test-memory 1024 检测操作系统能否提供1G内存给Redis
2.3 redis-benchmark
Redis性能测试工具。
-c: 代表客户端的并发数量,默认50
-n
redis-benchmark -c 100 -n 20000: 表示100个客户端同时请求redis,一共执行20000次
-q: 仅仅显示request per second信息
-r: 向redis插入更多随机的key
-P: 代表没一个请求pipeline的数据量
-k 1|0: 是否使用keepalive
-t: 对指定命令进行基准测试
redis-benchmark -t get,set -q
三 Pipeline
3.1 Pipeline概念
我们知道Redis客户端发送一条命令分为以下4个过程:
发送命令,命令排队,执行命令,返回结果
发送命令和返回结果的时间叫做Round Trip Time(往返时间),即RTT.
Redis提供了一些命令(比如mset和mget)可以减少RTT,但是不是所有的命令都支持批量操作。所以这类的命令N次请求就需要消耗N次RTT.
Pipeline就是可以将一组命令打包,然后传输到Redis服务端,服务器端执行完命令,再将结果返回给客户端,整个过程只需要一次RTT.
这样做的好处就是,客户端不用发送完一条命令,然后等待服务期结果,才能发送第二条。
3.2 原理
对于服务器端来说:能够处理一个客户端发起的TCP连接发送来的多个命令,然后拆包。而对于客户端就将多个命令缓存,缓冲区满了就发送。
3.2 Pipeline与原生的批处理命令的比较
# 原生批量命令时原子的;Pipeline是非原子的
# 原生批量命令,是一个命令对应多个key;Pipeline支出多个命令
# 原生批量命令时Redis服务端支持实现的,而Pipline需要服务端和客服端的共同实现
3.3 最佳实践
每一次Pipeline不能没有限制,否则一次组装命令过多,一方面会增加客户端等待时间,另一方面会造成一定网络阻塞,可以将一次包含大量命令的Pipeline拆分成多次较小的Pipeline完成。
四 事务
multi、exec、discard、watch是Redis事务相关的命令。事务可以一次执行多个命令,并且:
# 事务是一个单独的隔离操作:按顺序执行,不会被其他的客户端的发送来的请求打断
# 事务是一个原子操作:事务中的命令要么全部执行,要么全部不执行。
4.1 multi: 开启事务
multi执行之后,客户端可以继续向服务器发送任意条命令,这些命令不会立即被执行,而是放到一个队列中,等待EXEC执行的时候,队列中的命令才会被执行。
4.2 exec: 触发并执行事务中所有命令
执行完后,返回一个数组,数组组中的每一个元素都是执行队列命令产生的结果,而且顺序也和发送命令的顺序保持一致的。
# 事务在exec之前可能会出错,比如说,命令可能会产生语法错误,或者其他更严重的错误,比如内存不足
# 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。
对于发生在 EXEC 执行之前的错误,客户端以前的做法是检查命令入队所得的返回值:如果命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败。如果有命令在入队时失败,那么大部分客户端都会停止并取消这个事务。
不过,从 Redis 2.6.5 开始,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务。
4.3 discard: 清空事务队列
如果multi之后,exec之前,你调用了discard,那么队列里的命令就会被清空,放弃执行事务。
4.4 watch: 为事务提供check-and-set(CAS)行为
可以watch多个key,在EXEC之前,被监视的key如果至少有一个被修改了,那么整个事务就会被取消
4.5 为什么Redis不支持回滚
Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面,而这些错误是在编程的时候就该避免的。
192.168.1.201:6379> multi
OK
192.168.1.201:6379> keys *
QUEUED
192.168.1.201:6379> hset books "javacore" "Java In Action"
QUEUED
192.168.1.201:6379> hset books"spring" "spring cookbook"
QUEUED
192.168.1.201:6379> lpush animals pig hadoop tezhive
QUEUED
192.168.1.201:6379> exec
1) (empty list or set)
2) (integer) 1
3) (integer) 1
4) (integer) 4
五 发布和订阅
Redis提供就简单的基于发布/订阅模式的消息机制,消息发布者和消息消费者不直接通信,发布者向指定的频道发布消息,该订阅频道的每一个客户端都可以收到消息。
5.1 发布消息
publish channel message
publish channel:book "hadoop in action"
publish channel:fruit apple
5.2 订阅消息
subscribe channel [channel…..]
subscribe channel:book
subscribe channel:book channel:fruit
5.3 取消订阅
unsubscribe channel:book
5.4 按照模式订阅和取消订阅
psubscribe pattern [pattern…..]
punsubscribe pattern [pattern……]
psubscribe it*
punsubscribe it *
5.5 查询订阅
查询活跃的频道
pubsub channels
查看频道订阅数
pubsub numsub [channel…..]
通过模式订阅数
pubsub numpat channel