# 性能优化
- Redis 的 QPS 主要受网络延迟、CPU 频率影响。
- Redis 的读写速度很快,IO 压力小。因此没有必要读写分离,只是需要横向扩容。
# 内存
- 相关命令:
memory stats # 显示内存的统计信息,指标含义见 https://redis.io/commands/memory-stats/ memory usage <key> # 查询一个 key 及其 value 占用的内存体积,单位 bytes
- Redis 占用的内存主要受 key 影响。如果存在很多 key ,或 key、value 的长度大,则会占用很多内存。
- 如果 Redis 的内存开销大,可通过 shell 脚本统计所有 key 的 name、占用内存、ttl ,找到哪些 key 占用内存最多。
# 缓存
当 MySQL 等数据库的读操作远多于写操作时,可以用 Redis 作为读缓存。
- 当用户查询某个 Key 时,先到 Redis 缓存中查询,如果查询不到再到数据库查询。这样可以降低数据库的压力。
- 如果在数据库查询到了该 key 的值,则放入缓存,并设置几分钟的过期时间。
# 部署架构
- 本地缓存
- :将缓存服务器与客户端部署在同一主机,甚至集成在客户端进程中。
- 优点:响应速度很快,因为只需要读写内存,不需要等待网络 IO 。
- 缺点:单个主机的内存容量有限。
- 分布式缓存
- :在客户端主机之外的其它主机上,部署一个或多个缓存服务器。
- 优点:容易横向扩容。
- 缺点:响应速度较慢,因为需要等待网络 IO 。
- 多级缓存
- :将访问频率高的 key 存储在本地缓存中,其它 key 存储在分布式缓存中。
# 缓存穿透
- :有恶意请求不断地查询一些不存在的 key ,绕过缓存,直接冲向数据库。
- 解决方案:
- 即使查询到的值为空,也将该 key 放入缓存。
- 在查询缓存之前,先过滤掉明显不正常的查询请求。
# 缓存击穿
- :大量请求一直频繁地查询某个 key(称为热 key),当该 key 在某一时刻缓存过期时,这些请求会同时冲向数据库,造成数据库负载突增。
- 解决方案:
- 自动发现热 key ,并延长其过期时间。
# 缓存雪崩
- :在某一时刻,大量 key 同时缓存过期,导致大量请求同时冲向数据库。
- 缓存击穿是研究一个热 key ,而缓存雪崩是研究大量普通 key 。
- 解决方案:
- 给不同用途的各个 key 设置不同的缓存时长,给同一用途的各个 key 设置缓存时长时加上随机数,尽量分散所有 key 的缓存时间。
# redis-benchmark
:Redis 官方提供的性能测试工具, Redis 安装时自带。
命令:
redis-benchmark
-h 127.0.0.1 # redis 服务器的 IP 地址
-p 6379 # redis 服务器的端口号
-a ****** # 密码
-c 50 # 模拟连接的 client 数(默认 50 个)
-n 100000 # 模拟发出的请求数
-l # 循环测试,不停止
-d 3 # set、get 时的 value 大小(默认为 3 bytes)
-r 10000 # 使用随机的名字创建 key
-t set,get # 只执行某些测试用例(默认执行所有测试用例)
-P 10 # 使用管道,每次通信发送 10 条命令(默认每次只发送一条)
- 例:
redis-benchmark -h redis-1 -a ****** -t set,get
- 即使用 -a 选项指定的密码是错的,redis-benchmark 也依然可以运行,且不会报错。
- 当 -c 太少时,QPS 会比较小。当 QPS 达到瓶颈时,增加 -c 数,QPS 也不会增加。
- 测试时会在 Redis 服务器的 0 号数据库中创建几个 key ,比如
mylist
、key:__rand_int__
等。测试完之后不会删除。 - 使用 -r 10000 选项时,会用 10000 范围内的随机数给 key 命名,例如:
key:000000000912
、key:000000000882
。这样测试写入 3 次,虽然会有 key 重名,但总计能创建接近 10000 个 key ,每个 key 占用的内存由 -d 选项决定。