redis 是一个基于内存的开源数据存储系统,既然是基于内存,那么不可谓不快.

内存本来就是为了cpu能快速读取到数据而设计的嘛.

上个图

image.png

这个图不够准确哈,虽然是Aida64de benchmark.但是我开了很多软件和服务,跑的时候内存占用已经达到16个G了

第一行 Memory 就是内存相关的基准测试数据.

读取 51024MB/秒, 每秒可以读取近50个G,响应时间 68.6纳秒!!! 响应时间也就是说,68.6纳秒,就能准确的命中数据,给出想要的结果了.

相比普通硬盘,毫秒级的响应时间,不可谓不快.

image.png

这个是我的NVME 固态盘,机械盘响应时间还要慢.

机械盘8.3毫秒. 可见从内存里命中一条数据,比磁盘上命中一条是快了百倍

image.png.

这是某一时段,我的金士顿SSD固态的响应速度....

难道就此下结论

  • redis很快吗?
  • redis就一定快吗
  • redis在不同的环境下就一定可以快吗?

实践出真知

使用redis自带的基准测试,模拟50个客户端向局域网内的redis请求10万条 3字节的数据.

redis-benchmark.exe -h 192.168.3.21 -c 50

结果被截取了,不然太长了,截取到99%请求都响应了,剩下的1%舍弃了.

====== PING_INLINE ======
  100000 requests completed in 12.99 seconds 12.99秒10万请求完成
  50 parallel clients  --50并行客户端
  3 bytes payload  3字节负载
  keep alive: 1 

7.96% <= 1 milliseconds
24.64% <= 2 milliseconds
32.21% <= 3 milliseconds
41.42% <= 4 milliseconds
56.16% <= 5 milliseconds
70.02% <= 6 milliseconds
80.22% <= 7 milliseconds
83.89% <= 8 milliseconds
88.50% <= 9 milliseconds
93.95% <= 10 milliseconds
97.28% <= 11 milliseconds
99.65% <= 12 milliseconds
7700.01 requests per second

====== PING_BULK ======
  100000 requests completed in 13.96 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.37% <= 1 milliseconds
11.43% <= 2 milliseconds
25.74% <= 3 milliseconds
38.06% <= 4 milliseconds
53.93% <= 5 milliseconds
68.64% <= 6 milliseconds
78.01% <= 7 milliseconds
86.27% <= 8 milliseconds
92.55% <= 9 milliseconds
94.83% <= 10 milliseconds
99.56% <= 11 milliseconds
99.90% <= 15 milliseconds
7164.86 requests per second

====== SET ======
  100000 requests completed in 13.96 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.15% <= 1 milliseconds
14.14% <= 2 milliseconds
29.57% <= 3 milliseconds
43.32% <= 4 milliseconds
59.30% <= 5 milliseconds
72.35% <= 6 milliseconds
85.49% <= 7 milliseconds
96.92% <= 8 milliseconds
7161.78 requests per second

====== GET ======
  100000 requests completed in 14.59 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.48% <= 1 milliseconds
15.16% <= 2 milliseconds
30.32% <= 3 milliseconds
44.10% <= 4 milliseconds
58.19% <= 5 milliseconds
72.53% <= 6 milliseconds
86.59% <= 7 milliseconds
93.48% <= 8 milliseconds
99.13% <= 9 milliseconds
99.36% <= 10 milliseconds
6855.89 requests per second

====== INCR ======
  100000 requests completed in 14.04 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.18% <= 1 milliseconds
11.57% <= 2 milliseconds
30.22% <= 3 milliseconds
42.40% <= 4 milliseconds
56.65% <= 5 milliseconds
66.35% <= 6 milliseconds
76.44% <= 7 milliseconds
93.92% <= 8 milliseconds
98.35% <= 9 milliseconds
7124.54 requests per second


====== LRANGE_600 (first 600 elements) ======
  100000 requests completed in 48.45 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.00% <= 2 milliseconds
0.00% <= 3 milliseconds
0.01% <= 4 milliseconds
0.01% <= 5 milliseconds
0.02% <= 6 milliseconds
0.03% <= 7 milliseconds
0.03% <= 8 milliseconds
0.04% <= 9 milliseconds
0.05% <= 10 milliseconds
0.13% <= 11 milliseconds
0.47% <= 12 milliseconds
1.82% <= 13 milliseconds
5.16% <= 14 milliseconds
11.33% <= 15 milliseconds
17.60% <= 16 milliseconds
22.83% <= 17 milliseconds
27.77% <= 18 milliseconds
31.74% <= 19 milliseconds
35.32% <= 20 milliseconds
39.16% <= 21 milliseconds
44.86% <= 22 milliseconds
94.72% <= 23 milliseconds
97.87% <= 24 milliseconds
98.74% <= 25 milliseconds
99.24% <= 26 milliseconds
2063.86 requests per second

====== MSET (10 keys) ======
  100000 requests completed in 14.00 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

0.03% <= 1 milliseconds
13.21% <= 2 milliseconds
32.76% <= 3 milliseconds
43.76% <= 4 milliseconds
58.45% <= 5 milliseconds
75.08% <= 6 milliseconds
84.89% <= 7 milliseconds
94.41% <= 8 milliseconds
97.84% <= 9 milliseconds
99.13% <= 10 milliseconds
99.50% <= 11 milliseconds
99.56% <= 12 milliseconds
7141.84 requests per second

复制代码

大部分请求于10毫秒之内完成了, 但也有慢的,比如LRANGE_600 (first 600 elements)最终结果一度达到了300多毫秒(redis服务压力变大导致).

一个内存请求竟然用到了300毫秒.

那么redis,真的比MySQL还要快吗?

image.png

mysql 一条id查询用时14毫秒.

那么为什么?

虽然内存响应是纳秒级的,但是网络IO消耗了时间.

而网络IO主要延时由: 服务器响应延时 + 带宽限制 + 网络延时 + 跳转路由延时 + 本地接收延时 决定。(一般为几十到几千毫秒,受环境干扰极大)

所以纳秒级的redis在使用中依然是毫秒及,甚至达到了几十毫秒级.

mysql在一些索引查询中,速度不一定就比redis慢,刚才的一个id查询仅仅慢了几毫秒.

难道我们用redis的意义就在于快那么几毫秒吗?

答案一定是否定的.

  1. redis是nosql的.给我们的数据,带来了另一种存取可能.
  2. 让我们的数据,以另一种方式,快速的给到程序手中.
  3. 让我们的mysql和磁盘,得到喘息的机会.
  4. 有些mysql查询不是几十毫秒就能完成的,但redis查询响应速度不会相差太多.
  5. 对于频繁访问的内容,我不必重复的走以下的流程
    程序准备sql->jdbc pool 获取链接(无或核心链接满都需要创立)->建立网络IO发送sql命令->mysql收到请求,解析优化语句 -> mysql使用存储引擎查询数据->整理数据,使用网络IO响应查询内容.->一次请求结束
    复制代码
    我们可以将mysql一系列操作的成果,作为缓存放到内存中.减少CPU,硬盘,mysql使用的内存,网络带宽等等的服务器资源开销.

总结

redis快吗?

  • redis快,但redis不是万金油.什么都丢给redis不是不可以,但要知道同样容量的内存比硬盘的多了.
  • 存放的内容也要合适.这样才能充分的发挥出缓存的作用.
  • redis的使用环境要合适,要清楚redis也有网络IO限制了它的速度,

整理一下电脑硬件数据响应时间.

cpu 缓存 一级 零点几纳秒级
         二级 几纳秒级
         三级 十几纳秒级
         四级 几十纳秒级
    内存 几十纳秒级
    网卡 毫秒-秒级,受网络环境影响
    硬盘 毫秒级