马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
引言
尽管 redis 是一款非常优秀的 NoSQL 数据库,但更重要的是,作为使用者我们应该学会在不同的场景中如何更好的使用它,更大的发挥它的价值。主要可以从这四个方面进行优化:Redis键值设计、批处理优化、服务端优化、集群配置优化
1. Redis慢查询日志 使用
Redis 提供了慢日志 命令的统计功能,它记录了有哪些命令在执行时耗时比较久。
查看 Redis 慢日志 之前,你需要设置慢日志的阈值。例如,设置慢日志的阈值为 5 毫秒,并且保留最近 500 条慢日志记录:- # 命令执行耗时超过 5 毫秒,记录慢日志
- CONFIG SET slowlog-log-slower-than 5000
- # 只保留最近 500 条慢日志
- CONFIG SET slowlog-max-len 500
复制代码 设置完成之后,所有执行的命令如果操作耗时超过了 5 毫秒,都会被 Redis 记录下来。
此时,你可以执行以下命令,就可以查询到最近记录的慢日志:
- slowlog len:查询慢查询日志长度
- slowlog get [n]:读取n条慢查询日志
- slowlog reset:清空慢查询列表
- 127.0.0.1:6379> SLOWLOG get 5
- 1) 1) (integer) 12691 # 慢日志ID
- 2) (integer) 16027264377 # 执行时间戳
- 3) (integer) 6989 # 执行耗时(微秒)
- 4) 1) "LRANGE" # 具体执行的命令和参数
- 2) "goods_list:100"
- 3) "0"
- 4) "-1"
- 2) 1) (integer) 12692
- 2) (integer) 16028254247
- 3) (integer) 5454
- 4) 1) "GET"
- 2) "good_info:100"
-
复制代码 有可能会导致操作延迟的情况:
- 经常使用 O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合类命令,要花费更多的 CPU 资源
- 使用 O(N) 复杂度的命令,但 N 的值非常大,Redis 一次需要返回给客户端的数据过多,更多时间花费在数据协议的组装和网络传输过程中。
你可以使用以下方法优化你的业务:
<ul>尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做
执行 O(N) 命令,保证 N 尽量的小(推荐 N = maxLen) { System.out.printf("Found big key : %s, type: %s, length or size: %d %n", key, type, len); } } } while (!cursor.equals("0")); } @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } }}[/code]第三方工具
网络监控
- 自定义工具,监控
进出 Redis 的网络数据,超出预警值时主动告警
- 一般阿里云搭建的云服务器就有相关监控
页面

2.2.4 BigKey 解决方案
这里有两点可以优化:
- 业务应用尽量避免写入 bigkey
- 如果你使用的 Redis 是 4.0 以上版本,用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行,从而降低对 Redis 的影响
- 如果你使用的 Redis 是 6.0 以上版本,可以开启 lazy-free 机制(lazyfree-lazy-user-del = yes),在执行 DEL 命令时,释放内存也会放到后台线程中执行
bigkey 在很多场景下,都会产生性能问题。例如,bigkey 在分片集群模式下,对于数据的迁移也会有性能影响,以及我后面即将讲到的数据过期、数据淘汰、透明大页,都会受到 bigkey 的影响。因此,即使 reids6.0 以后,仍然不建议使用 BigKey
2.3 总结
- Key 的最佳实践
- 固定格式:[业务名]:[数据名]:[id]
- 足够简短:不超过 44 字节
- 不包含特殊字符
- Value 的最佳实践:
- 合理的拆分数据,拒绝 BigKey
- 选择合适数据结构
- Hash 结构的 entry 数量不要超过 1000
- 设置合理的超时时间
3. 批处理优化
3.1 Pipeline
3.1.1 客户端与服务端交互
单个命令的执行流程

N 条命令的执行流程

redis 处理指令是很快的,主要花费的时候在于网络传输。于是乎很容易想到将多条指令批量的传输给 redis

3.1.2 MSet
Redis 提供了很多 Mxxx 这样的命令,可以实现批量插入数据,例如:
利用 mset 批量插入 10 万条数据
[code]@Testvoid testMxx() { String[] arr = new String[2000]; int j; long b = System.currentTimeMillis(); for (int i = 1; i |