替你踩过Redis缓存的坑,奉上使用规范和监控方法( 二 )
继续跟进JedisConnection代码 , 当选择库大于1时 , 会有select db操作 。 如果一直使用0库是不需要额外执行切库命令的 。 知道了第一个切库select 1的地方 , 那么select 0是哪来的呢?
文章插图
其实客户端使用Redis也会是要释放链接的 , 只不过RedisTemplate已经帮我们自动释放了 , 让我们再回到一开始RedisTemplate执行execute(...)方法的地方 。
文章插图
下面还是RedisConnectionUtils.java , 执行链接关闭的代码 。
文章插图
按代码注释的意思 , 如果选择库编号不为0 , spring-data-redis框架每次都会执行重置select 0!
文章插图
笔者在vivo商城业务中 , 商品详情页接口经过上面的调优 , 性能提高了3倍多 。
进一步验证数据库切换至少影响性能3倍左右(视具体业务而定) 。
Rediscluster集群数据库 , 默认0库 , 无法选择其他数据库 , 也就避免了这个问题 。
5、当心时间复杂度o(n)Redis命令
Redis是单线程的 , 所以线程安全的 。
Redis使用非阻塞IO , 并且大部分命令的时间复杂度O(1) 。
使用高耗时的命令是非常危险的 , 会占用唯一的一个线程的大量处理时间 , 导致所有的请求都被拖慢 。
例如:获取所有set集合中的元素 smembers myset , 返回指定Hash中所有的member , 时间复杂度O(N) 。
缓存的Value集合变大 , 当高并接口请求时 , 会从Redis读取相关数据 , 每个请求读取的时间变长 , 不断的叠加 , 导致出现热点KEY情况 , Redis某个分片处于阻塞 , CPU使用率达到100% 。
6、缓存热key
在Redis中 , 访问频率高的key称为热点key , 当某一热点key的请求到Server主机时 , 由于请求量特别大 , 导致主机资源不足 , 甚至宕机 , 影响正常的服务 。
热key问题的产生 , 有如下两种原因:
- 用户消费的数据远大于生产的数据 , 比如热卖商品或秒杀商品、热点新闻、热点评论等 , 这些典型的读多写少的场景会产生热点问题;
- 请求分片集中 , 超过单Server的性能极限 , 比如 固定名称key , 哈希落入一台Server , 访问量极大的情况 , 超过Server极限时 , 就会导致热点Key问题的产生 。
- 凭借业务经验 , 进行预估哪些是热key;
- 客户端统计收集 , 本地统计或者上报;
- 如果服务端有代理层 , 可以在代理层进行收集上报 。
- Redis集群扩容:增加分片副本 , 均衡读流量;
- 进一步对热key进行散列 , 比如将一个key备份为key1,key2……keyN , 同样的数据N个备份 , N个备份分布到不同分片 , 访问时可随机访问N个备份中的一个 , 进一步分担读流量;
- 使用二级缓存 , 即本地缓存 。
五、Redis规范
1、禁止使用非database 0
说明:
【替你踩过Redis缓存的坑,奉上使用规范和监控方法】Redis-standalone架构 , 禁止使用Redis中的其他database 。
原由:
- 为以后业务迁移 Redis Cluster 保持兼容性;
- 多个 database 用 select 切换时 , 更消耗CPU资源;
- 更易自动化运维管理 , 如 scan/dbsize 命令只用于当database;
- 部分 Redis Clients 因线程安全问题 , 不支持单实例多 database 。
按业务功能命名key前缀 , 防止key冲突覆盖 , 推荐 用冒号分隔 , 例如 , 业务名:表名:id: , 如 live:rank:user:weekly:1:202003 。
Key的长度小于30个字符 , Key名字本身是String对象 , Redis硬编码限制最大长度512MB 。
在Redis缓存场景 , 推荐Key都设置TTL值 , 保证不使用的Key能被及时清理或淘汰 。
Key设计时禁止包含特殊字符 , 如空格、换行、单双引号以及其他转义字符 。
3、Value设计规范
单个Value大小必须控制10KB以内 , 单实例键个数过大 , 可能导致过期键的回收不及时 。
set、hash、list等复杂数据类型 , 要尽量降低数据结构中的元素个数 , 建议个数不要超过1000 。
4、关注命令时间复杂度
- 用户|自称百度旗下平台,收集用户信息,为资金盘倒流,这个坑你踩过吗?
- 3天时间,我是如何解决redis bigkey 删除问题的?
- Django实战016:django中使用redis详解
- 你不知道的Redis:入门?数据结构?常用指令?
- Python操作Redis大全
- 为什么 Redis 单线程能支撑高并发?
- Martian框架发布 3.0.3 版本,Redis分布式锁
- redis 数据类型详解 以及 redis适用场景场合
- Redis流行的原因
- Redis源码剖析之快速列表(quicklist)