1. 前言
最近在公司写代码,有一个工程由于担心 Redis 处理的数据量太大,存在性能问题,所以做了比较复杂的设计。但是我在想,Redis 的处理真的很耗时么?根据阿姆达尔定律,我们应该先发现耗时的点所在。目前接口的处理时长大概是100ms-200ms,为了找到最耗时的环节,我对 Redis 做了一下性能测试。
2. 实验
2.1 环境
- Docker Redis
- Redis Tool 自带的 benchmark 压力测试工具。
- Linux 命令:
top
,iftop
(网络流量top)
2.2 步骤
Redis 官方曾经宣布 Redis 的 QPS 可以达到 10W/s,并且性能瓶颈一般是网络层的带宽。
由此,我们设计实验验证一下这个观点。
- 本地压力测试
- 局域网压力测试
2.2.1 本机压力测试
- 我们在一个 Ubuntu 主机的 Docker 上安装 Redis,配置保持默认。
- 在 Terminal 上输入一下命令,默认50个并发客户端,一遍观察计算机的工况,一遍等待结束
root@ubuntu:~# redis-benchmark -p 6379
-
计算机工况: | 硬件 | 描述 | |------|------------| | CPU | us、sy 均上升,达到 97%+,由于Redis单线程,redis-server 进程不会突破100%| | 网络IO | 无流量 |
-
数据与简单结论(具体可以查看文章底部:附录) | 指标 | 描述 | |------|------------| | 时间复杂度为O(1) 的 QPS | 5W+,99%的请求在 1ms 内返回| | 时间复杂度O(n) 的 QPS (范围查询:range) | 8k-1.5W+,99%的请求在 4ms 内返回| |
2.2.2 局域网压力测试
- 我们在一个 Ubuntu 主机的 Docker 上安装 Redis,配置保持默认。
- 在局域网上,通过 Mac 向 Ubuntu 发送压力测试请求。局域网配置是普通家庭设置,路由器是 小米路由器4
- 在 Terminal 上输入一下命令,默认50个并发客户端,一遍观察计算机的工况,一遍等待结束
➜ ~ redis-benchmark -h home.qpm.com
- 计算机工况
硬件 | 描述 |
---|---|
CPU | 使用率稳定在 27%+ |
网络IO | 监控到流量,如上图 |
- 数据与简单结论(具体可以查看文章底部:附录) | 指标 | 描述 | |------|------------| | 时间复杂度为O(1) 的 QPS | 8k+,99%的请求在 40ms 内返回,网络流量Total峰值:10-12Mb| | 时间复杂度O(n) 的 QPS (范围查询:range) | 1k-3k,99%的请求在 180ms 内返回,最长时间为:1700ms| | 网络流量,在写入类 的 TPS| 服务器->客户端的约 3M/s | 网路流量,在 range 类 查询|服务器 -> 客户端的带宽表显示 40M/s, 但 Mac 显示只收到 9M/s
2.3 测试结论
如 Redis 官方所言,网络带宽通常是 Redis 的瓶颈
从上面的数据可知,在一个比较差的网络配置下,Redis 的性能是完全没发掘出来的。在网络拥塞情况下,Redis 的性能表现抖动还会比较明显。
2.4 心得
既然网络带宽会成为瓶颈,那在大量使用 Redis 请求的情况下,可以优先考虑 Pipeline 的交互方式。当一段代码中涉及 for 循环 + Redis,很容易就会成为系统最差的瓶颈,除非带宽已经赶上 CPU 的处理速度(这不太可能),否则 Pipeline 会非常有用地提供效率。
注意设计好使用 Redis 的数据结构,避免拉取过量的数据,或过度冗余地存储数据,这样也会消耗带宽,降低 Redis 中间件的服务性能