golang redis获取所有key_maxRt——看看你的Redis有没有慢查询

温旭峰好文:

PHP7升级的性能提升

五个套路帮你搞定慢接口

PhpStorm使用技巧

Go Module 在项目中的应用

Go语言开发规范(更新)

自定义监控阿里云RDS - Prometheus使用Golang自定义Exporter

Golang HTTP服务平滑重启及升级

使用openresty打造接口校验服务

在整个系统的慢响应处理到低水位后,很多日常难以看到的点开始暴露出来,但原因难以查找。于是将系统内所有的应用指标进行了一次系统梳理,将告警阈值设置到日常水平稍高,一些新的线索浮现出来。

8cc116f75fd3c7096768c28733adcdeb.png

阿里云Redis Proxy上会统计Avg RT和Max RT(RT就是上面提到的从收到Request到给客户端回复Reponse的时间),Avg RT就是统计周期内所有Request的sum(RT) / Request数量,Max RT则是统计周期内RT最大的那个Request。

一般情况下,maxRt高的原因可以总结为以下几点:

  1. 耗时的操作,如 KEYS 

  2. bigkey

  3. cpu升高

在阿里云Redis后台慢请求可以看到如下的操作记录:

507593a283b55a863b69f4a6d44d8bfe.png

从上面可以看到主要是集中在 KEYS 操作、 DEL bigkey操作;关于 KEYS 操作通常情况下是可以构造出完整的key来避免,这篇文章,我们主要如何删除bigkey?

什么是bigkey?

bigkey是指key对应的value所占的内存比较大。按数据结构可分为以下两种情况:

  1. string类型:一般认为超过10KB就是bigkey

  2. 非string类型:hash、list、set、sort set都表现为元素过多

有什么危害?

  1. 内存分配不均衡:在redis集群中表现为键值个数接近的情况下,某个节点内存比其他节点内存占用高,这样不利于对集群内存的统一管理,存在丢失数据的风险

  2. 超时阻塞,导致MaxRt高:redis是单线程的,操作bigkey时通常都是比较耗时的,阻塞redis的可能性非常大,这样会造成客户端阻塞,单节点情况下会导致接口AvgRt升高,集群环境下可能引起故障切换

  3. 网络阻塞:bigkey在每次获取要产生更大的网络流量,假设一个bigkey为1MB,客户端每秒访问量为1000,那每秒要产生1000MB的流量

  4. 迁移困难:迁移时也可能会阻塞redis

  5. 过期删除:过期删除的bigkey不会再慢查询中出现,如果没有使用redis4.0的lazyfree,也会阻塞redis

如何产生?

一般来说,bigkey的产生都是由于设计不合理或对数据预估不足造成的,如:

  1. 统计类:如按天存储某个页面访问的用户集合

  2. 社交类:如明星、大v的粉丝列表

  3. 缓存类:如从数据库中load出来序列化放到redis中的

如何删除?

  1. string类型

string类型的数据,可以直接使用 DEL 操作删除

  1. 非string类型

如果仅有少量数据,可直接使用 DEL ,否则建议渐进式的方式操作:HSCAN、SSCAN、LTRIM、ZCSAN。如果使用的Redis4.0+,则可以开启lazyfree,一条异步删除 UNLINK 即可解决问题。

以HASH类型的删除为例:

<?php /** * 删除hash类型的key * @param XRedis $redis * @param string $key */function deleteHashKey(XRedis $redis, string $key): void {  if ($redis === null || empty($key)) {    return;  }    if ($redis->hLen($key) < 10) {    $redis->del($key);    return;  }    $iterator = null;  while ($data = $redis->hScan($key, $iterator)) {    foreach ($data as $k) {      $redis->hdel($key, $k);    }  }  $redis->del($key);}

LIST类型:Redis并没有提供 LSCAN 这样的API来遍历列表类型,但是提供了 LTRIM 这样的命令可以渐进式的删除列表元素,直到把列表删除。

SET类型:使用 SSCAN 命令,每次获取部分元素,再用 SREM 删除每个元素

SORTED SET类型:使用 ZSCAN 命令,每次获取部分元素,再用 ZREMRANGEBYRANK 删除元素


拖地先生,从事互联网技术工作,在这里每周两篇文章,聊聊日常的实践和心得。往期推荐:

说说这个公众号

平均响应1000ms到200ms,PHP和Go那家强?

崩溃率从1%到0.02%,iOS稳定性解决之道

七招优化Android包体减少30%

技术产品职业瓶颈?29份腾讯通道材料教你成长

低头赶路,也别忘了抬头看天

加班能解决交付的期望么?

8f29f79f70f20bd7a0cc45dfa33414ed.png

如果对你有帮助,让大家也看看呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值