四、redi性能测试、协议、事务

一、redis慢查询

慢查询的作用:通过慢查询分析,找到有问题的命令进行优化。

Redis slowlog是Redis用来记录查询执行时间的日志系统。

查询执行时间指的是不包括像客户端响应(talking)、发送回复等IO操作,而单单是执行一个查询命令所耗费的时间。

1、慢查询配置

  • 动态设置: config set slowlog-log-slower-than 10000 //10 毫秒
    使用 config set 完后,若想将配置持久化保存到 redis.conf,要执行 config rewrite
  • redis.conf 修改:找到 slowlog-log-slower-than 10000 ,修改保存即可。注意:slowlog-log-slower-than =0 记录所有命令, -1 命令都不记录
  • slow-max-len 存放的记录最大条数,
    比如设置的 slow-max-len=10,当有第 11 条慢查询命令插入时,队列的第一条命令 就会出列,第 11 条入列到慢查询队列中, 可以 config set 动态设置,也可以修改 redis.conf 完成配置

2、慢查询命令使用

  • slowlog get:获取队列里慢查询的命令
  • slowlog len :获取慢查询列表当前的长度
  • slowlog reset:对慢查询列表清理(重置) //再查 slowlog len 此时返回 0 清空;
  • 对于线上 slow-max-len 配置的建议:线上可加大 slow-max-len 的值,记录慢查询存长命令时 redis 会做截断,不会占用大量内存,线上可设置 1000 以上
  • 对于线上 slowlog-log-slower-than 配置的建议:默认为 10 毫秒,根据 redis 并发量来调整,对于高并发比建议为 1 毫秒
  • 慢查询是先进先出的队列,访问日志记录出列丢失,需定期执行 slowlog get,将结果存储到其它设备中(如 mysql)

3、慢查询优化

  • 尽量使用短的key,对于value有些也可精简,能使用int就int
  • 避免使用keys *,因为keys *, 这个命令是阻塞的,即操作执行期间,其它任何命令在你的实例中都无法执行。当redis中key数据量小时到无所谓,数据量大就很糟糕了。所以我们应该避免去使用这个命令。可以去使用SCAN,来代替
  • 我们应该尽可能的利用key有效期。过了有效期Redis就会自动为你清除!
    选择回收策略(maxmemory-policy),当Redis的实例空间被填满了之后,将会尝试回收一部分key。根据你的使用方式,强烈建议使用 volatile-lru(默认) 策略——前提是你对key已经设置了超时。但如果你运行的是一些类似于 cache 的东西,并且没有对 key 设置超时机制,可以考虑使用 allkeys-lru 回收机制,具体讲解查看 。maxmemory-samples 3 是说每次进行淘汰的时候 会随机抽取3个key 从里面淘汰最不经常使用的(默认选项)。
  • volatile-lru:只对设置了过期时间的key进行LRU(默认值)
  • allkeys-lru : 是从所有key里 删除 不经常使用的key
  • volatile-random:随机删除即将过期key
  • allkeys-random:随机删除
  • volatile-ttl : 删除即将过期的
  • noeviction : 永不过期,返回错误
  • 对数据量较大的进行分片,比如按时间进行分片等

二、redis构建后的性能测试

  1. redis-benchmark -h 192.168.42.111 -p 6379 -c 100 -n 10000 : 100个并发连接,10000个请求,检测服务器性能
  2. redis-benchmark -h 192.168.42.111 -p 6379 -q -d 100 :测试存取大小为100字节的数据包的性能
  3. redis-benchmark -h 192.168.42.111 -p 6379 -t set,get -n 100000 -q:只测试 set,lpush操作的性能
  4. redis-benchmark -h 192.168.42.111 -p 6379 -n 100000 -q script load “redis.call(‘set’,‘foo’,‘bar’)”:只测试某些数值存取的性能

三、mysql迁移到redis

  • 使用用户名和密码登陆连接数据库
  • 登陆成功后执行 order.sql 的 select 语句得到查询结果集 result
  • 使用密码登陆 Redis
  • Redis 登陆成功后, 使用 PIPE 管道将 result 导入 Redis.
mysql -utest -ptest stress --default-character-set=utf8 --skip-column-names --raw < order.sql | redis-cli -h 192.168.42.111 -p 6379 -a 12345678 --pipe
SELECT CONCAT(
 '*10\r\n',
   '$', LENGTH(redis_cmd), '\r\n', redis_cmd, '\r\n',
   '$', LENGTH(redis_key), '\r\n', redis_key, '\r\n',
   '$', LENGTH(hkey1),'\r\n',hkey1,'\r\n',
   '$', LENGTH(hval1),'\r\n',hval1,'\r\n',
   '$', LENGTH(hkey2),'\r\n',hkey2,'\r\n',
   '$', LENGTH(hval2),'\r\n',hval2,'\r\n',
   '$', LENGTH(hkey3),'\r\n',hkey3,'\r\n',
   '$', LENGTH(hval3),'\r\n',hval3,'\r\n',
   '$', LENGTH(hkey4),'\r\n',hkey4,'\r\n',
   '$', LENGTH(hval4),'\r\n',hval4,'\r'
)
FROM (
 SELECT
 'HSET' AS redis_cmd,
 CONCAT('order:info:',orderid) AS redis_key,
 'ordertime' AS hkey1, ordertime AS hval1,
 'ordermoney' AS hkey2, ordermoney AS hval2,
 'orderstatus' AS hkey3, orderstatus AS hval3,
 'version' AS hkey4, `version` AS hval4
 FROM `order`
) AS t

四、redis的批量操作(pipeline)

大多数情况下,我们都会通过请求-相应机制去操作 redis。只用这种模式的一般的步骤是,先获得 jedis 实例,然后通过 jedis 的 get/put 方法与 redis 交互。由于 redis 是单线程的, 下一次请求必须等待上一次请求执行完成后才能继续执行。然而使用 Pipeline 模式,客户端 可以一次性的发送多个命令,无需等待服务端返回。这样就大大的减少了网络往返时间,提 高了系统性能

  • 批量操作时使用如下代码网络开销非常大,每一次请求都会建立网络连接, 非常耗时, 特别是跨机房的场景下
    在这里插入图片描述
  • 使用 PIPELINE 可以解决网络开销的问题,代码如下,原理也非常简单,流程如下, 将多个指令打包后,一次性提交到 Redis, 网络通信只有一次
    在这里插入图片描述
    在这里插入图片描述

五、redis事务

刚大家知道,pipeline 是多条命令的组合,为了保证它的原子性,redis 提供了简单的事务,什么是事务?事务是指一组动作的执行,这一组动作要么成功,要么失败

  • A.redis的简单事务,将一组需要一起执行的命令放到multi和exec两个命令之间, 其中 multi 代表事务开始,exec 代表事务结束,
    注:在 multi 前 set user:age 4 //请提前初始化该值
    发现除了错误的指令外,其他指令还是执行成功了,所以说redis的事务是弱事务,不支持回滚操作
    在这里插入图片描述
  • B.取消事务
    discard之后,事务是不生效的
    在这里插入图片描述
  • C.命令错误,语法不正确,导致事务不能正常结束
    错误的指令会导致事务直接失效,其他正确的操作也不会被执行成功
    在这里插入图片描述
  • watch命令:使用watch后, multi失效,事务失效
    在这里插入图片描述

六、redis发布与订阅

redis 主要提供发布消息、订阅频道、取消订阅以及按照模式订阅和取消订阅

  • 发布消息:publish channel:test "hello world"
    在这里插入图片描述
  • 订阅消息
    subscrible channel:test
    此时另一个客户端发布一个消息:publish channel:test “james test” 当前订阅者客户端会收到如下消息
    在这里插入图片描述
  • 查看订阅数:pubsub numsub channel:test
  • 取消订阅:unsubscribe channel:test
  • 按模式订阅和取消订阅
    psubscribe ch* //订阅以 ch 开头的所有频道
    在这里插入图片描述
    punsubscribe ch* //取消以 ch 开头的所有频道
    在这里插入图片描述

七、键的迁移,key的遍历

1、键的迁移:把部分数据迁移到另一台 redis 服务器

  1. move key db //reids 有 16 个库, 编号为 0-15
    set name james1; move name 5 //迁移到第 6 个库
    select 5 ;//数据库切换到第 6 个库, get name 可以取到 james1 这种模式不建议在生产环境使用,在同一个 reids 里可以玩
  2. restore key ttl value//实现不同 redis 实例的键迁移,ttl=0 代表没有过期时间
    在 A 服务器上 192.168.42.111 set name james;
    dump name; // 得到"\x00\x05james\b\x001\x82;f"DhJ" 在 B 服务器上:192.168.1.118
    restore name 0 “\x00\x05james\b\x001\x82;f"DhJ”
    get name //返回 james
  3. migrate 用于在 Redis 实例间进行数据迁移,实际上 migrate 命令是将 dump、 restore、del 三个命令进行组合,从而简化了操作流程。
    migrate 命令具有原子性,从 Redis 3.0.6 版本后已经支持迁移多个键的功能。 migrate 命令的数据传输直接在源 Redis 和目标 Redis 上完成,目标 Redis 完成 restore 后会发送 OK 给源 Redis。

把 111 上的 name 键值迁移到 112 上的 redis
192.168.42.111:6379> migrate 192.168.42.112 6379 name 0 1000 copy

在这里插入图片描述

2、key的遍历

redis 提供了两个命令来遍历所有的键

键全量遍历

考虑到是单线程, 在生产环境不建议使用,如果键多可能会阻塞 如果键少,可以

  • keys * //返回所有的键, *匹配任意字符多个字符
  • keys *y //以结尾的键,
  • keys n*e //以 n 开头以 e 结尾,返回 name
  • keys n?me // ?问号代表只匹配一个字符 返回 name,全局匹配
  • keys n?m* //返回 name
  • keys [j,l]* //返回以 j l 开头的所有键 keys [j]ames 全量匹配 james
渐进式遍历

scan 0 match n* count 5
在这里插入图片描述

当最后返回 0 时,键被取完

两种遍历对比

scan 相比 keys 具备有以下特点:‘

1,通过游标分布进行的,不会阻塞线程。
2,提供 limit 参数,可以控制每次返回结果的最大条数,limit 不准,返回的
结果可多可少;
3,同 keys 一样,Scan 也提供模式匹配功能; 4,服务器不需要为游标保存状态,游标的唯一状态就是 scan 返回给客户端的
游标整数;
5,scan 返回的结果可能会有重复,需要客户端去重复;
6,scan 遍历的过程中如果有数据修改,改动后的数据能不能遍历到是不确定的; 7,单次返回的结果是空的并不意味着遍历结束,而要看返回的游标值是否为零;

 除 scan 字符串外:还有以下
 SCAN 命令用于迭代当前数据库中的数据库键。
 SSCAN 命令用于迭代集合键中的元素。
 HSCAN 命令用于迭代哈希键中的键值对。
 ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和分值)。 用法和 scan 一样

resp协议简单
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值