【redis】redis压力测试工具-----redis-benchmark

摘自:https://www.cnblogs.com/lxs1314/p/8399069.html

redis做压测可以用自带的redis-benchmark工具,使用简单

压测命令:redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000

压测需要一段时间,因为它需要依次压测多个命令的结果,如:get、set、incr、lpush等等,所以我们需要耐心等待,如果只需要压测某个命令,如:get,那么可以在以上的命令后加一个参数-t(红色部分):

1、redis-benchmark -h 127.0.0.1 -p 6086 -c 50 -n 10000 -t get

 C:\Program Files\Redis>redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 -t get

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

99.53% <= 1 milliseconds
100.00% <= 1 milliseconds
62893.08 requests per second

例如上面一共执行了10000次get操作,在0.16 秒完成,每个请求数据量是3个字节,99.53%的命令执行时间小于1毫秒,Redis每秒可以处理62893.08次get请求。

2、redis-benchmark -h 127.0.0.1 -p 6086 -c 50 -n 10000 -t set

C:\Program Files\Redis>redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 -t set

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

87.76% <= 1 milliseconds
99.47% <= 2 milliseconds
99.51% <= 7 milliseconds
99.74% <= 8 milliseconds
100.00% <= 8 milliseconds
56179.77 requests per second

这样看起来数据很多,如果我们只想看最终的结果,可以带上参数-q,完整的命令如下:

(-q选项仅仅显示redis-benchmark的requests per second信息)

3、redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 -q

C:\Program Files\Redis>redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 -q
PING_INLINE: 63291.14 requests per second
PING_BULK: 62500.00 requests per second
SET: 49261.09 requests per second
GET: 47619.05 requests per second
INCR: 42194.09 requests per second
LPUSH: 61349.69 requests per second
RPUSH: 56818.18 requests per second
LPOP: 47619.05 requests per second
RPOP: 45045.04 requests per second
SADD: 46296.30 requests per second
SPOP: 59523.81 requests per second
LPUSH (needed to benchmark LRANGE): 56818.18 requests per second
LRANGE_100 (first 100 elements): 32362.46 requests per second
LRANGE_300 (first 300 elements): 13315.58 requests per second
LRANGE_500 (first 450 elements): 10438.41 requests per second
LRANGE_600 (first 600 elements): 8591.07 requests per second
MSET (10 keys): 55248.62 requests per second

 


测试命令事例:

1、redis-benchmark -h 192.168.1.201 -p 6379 -c 100 -n 100000 
100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性能 

2、redis-benchmark -h 192.168.1.201 -p 6379 -q -d 100  

测试存取大小为100字节的数据包的性能

3、redis-benchmark -t set,lpush -n 100000 -q

只测试某些操作的性能

4、redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"

只测试某些数值存取的性能

 

 

以下摘自:https://blog.youkuaiyun.com/yangcs2009/article/details/50781530

这个工具使用起来非常方便,同时你可以使用自己的基准测试工具, 不过开始基准测试时候,我们需要注意一些细节。

只运行一些测试用例的子集 -t

你不必每次都运行 redis-benchmark 默认的所有测试。 使用 -t 参数可以选择你需要运行的测试用例,比如下面的范例:

 

$ redis-benchmark -t set,lpush -n 100000 -q
SET: 74239.05 requests per second
LPUSH: 79239.30 requests per second

 

 

在上面的测试中,我们只运行了 SET 和 LPUSH 命令, 并且运行在安静模式中(使用 -q 参数)。也可以直接指定命令来直接运行,比如下面的范例:

 

$ redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"
script load redis.call('set','foo','bar'): 69881.20 requests per second

 

 

选择测试键的范围大小 -r

默认情况下面,基准测试使用单一的 key。在一个基于内存的数据库里, 单一 key 测试和真实情况下面不会有巨大变化。当然,使用一个大的 key 范围空间, 可以模拟现实情况下面的缓存不命中情况。

这时候我们可以使用 -r 命令。比如,假设我们想设置 10 万随机 key 连续 SET 100 万次,我们可以使用下列的命令:

 

$ redis-cli flushall
OK

$ redis-benchmark -t set -r 100000 -n 1000000
====== SET ======
  1000000 requests completed in 13.86 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

99.76% `<=` 1 milliseconds
99.98% `<=` 2 milliseconds
100.00% `<=` 3 milliseconds
100.00% `<=` 3 milliseconds
72144.87 requests per second

$ redis-cli dbsize
(integer) 99993

4.-r

在一个空的Redis上执行了redis-benchmark会发现只有3个键:

 
  1. 127.0.0.1:6379> dbsize  
  2. (integer) 3  
  3. 127.0.0.1:6379> keys *  
  4. 1) "counter:__rand_int__"  
  5. 2) "mylist"  
  6. 3) "key:__rand_int__" 

如果想向Redis插入更多的键,可以执行使用-r(random)选项,可以向Redis插入更多随机的键。

  1. $redis-benchmark -c 100 -n 20000 -r 10000 

-r选项会在key、counter键上加一个12位的后缀,-r 10000代表只对后四位做随机处理(-r不是随机数的个数)。例如上面操作后,key的数量和结果结构如下:

  1. 127.0.0.1:6379> dbsize  
  2. (integer) 18641  
  3. 127.0.0.1:6379> scan 0  
  4. 1) "14336"  
  5. 2)  1) "key:000000004580"  
  6.     2) "key:000000004519"  
  7.     …  
  8.    10) "key:000000002113" 

 

使用 pipelining -P

默认情况下,每个客户端都是在一个请求完成之后才发送下一个请求 (benchmark 会模拟 50 个客户端除非使用 -c 指定特别的数量), 这意味着服务器几乎是按顺序读取每个客户端的命令。Also RTT is payed as well.

真实世界会更复杂,Redis 支持 /topics/pipelining,使得可以一次性执行多条命令成为可能。 Redis pipelining 可以提高服务器的 TPS。下面这个案例是在 Macbook air 11上使用 pipelining 16 条命令的测试范例:

 

$ redis-benchmark -n 1000000 -t set,get -P 16 -q
SET: 403063.28 requests per second
GET: 508388.41 requests per second

 

记得在多条命令需要处理时候使用 pipelining。

5.-P

-P选项代表每个请求pipeline的数据量(默认为1)。

6.-k <boolean>

-k选项代表客户端是否使用keepalive,1为使用,0为不使用,默认值为1。

陷阱和错误的认识

第一点是显而易见的:基准测试的黄金准则是使用相同的标准。 用相同的任务量测试不同版本的 Redis,或者用相同的参数测试测试不同版本 Redis。 如果把 Redis 和其他工具测试,那就需要小心功能细节差异。

  • Redis 是一个服务器:所有的命令都包含网络或 IPC 消耗。这意味着和它和 SQLite, Berkeley DB, Tokyo/Kyoto Cabinet 等比较起来无意义, 因为大部分的消耗都在网络协议上面。
  • Redis 的大部分常用命令都有确认返回。有些数据存储系统则没有(比如 MongoDB 的写操作没有返回确认)。把 Redis 和其他单向调用命令存储系统比较意义不大。
  • 简单的循环操作 Redis 其实不是对 Redis 进行基准测试,而是测试你的网络(或者 IPC)延迟。想要真正测试 Redis,需要使用多个连接(比如 redis-benchmark), 或者使用 pipelining 来聚合多个命令,另外还可以采用多线程或多进程。
  • Redis 是一个内存数据库,同时提供一些可选的持久化功能。 如果你想和一个持久化服务器(MySQL, PostgreSQL 等等) 对比的话, 那你需要考虑启用 AOF 和适当的 fsync 策略。
  • Redis 是单线程服务。它并没有设计为多 CPU 进行优化。如果想要从多核获取好处, 那就考虑启用多个实例吧。将单实例 Redis 和多线程数据库对比是不公平的。

一个普遍的误解是 redis-benchmark 特意让基准测试看起来更好, 所表现出来的数据像是人造的,而不是真实产品下面的。

Redis-benchmark 程序可以简单快捷的对给定硬件条件下面的机器计算出性能参数。 但是,通常情况下面这并不是 Redis 服务器可以达到的最大吞吐量。 事实上,使用 pipelining 和更快的客户端(hiredis)可以达到更大的吞吐量。 redis-benchmark 默认情况下面仅仅使用并发来提高吞吐量(创建多条连接)。 它并没有使用 pipelining 或者其他并行技术(仅仅多条连接,而不是多线程)。

如果想使用 pipelining 模式来进行基准测试(了达到更高吞吐量),可以使用 -P 参数。这种方案的确可以提高性能,有很多使用 Redis 的应用在生产环境中这样做。

最后,基准测试需要使用相同的操作和数据来对比,如果这些不一样, 那么基准测试是无意义的。

比如,Redis 和 memcached 可以在单线程模式下面对比 GET/SET 操作。 两者都是内存数据库,协议也基本相同,甚至把多个请求合并为一条请求的方式也类似 (pipelining)。在使用相同数量的连接后,这个对比是很有意义的。

下面这个很不错例子是在 Redis(antirez)和 memcached(dormando)测试的。

antirez 1 - On Redis, Memcached, Speed, Benchmarks and The Toilet

dormando - Redis VS Memcached (slightly better bench)

antirez 2 - An update on the Memcached/Redis benchmark

你可以发现相同条件下面最终结果是两者差别不大。请注意最终测试时候, 两者都经过了充分优化。

最后,当特别高性能的服务器在基准测试时候(比如 Redis、memcached 这类), 很难让服务器性能充分发挥,通常情况下,客户端回事瓶颈限制而不是服务器端。 在这种情况下面,客户端(比如 benchmark 程序自身)需要优化,或者使用多实例, 从而能达到最大的吞吐量。

 

影响 Redis 性能的因素

有几个因素直接决定 Redis 的性能。它们能够改变基准测试的结果, 所以我们必须注意到它们。一般情况下,Redis 默认参数已经可以提供足够的性能, 不需要调优。

  • 网络带宽和延迟通常是最大短板。建议在基准测试之前使用 ping 来检查服务端到客户端的延迟。根据带宽,可以计算出最大吞吐量。 比如将 4 KB 的字符串塞入 Redis,吞吐量是 100000 q/s,那么实际需要 3.2 Gbits/s 的带宽,所以需要 10 GBits/s 网络连接, 1 Gbits/s 是不够的。 在很多线上服务中,Redis 吞吐会先被网络带宽限制住,而不是 CPU。 为了达到高吞吐量突破 TCP/IP 限制,最后采用 10 Gbits/s 的网卡, 或者多个 1 Gbits/s 网卡。
  • CPU 是另外一个重要的影响因素,由于是单线程模型,Redis 更喜欢大缓存快速 CPU, 而不是多核。这种场景下面,比较推荐 Intel CPU。AMD CPU 可能只有 Intel CPU 的一半性能(通过对 Nehalem EP/Westmere EP/Sandy 平台的对比)。 当其他条件相当时候,CPU 就成了 redis-benchmark 的限制因素。
  • 在小对象存取时候,内存速度和带宽看上去不是很重要,但是对大对象(> 10 KB), 它就变得重要起来。不过通常情况下面,倒不至于为了优化 Redis 而购买更高性能的内存模块。
  • Redis 在 VM 上会变慢。虚拟化对普通操作会有额外的消耗,Redis 对系统调用和网络终端不会有太多的 overhead。建议把 Redis 运行在物理机器上, 特别是当你很在意延迟时候。在最先进的虚拟化设备(VMWare)上面,redis-benchmark 的测试结果比物理机器上慢了一倍,很多 CPU 时间被消费在系统调用和中断上面。
  • 如果服务器和客户端都运行在同一个机器上面,那么 TCP/IP loopback 和 unix domain sockets 都可以使用。对 Linux 来说,使用 unix socket 可以比 TCP/IP loopback 快 50%。 默认 redis-benchmark 是使用 TCP/IP loopback。当大量使用 pipelining 时候,unix domain sockets 的优势就不那么明显了。
  • 当大量使用 pipelining 时候,unix domain sockets 的优势就不那么明显了。
  • 当使用网络连接时,并且以太网网数据包在 1500 bytes 以下时, 将多条命令包装成 pipelining 可以大大提高效率。事实上,处理 10 bytes,100 bytes, 1000 bytes 的请求时候,吞吐量是差不多的,详细可以见下图。

Data size impact

  • 在多核 CPU 服务器上面,Redis 的性能还依赖 NUMA 配置和 处理器绑定位置。 最明显的影响是 redis-benchmark 会随机使用 CPU 内核。为了获得精准的结果, 需要使用固定处理器工具(在 Linux 上可以使用 taskset 或 numactl)。 最有效的办法是将客户端和服务端分离到两个不同的 CPU 来高校使用三级缓存。 这里有一些使用 4 KB 数据 SET 的基准测试,针对三种 CPU(AMD Istanbul, Intel Nehalem EX, 和 Intel Westmere)使用不同的配置。请注意, 这不是针对 CPU 的测试。

NUMA chart

  • 在高配置下面,客户端的连接数也是一个重要的因素。得益于 epoll/kqueue, Redis 的事件循环具有相当可扩展性。Redis 已经在超过 60000 连接下面基准测试过, 仍然可以维持 50000 q/s。一条经验法则是,30000 的连接数只有 100 连接的一半吞吐量。 下面有一个关于连接数和吞吐量的测试。

connections chart

  • 在高配置下面,可以通过调优 NIC 来获得更高性能。最高性能在绑定 Rx/Tx 队列和 CPU 内核下面才能达到,还需要开启 RPS(网卡中断负载均衡)。更多信息可以在thread 。Jumbo frames 还可以在大对象使用时候获得更高性能。

  • 在不同平台下面,Redis 可以被编译成不同的内存分配方式(libc malloc, jemalloc, tcmalloc),他们在不同速度、连续和非连续片段下会有不一样的表现。 如果你不是自己编译的 Redis,可以使用 INFO 命令来检查内存分配方式。 请注意,大部分基准测试不会长时间运行来感知不同分配模式下面的差异, 只能通过生产环境下面的 Redis 实例来查看。

其他需要注意的点

任何基准测试的一个重要目标是获得可重现的结果,这样才能将此和其他测试进行对比。

  • 一个好的实践是尽可能在隔离的硬件上面测试。如果没法实现,那就需要检测 benchmark 没有受其他服务器活动影响。
  • 有些配置(桌面环境和笔记本,有些服务器也会)会使用可变的 CPU 分配策略。 这种策略可以在 OS 层面配置。有些 CPU 型号相对其他能更好的调整 CPU 负载。 为了达到可重现的测试结果,最好在做基准测试时候设定 CPU 到最高使用限制。
  • 一个重要因素是配置尽可能大内存,千万不要使用 SWAP。注意 32 位和 64 位 Redis 有不同的内存限制。
  • 如果你计划在基准测试时候使用 RDB 或 AOF,请注意不要让系统同时有其他 I/O 操作。 避免将 RDB 或 AOF 文件放到 NAS 或 NFS 共享或其他依赖网络的存储设备上面(比如 Amazon EC2 上 的 EBS)。
  • 将 Redis 日志级别设置到 warning 或者 notice。避免将日志放到远程文件系统。
  • 避免使用检测工具,它们会影响基准测试结果。使用 INFO 来查看服务器状态没问题, 但是使用 MONITOR 将大大影响测试准确度。

 

不同云主机和物理机器上的基准测试结果

  • 这些测试模拟了 50 客户端和 200w 请求。
  • 使用了 Redis 2.6.14。
  • 使用了 loopback 网卡。
  • key 的范围是 100 w。
  • 同时测试了 有 pipelining 和没有的情况(16 条命令使用 pipelining)。

Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (with pipelining)

 

$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q
SET: 552028.75 requests per second
GET: 707463.75 requests per second
LPUSH: 767459.75 requests per second
LPOP: 770119.38 requests per second

 

 

Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (without pipelining)

 

$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
SET: 122556.53 requests per second
GET: 123601.76 requests per second
LPUSH: 136752.14 requests per second
LPOP: 132424.03 requests per second

 

 

Linode 2048 instance (with pipelining)

 

$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q -P 16
SET: 195503.42 requests per second
GET: 250187.64 requests per second
LPUSH: 230547.55 requests per second
LPOP: 250815.16 requests per second

 

 

Linode 2048 instance (without pipelining)

 

$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
SET: 35001.75 requests per second
GET: 37481.26 requests per second
LPUSH: 36968.58 requests per second
LPOP: 35186.49 requests per second

 

 

更多使用 pipeline 的测试

 

$ redis-benchmark -n 100000

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

58.50% <= 0 milliseconds
99.17% <= 1 milliseconds
99.58% <= 2 milliseconds
99.85% <= 3 milliseconds
99.90% <= 6 milliseconds
100.00% <= 9 milliseconds
114293.71 requests per second

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

43.12% <= 0 milliseconds
96.82% <= 1 milliseconds
98.62% <= 2 milliseconds
100.00% <= 3 milliseconds
81234.77 requests per second

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

32.32% <= 0 milliseconds
96.67% <= 1 milliseconds
99.14% <= 2 milliseconds
99.83% <= 3 milliseconds
99.88% <= 4 milliseconds
99.89% <= 5 milliseconds
99.96% <= 9 milliseconds
100.00% <= 18 milliseconds
68458.59 requests per second

====== LPUSH ======
  100004 requests completed in 1.14 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

62.27% <= 0 milliseconds
99.74% <= 1 milliseconds
99.85% <= 2 milliseconds
99.86% <= 3 milliseconds
99.89% <= 5 milliseconds
99.93% <= 7 milliseconds
99.96% <= 9 milliseconds
100.00% <= 22 milliseconds
100.00% <= 208 milliseconds
88109.25 requests per second

====== LPOP ======
  100001 requests completed in 1.39 seconds
  50 parallel clients
  3 bytes payload
  keep alive: 1

54.83% <= 0 milliseconds
97.34% <= 1 milliseconds
99.95% <= 2 milliseconds
99.96% <= 3 milliseconds
99.96% <= 4 milliseconds
100.00% <= 9 milliseconds
100.00% <= 208 milliseconds
71994.96 requests per second

 

 

注意:包大小从 256 到 1024 或者 4096 bytes 不会改变结果的量级 (但是到 1024 bytes 后,GETs 操作会变慢)。同样的,50 到 256 客户端的测试结果相同。 10 个客户端时候,吞吐量会变小(译者按:总量到不了最大吞吐量)。

不同机器可以获的不一样的结果,下面是 Intel T5500 1.66 GHz 在 Linux 2.6 下面的结果:

 

$ ./redis-benchmark -q -n 100000
SET: 53684.38 requests per second
GET: 45497.73 requests per second
INCR: 39370.47 requests per second
LPUSH: 34803.41 requests per second
LPOP: 37367.20 requests per second

 

 

另外一个是 64 位 Xeon L5420 2.5 GHz 的结果:

 

$ ./redis-benchmark -q -n 100000
PING: 111731.84 requests per second
SET: 108114.59 requests per second
GET: 98717.67 requests per second
INCR: 95241.91 requests per second
LPUSH: 104712.05 requests per second
LPOP: 93722.59 requests per second

 

 

高性能硬件下面的基准测试

  • Redis 2.4.2
  • 默认连接数,数据包大小 256 bytes。
  • Linux 是 SLES10 SP3 2.6.16.60-0.54.5-smp,CPU 是 Intel X5670 @ 2.93 GHz.
  • 固定 CPU,但是使用不同 CPU 内核。

使用 unix domain socket:

 

$ numactl -C 6 ./redis-benchmark -q -n 100000 -s /tmp/redis.sock -d 256
PING (inline): 200803.22 requests per second
PING: 200803.22 requests per second
MSET (10 keys): 78064.01 requests per second
SET: 198412.69 requests per second
GET: 198019.80 requests per second
INCR: 200400.80 requests per second
LPUSH: 200000.00 requests per second
LPOP: 198019.80 requests per second
SADD: 203665.98 requests per second
SPOP: 200803.22 requests per second
LPUSH (again, in order to bench LRANGE): 200000.00 requests per second
LRANGE (first 100 elements): 42123.00 requests per second
LRANGE (first 300 elements): 15015.02 requests per second
LRANGE (first 450 elements): 10159.50 requests per second
LRANGE (first 600 elements): 7548.31 requests per second

 

 

使用 TCP loopback:

 

$ numactl -C 6 ./redis-benchmark -q -n 100000 -d 256
PING (inline): 145137.88 requests per second
PING: 144717.80 requests per second
MSET (10 keys): 65487.89 requests per second
SET: 142653.36 requests per second
GET: 142450.14 requests per second
INCR: 143061.52 requests per second
LPUSH: 144092.22 requests per second
LPOP: 142247.52 requests per second
SADD: 144717.80 requests per second
SPOP: 143678.17 requests per second
LPUSH (again, in order to bench LRANGE): 143061.52 requests per second
LRANGE (first 100 elements): 29577.05 requests per second
LRANGE (first 300 elements): 10431.88 requests per second
LRANGE (first 450 elements): 7010.66 requests per second
LRANGE (first 600 elements): 5296.61 requests per second

 

转自 http://www.redis.cn/topics/benchmarks.html

英文版 http://redis.io/topics/benchmarks

 

<think>好的,用户现在想了解Redis缓存相关的面试题。我之前已经帮他解答过抢红包系统设计的问题,现在需要转到Redis面试题上。首先,我需要考虑用户的需求是什么。可能他正在准备面试,特别是技术岗位,比如后端开发或者系统架构师,所以需要掌握常见的Redis面试问题及其答案。 用户可能对Redis的基础知识、高级特性、实际应用中的问题以及性能优化等方面感兴趣。接下来,我要整理常见的Redis面试题,并确保覆盖这些方面。需要分门别类,结构清晰,便于用户理解和记忆。 首先,基础部分应该包括数据结构、持久化机制、缓存问题如雪崩、穿透、击穿,以及单线程模型等。然后高级部分可能涉及集群模式、分布式锁、事务、内存淘汰策略等。应用场景和性能优化也是常见的考点,比如如何选择数据结构,如何优化大Key问题等。 同时,要注意结合之前的回答风格,使用清晰的标题和分点,适当使用公式和代码示例来增强专业性。例如,在解释缓存雪崩时,可以用公式说明过期时间的随机分布,或者用代码示例展示分布式锁的实现。 还要考虑用户可能的后续问题,比如如何解决某些具体问题,或者更深入的技术细节,所以在回答中需要提供足够的细节,但不过于冗长。此外,确保每个问题都有简明扼要的解答,方便用户快速复习。 最后,检查是否有遗漏的重要知识点,比如Redis的线程模型变化(6.0引入多线程IO),或者新特性如Stream数据类型,以及与其他缓存系统的比较等。确保内容全面且符合当前的技术趋势。</think>### Redis缓存面试核心知识点解析 --- #### 一、基础必考问题 1. **Redis为什么快?** - 内存操作:数据存储在内存中 - 单线程模型:避免上下文切换(6.0后引入多线程IO) - I/O多路复用:epoll/kqueue实现高效网络通信 - 高效数据结构:如跳表、压缩列表等 2. **5种基础数据结构** | 类型 | 特征 | 应用场景 | |------------|--------------------------------|--------------------| | String | 最大512MB | 计数器、分布式锁 | | Hash | 字段值映射 | 对象存储 | | List | 双向链表 | 消息队列、最新列表 | | Set | 无序唯一集合 | 共同关注、抽奖 | | ZSet | 带排序的Set | 排行榜、延迟队列 | 3. **缓存三大经典问题** - **缓存雪崩**: $$ \text{大量key同时过期} \rightarrow \text{数据库压力激增} $$ 解决方案:随机过期时间、永不过期+后台更新 - **缓存穿透**: $$ \text{查询不存在的数据} \rightarrow \text{绕过缓存直击DB} $$ 解决方案:布隆过滤器、空值缓存 - **缓存击穿**: $$ \text{热点key过期瞬间高并发请求} $$ 解决方案:互斥锁、逻辑过期时间 --- #### 二、高级特性考察 1. **持久化机制对比** | | RDB(快照) | AOF(日志) | |--------------|--------------------------------|---------------------------------| | 存储方式 | 二进制压缩文件 | 追加命令日志 | | 恢复速度 | 快 | 慢 | | 数据安全性 | 可能丢失最后一次快照后的数据 | 根据fsync策略决定(默认1秒) | | 文件体积 | 小 | 大 | 2. **Redis事务特性** ```bash > MULTI # 开启事务 > SET a 100 > INCR b > EXEC # 提交执行 ``` - 不保证原子性:单条命令失败不影响其他命令 - 没有回滚机制 3. **内存淘汰策略** | 策略 | 说明 | |---------------------|------------------------------| | volatile-lru | 从已设置过期时间的key中LRU淘汰| | allkeys-lru | 所有key中LRU淘汰 | | volatile-random | 随机淘汰有过期时间的key | | volatile-ttl | 淘汰剩余存活时间最短的key | --- #### 三、高频实战问题 1. **如何实现分布式锁?** ```lua -- 加锁脚本(原子操作) if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end ``` - 关键要素:原子性、超时机制、唯一标识、续期能力(看门狗) 2. **大Key优化方案** - 问题定义:Value > 10KB(String)或元素数量>1万(集合) - 解决方案: - 拆分:Hash分field存储 - 压缩:Gzip压缩后存储 - 清理:定期扫描删除 3. **集群模式对比** | 模式 | 特点 | 适用场景 | |--------------|------------------------------|------------------| | 主从复制 | 读写分离,数据冗余 | 中小规模系统 | | Sentinel | 自动故障转移 | 高可用需求 | | Cluster | 数据分片(16384 slots) | 大规模分布式系统 | --- #### 四、进阶场景分析 1. **缓存与数据库一致性** - 更新策略选择: ```mermaid graph LR A[更新操作] --> B{强一致性要求?} B -->|是| C[先更新DB再删缓存] B -->|否| D[延迟双删策略] ``` 2. **热点数据发现** - 监控工具Redis的hotkeys参数(需配置) - 代理层统计:在接入层记录请求频率 - 解决方案: - 本地缓存 - 多副本分布 - 限流保护 3. **管道(pipeline) vs 事务** | 特性 | Pipeline | 事务 | |------------|-------------------------------|--------------------| | 原子性 | 无 | 无 | | 执行方式 | 批量发送命令 | 命令队列 | | 网络消耗 | 减少RTT次数 | 正常消耗 | | 错误处理 | 中间命令失败不影响后续执行 | 语法错误导致全失败 | --- #### 五、性能优化技巧 1. **连接池配置**: ```java // Jedis配置示例 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(100); // 最大连接数 config.setMaxIdle(20); // 最大空闲连接 config.setMinIdle(5); // 最小空闲连接 ``` 2. **慢查询优化**: ```bash # 监控命令 slowlog get 10 # 获取最近10条慢查询 config set slowlog-log-slower-than 10000 # 设置阈值(单位:微秒) ``` 3. **内存优化方案**: - 使用Hash代替多个String - 启用内存碎片整理(`activedefrag yes`) - 选择合适的数据编码(如ziplist) --- #### 六、最新特性(Redis 7.0+) 1. **Function特性**: ```lua # 注册函数 redis.register_function('myfunc', function(keys, args) return redis.call('incr', keys[1]) end) ``` 2. **多线程改进**: - I/O线程处理网络读写(非命令执行) - 配置项:`io-threads 4` 3. **新数据类型**: - Stream:支持消费者组的消息队列 - JSON:原生支持JSON格式操作 --- #### 七、经典面试题示例 1. **为什么Redis选择单线程模型?** - 避免上下文切换开销 - 内存操作本身速度极快 - 瓶颈在网络IO而非CPU(6.0后针对网络IO多线程优化) 2. **如何保证集群扩容时的数据迁移安全?** - 使用`CLUSTER SETSLOT`命令逐步迁移 - 采用异步迁移+ask重定向机制 - 迁移完成后执行`CLUSTER SETSLOT... NODE`更新路由表 3. **Redis如何实现事务的ACID特性?** - 原子性:不支持回滚,单条命令失败不影响其他 - 一致性:通过错误检测保证 - 隔离性:单线程执行天然隔离 - 持久性:依赖AOF/RDB配置 --- **附:性能压测参考值** 使用`redis-benchmark`工具测试: ```bash redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000 ``` 典型结果: - SET操作:约10万QPS - GET操作:约12万QPS - 管道批量操作:可达50万QPS 建议结合业务场景设计分层缓存架构(本地缓存+Redis+数据库),实际项目中注意监控内存使用率、命中率、延迟等核心指标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值