Redis 常见面试题

Redis 常见面试题梳理:从基础概念到实战问题

Redis 面试题看起来很多,但核心其实很集中:Redis 为什么快、有哪些数据结构、怎样保证数据不丢、如何扩展容量和可用性,以及在缓存、分布式锁、消息队列等场景中会踩哪些坑。本文按照课件第十一章的顺序,把常见问题整理成一篇适合复习和发布的博客。

1. 什么是 Redis?它有什么特点?

Redis 是一个高性能的 key-value 内存数据库。它和 MySQL 这类关系型数据库不同,不使用"表"来组织数据,而是通过键值对来存储数据。Redis 的数据主要放在内存中,因此读写速度非常快;同时它也支持把数据持久化到磁盘,避免服务重启后数据完全丢失。

Redis 牺牲了关系型数据库中的复杂查询、强约束、复杂事务等能力,换来了简单、高效和灵活。它的主要特点包括:

  • 使用内存存储,读写性能高。
  • 支持多种数据结构。
  • 支持 RDB、AOF 等持久化机制。
  • 命令执行主要是单线程模型。
  • 支持主从复制。
  • 支持哨兵模式。
  • 支持集群模式。
  • 支持事务。
  • 支持多语言客户端。

面试回答时不必死背定义,可以围绕"内存数据库、key-value、多数据结构、高性能、可持久化、支持高可用和集群"这几个关键词展开。

2. Redis 支持哪些数据类型?

Redis 最核心的五种数据类型是:

  • String:字符串,最基础的数据类型。
  • List:列表,适合队列、栈等场景。
  • Hash:哈希,适合存储对象。
  • Set:集合,适合去重、共同好友、标签等场景。
  • ZSet:有序集合,适合排行榜、权重排序等场景。

后续版本还加入了一些特定场景的数据类型:

  • Bitmap:通过二进制位表示状态。
  • Bitfield:把字符串当作位图并进行位操作。
  • HyperLogLog:适合做基数统计,空间占用很小。
  • Geospatial:存储经纬度并进行地理位置计算。
  • Stream:消息流,常用于消息队列场景。

前五种类型通用性最强,面试中出现频率最高;后面的类型更偏专项能力,知道适用场景即可。

3. Redis 数据类型底层的编码方式是什么?

Redis 的每一种数据类型,底层都可能有多种编码方式。Redis 会根据数据规模和元素特征自动选择合适的内部编码。

常见对应关系如下:

数据类型 常见内部编码
string raw、int、embstr
hash hashtable、ziplist / listpack
list linkedlist / quicklist、ziplist
set hashtable、intset
zset skiplist、ziplist / listpack

几个重点概念:

  • embstr:短字符串的优化实现,课件中提到小于等于 39 字节时可能使用。
  • raw:普通字符串编码,适合较长字符串。
  • ziplist:压缩列表,本质是连续内存,节省空间,适合元素少且元素短的场景。
  • listpack:Redis 7 开始引入的新结构,用来替代 ziplist。
  • intset:整数集合,适合元素都是整数且数量较少的 set。
  • skiplist:跳表,常用于有序集合。
  • quicklist:由多个压缩列表组成的链表,是 list 的重要实现方式。

可以使用下面的命令查看某个 key 的实际编码:

bash 复制代码
object encoding key

4. ZSet 为什么使用跳表,而不是红黑树?

跳表和红黑树在插入、查询、删除上的时间复杂度都可以达到 O(logN),但跳表实现更简单,也不需要像红黑树那样进行复杂的旋转和重新平衡。

对于 Redis 来说,跳表足够高效,而且工程实现成本更低,所以 ZSet 选择跳表作为重要的底层结构。

5. Redis 的常见应用场景有哪些?

Redis 常见应用场景包括:

  • 缓存:缓存热点数据,减少数据库访问压力。
  • 计数器:统计播放量、点赞数、访问数等。
  • 排行榜:基于 ZSet 很容易实现分数排序。
  • 分布式会话:把 session 放到 Redis,多个服务节点共享。
  • 分布式锁:通过 Redis 控制分布式系统中的并发访问。
  • 消息队列:可以使用 List、Pub/Sub 或 Stream 实现简单消息队列。

这些场景都有一个共同点:要么需要高性能读写,要么需要 Redis 提供的特定数据结构能力。

6. 怎样测试 Redis 服务器的连通性?

使用 ping 命令即可:

bash 复制代码
redis-cli ping

如果 Redis 正常连通,会返回:

bash 复制代码
PONG

这是排查 Redis 服务是否启动、网络是否通畅、客户端是否能连接的最基本方式。

7. 如何设置 key 的过期时间?

有两种常见方式。

第一种是在 set 时直接指定:

bash 复制代码
set name zhangsan ex 60

表示 name 这个 key 60 秒后过期。

第二种是先设置 key,再单独使用 expire

bash 复制代码
set name zhangsan
expire name 60

如果需要查看剩余过期时间,可以使用:

bash 复制代码
ttl name

8. Redis 为什么采用单线程模型?

Redis 的性能瓶颈通常不在 CPU,而在内存和网络 IO。Redis 内部逻辑相对简单,如果为了命令执行引入多线程,收益不一定明显,反而会增加线程安全、锁竞争、上下文切换等复杂度。

Redis 使用单线程执行命令,可以让数据结构实现更简单,也能避免多线程并发带来的很多问题。

需要注意的是,Redis 6.0 之后引入了多线程 IO,但多线程主要用于网络数据读写和协议解析,真正执行 Redis 命令仍然主要是单线程完成。

9. Redis 里的 IO 多路复用是怎么回事?

IO 多路复用可以理解为:用一个线程同时管理多个 socket 连接,当某个连接真正有数据到来时,再通知线程去处理。

Linux 中常见的 IO 多路复用实现包括:

  • select
  • poll
  • epoll

Redis 主要基于 epoll 实现高效网络 IO。epoll 可以在内核中管理大量连接,并在连接有事件发生时通知用户线程处理。这样 Redis 不需要为每个客户端连接都创建一个线程,从而减少线程资源浪费。

这也是 Redis 单线程模型仍然能够支撑高并发的重要原因之一。

10. Redis 的持久化机制有哪些?

Redis 持久化主要有两种:

  • RDB:快照持久化,在某个时间点把内存数据生成快照文件。
  • AOF:追加日志持久化,把写命令追加到日志文件中。

RDB 文件更紧凑,适合备份和快速恢复;AOF 记录更细,数据丢失风险相对更低。实际生产中可以根据业务要求选择,也可以两者结合使用。

11. RDB 的持久化触发条件有哪些?

RDB 可以手动触发,也可以自动触发。

手动触发方式:

bash 复制代码
save
bgsave

其中 save 会阻塞 Redis 主线程,bgsave 会创建子进程生成 RDB 文件,主进程继续处理请求。

自动触发方式包括:

  • 在配置文件中通过 save m n 配置,例如 m 秒内发生 n 次修改就触发。
  • 从节点进行全量复制时触发。
  • 执行 shutdown 关闭 Redis 时触发。

12. AOF 的文件同步策略有哪些?

AOF 的同步策略主要有三种:

策略 含义
always 每次写入 AOF 缓冲区后都调用 fsync 同步到磁盘,最安全但性能最低
everysec 写入后先由操作系统缓存,每秒同步一次,性能和安全性较均衡
no 只写入操作系统缓存,由操作系统决定何时刷盘,性能最好但风险最大

生产中最常见的是 everysec,它通常能在性能和数据安全之间取得较好的平衡。

13. AOF 的重写机制是怎样的?

AOF 会不断追加写命令,文件会越来越大。AOF 重写的作用是:在不改变最终数据结果的前提下,用更少的命令重新描述当前数据集。

例如一个计数器执行了很多次 incr,AOF 中可能记录了大量命令;重写后可以变成一条最终的 set 命令。这样可以减小 AOF 文件体积,提高恢复速度。

14. Redis 的 key 过期删除策略是怎样的?

Redis 同时使用惰性删除和定期删除。

惰性删除是指:访问某个 key 时,Redis 才检查它是否过期,如果已经过期,就删除它。这种方式节省 CPU,但如果过期 key 长时间没人访问,可能会继续占用内存。

定期删除是指:Redis 周期性抽样检查设置了过期时间的 key,删除其中已经过期的 key。它在 CPU 和内存之间做了折中。

所以 Redis 不是一到过期时间就立刻删除所有 key,而是通过"访问时检查 + 定期抽样检查"的方式处理过期数据。

15. 大量 key 在同一时间过期会产生什么问题?如何处理?

如果大量 key 的过期时间设置得过于集中,到期时 Redis 需要删除大量 key,可能造成短暂卡顿。

Redis 的定期删除会限制单次删除的最大耗时,避免长时间阻塞,但在对延迟要求很高的业务中,即使几十毫秒的停顿也可能影响明显。

解决思路是:给过期时间增加随机值,让 key 的过期时间分散开。

例如原本都设置为 2 秒过期,可以调整为:

text 复制代码
2 秒 + 随机 0 到 500 毫秒

这样可以减少同一瞬间大量 key 同时过期的风险。

16. Redis 的淘汰策略是怎样的?

当 Redis 内存不足,并且继续写入新数据时,会根据配置的淘汰策略处理旧 key。

常见淘汰策略包括:

  • volatile-lru:从设置了过期时间的 key 中淘汰最近最少使用的 key。
  • allkeys-lru:从所有 key 中淘汰最近最少使用的 key。
  • volatile-lfu:从设置了过期时间的 key 中淘汰最近使用频率最低的 key。
  • allkeys-lfu:从所有 key 中淘汰最近使用频率最低的 key。
  • volatile-random:从设置了过期时间的 key 中随机淘汰。
  • allkeys-random:从所有 key 中随机淘汰。
  • volatile-ttl:从设置了过期时间的 key 中优先淘汰更早过期的 key。
  • noeviction:不淘汰,写入新数据时报错。

LRU 表示 Least Recently Used,即最近最少使用;LFU 表示 Least Frequently Used,即最近使用频率最低。

生产环境中,默认策略 noeviction 往往更容易暴露问题。因为 Redis 不应该等到内存完全耗尽才处理,应该依赖监控和告警提前扩容或优化。

17. Redis 如果内存用完了,会发生什么?

Redis 内存达到上限后,如果继续写入数据,会触发淘汰策略。具体结果取决于 maxmemory-policy 的配置:

  • 如果配置了 LRU、LFU、random、ttl 等策略,会删除一部分 key。
  • 如果是 noeviction,写请求会失败并返回错误。

因此生产环境一定要设置合理的内存上限,并配合监控系统观察内存使用趋势。

18. Redis 为什么把数据放到内存中?

核心原因是效率。内存访问速度远快于磁盘访问速度。

课件中给出的对比很直观:一次内存随机访问大约是 100ns,而一次磁盘寻道可能达到 10,000,000ns,差距是多个数量级。

把数据放到内存中,让 Redis 在读写性能上有明显优势。但内存也有缺点:

  • 空间比磁盘小。
  • 掉电后数据会丢失。

因此 Redis 一方面以内存为主保证性能,另一方面通过 RDB、AOF 做持久化,降低数据丢失风险。

19. Redis 的主从同步 / 主从复制是怎么回事?

主从复制用于解决两个问题:

  • 提高可用性,主节点故障时还有从节点保存数据副本。
  • 分担读压力,读多写少场景下可以让从节点承担部分读请求。

部署时,一个 Redis 节点作为主节点,其他节点作为从节点。从节点启动后通过配置指定主节点,然后复制主节点的数据。后续主节点数据发生变化,从节点也会同步更新。

一般情况下,主节点可以读写,从节点主要负责读。这样可以降低主节点压力。

20. Redis 的 pipeline 是什么?

正常情况下,客户端执行多条命令,每条命令都要经历一次请求和响应,也就是一次 RTT。命令数量多时,大量时间会消耗在网络往返上。

pipeline 可以把多条 Redis 命令合并到一次请求中发送给服务端,服务端依次执行后再统一返回结果,从而减少网络开销。

需要注意:pipeline 不是事务,不保证这批命令原子执行。它只是减少网络往返,提高批量命令执行效率。

如果一次 pipeline 中命令太多,也可能让 Redis 阻塞,所以要控制批量大小。

21. Redis 哨兵是什么?

哨兵 Sentinel 是 Redis 的高可用方案。它主要负责监控主从节点状态,并在主节点故障时自动完成故障转移。

哨兵的核心作用包括:

  • 监控 Redis 主节点和从节点是否正常。
  • 主节点故障时,从从节点中选举新的主节点。
  • 通知客户端新的主节点地址。
  • 让其他从节点切换复制新的主节点。

哨兵解决的是"主节点挂了之后需要人工切换"的问题。

22. Redis 哨兵发现主节点宕机后会做什么?

大致流程是:

  1. 哨兵通过心跳检测发现主节点疑似下线。
  2. 多个哨兵达成一致后确认主节点客观下线。
  3. 哨兵之间选举出一个 leader。
  4. leader 从从节点中选择一个合适的节点提升为新主节点。
  5. 让其他从节点改为复制新的主节点。
  6. 通知客户端主节点已经发生切换。

这个过程就是故障自动转移。

23. Redis 集群是干什么的?

主从复制和哨兵主要解决可用性问题,但不能真正扩展单个 Redis 主节点的存储容量。Redis 集群用于解决数据分片和水平扩展问题。

Redis Cluster 会把数据分散到多个主节点上,每个主节点负责一部分数据。这样可以突破单机内存上限,也可以分摊读写压力。

24. Redis 的哈希槽是怎么回事?

Redis Cluster 把整个数据空间划分为 16384 个哈希槽。每个 key 会根据哈希规则映射到某个槽,再由负责该槽的节点存储。

可以简单理解为:

text 复制代码
key -> hash -> slot -> node

通过哈希槽,Redis Cluster 能够把不同 key 分散到不同节点,实现数据分片。

25. Redis 集群的最大节点个数是多少?

课件中提到,作者建议集群节点数量不要超过 1000 个。节点数量过多会增加集群通信和维护成本,反而影响稳定性。

实际生产中也不会盲目堆节点,而是根据数据量、访问量、机器配置、运维复杂度综合设计集群规模。

26. Redis 集群会丢失操作吗?

Redis 集群不能保证强一致性,在某些极端情况下可能丢失写操作。

例如客户端写入某个 key 后,主节点还没来得及把数据同步给从节点,也没来得及写入 AOF,此时主节点宕机,新的主节点并没有这条数据,那么这次写入就可能丢失。

所以 Redis 更偏向高性能和最终一致性,不适合对强一致要求极高的核心交易场景。

27. Redis 集群如何选择数据库?

Redis 单机模式可以通过 select 命令选择不同数据库,例如 0、1、2 等。

但 Redis Cluster 不支持选择数据库,只能使用默认的 0 号数据库。

28. 什么是一致性哈希算法?

一致性哈希是一种常见的数据分片算法。它把节点和数据都映射到一个哈希环上,数据顺时针找到离自己最近的节点进行存储。

一致性哈希的优点是:当节点增加或减少时,不需要让所有数据重新分布,只会影响环上一小部分数据。

Redis Cluster 使用的是哈希槽机制,不是传统一致性哈希,但它们解决的问题类似,都是为了让数据能够分散到多个节点。

29. Redis 事务和 MySQL 事务有什么区别?

Redis 事务通过 MULTIEXEC 等命令,把一组命令打包执行。它更像是"批量顺序执行",而不是 MySQL 那种完整事务。

主要区别:

  • Redis 事务没有复杂的回滚机制。
  • Redis 事务不保证像 MySQL 那样的强原子性。
  • Redis 事务执行期间命令会按顺序执行。
  • 可以配合 WATCH 实现乐观锁效果。

所以 Redis 事务适合简单批量操作,不适合替代关系型数据库的复杂事务。

30. Redis 和事务相关的命令有哪些?

常见事务命令包括:

  • MULTI:开启事务。
  • EXEC:执行事务中的命令。
  • DISCARD:取消事务。
  • WATCH:监控 key,用于实现乐观锁。

31. 为什么生产环境不应该使用 keys *

keys * 会扫描 Redis 中所有 key,类似于数据库中的全表扫描。如果 key 数量很大,这个命令会耗时很长。

由于 Redis 命令执行主要是单线程的,一个耗时命令会阻塞后续命令,导致线上请求延迟升高,甚至造成故障。

生产环境中需要遍历 key 时,应优先使用 scan 渐进式遍历。

32. 如何使用 Redis 作为消息队列?

常见做法有三种。

第一种是使用 List。生产者通过 LPUSHRPUSH 写入消息,消费者通过 BLPOPBRPOP 阻塞式读取消息。

第二种是使用 Pub/Sub。发布者发送消息,订阅者接收消息,适合实时广播,但消息可靠性较弱。

第三种是使用 Stream。Stream 是 Redis 5 引入的数据类型,功能比 List 和 Pub/Sub 更完整,更适合消息流场景。

不过如果业务对消息可靠性、堆积、重试、消费组等要求很高,通常还是更建议使用专业 MQ。

33. 如何使用 Redis 实现分布式锁?

最基本思路是使用 set nx ex

bash 复制代码
set lock_key unique_value nx ex 10

含义是:只有 key 不存在时才设置成功,并且设置过期时间,避免业务异常导致锁永远不释放。

释放锁时要注意只能释放自己加的锁,所以 value 通常要设置为唯一标识,删除前先判断 value 是否匹配。实际项目中不建议手写复杂分布式锁,可以使用 Redisson 等成熟库。

34. 什么是缓存穿透、缓存雪崩、缓存击穿?

缓存穿透是指查询的数据在缓存和数据库中都不存在,请求每次都会打到数据库。常见解决方案是缓存空值、使用布隆过滤器。

缓存雪崩是指大量 key 在同一时间过期,或者 Redis 整体不可用,导致大量请求同时打到数据库。常见解决方案是过期时间加随机值、多级缓存、限流降级。

缓存击穿是指某个热点 key 过期,大量请求同时访问这个 key,瞬间打到数据库。常见解决方案是热点 key 永不过期、互斥锁重建缓存、逻辑过期。

这三个问题都和"缓存失效后流量打到数据库"有关,但触发原因不同。

35. 什么是热 key 问题?如何解决?

热 key 是指某个 key 的访问频率特别高,甚至单独一个 key 就能把某个 Redis 分片打满。

Redis Cluster 可以分散不同 key 的压力,但同一个 key 只能落到同一个分片上,所以热 key 很容易造成局部压力过大。

常见解决思路:

  • 扩大集群规模,尤其是增加热 key 所在分片的从节点。
  • 在应用层识别热 key,并进行二次哈希,把一个逻辑 key 拆成多个物理 key。
  • 将热 key 单独放到独立 Redis 集群中。
  • 使用应用本地缓存,减少访问 Redis 的次数。

36. 如何实现 Redis 高可用?

Redis 高可用通常依赖三类能力:

  • 主从复制:提供数据副本和读压力分摊。
  • 哨兵:监控主节点,故障时自动切换。
  • 集群:实现数据分片和水平扩展。

简单说,主从解决副本问题,哨兵解决自动故障转移问题,集群解决容量扩展问题。

37. Redis 和 MySQL 如何保证双写一致性?

双写一致性指的是:用户修改数据时,既要修改数据库,也要让缓存中的数据保持正确。

直接"更新数据库 + 更新 Redis"容易出现不一致,因为这两个操作不是原子的。更常见的做法是删除缓存,而不是直接更新缓存。

方案一是延时双删:

  1. 先删除缓存。
  2. 再更新数据库。
  3. 延迟一小段时间后再次删除缓存。

第二次删除是为了兜底,降低并发场景下出现脏数据的概率。

方案二是删除缓存失败后重试。比如删除失败时把 key 放入 MQ,后续不断重试删除。更工程化的做法可以结合 MySQL binlog,例如使用 Canal 监听数据库变更,再删除或更新缓存。

38. 生成 RDB 期间,Redis 是否可以处理写请求?

取决于触发 RDB 的方式。

如果使用 save,Redis 主线程会被阻塞,期间无法处理外部写请求。

如果使用 bgsave,Redis 会 fork 子进程生成 RDB 文件,父进程继续处理请求。因此 bgsave 期间 Redis 通常仍然可以处理写请求。

不过在 bgsave 之后新写入的数据,不一定会进入当前这份 RDB 文件,可能要等下一轮持久化。

39. Redis 的常用管理命令有哪些?

常见管理命令包括:

bash 复制代码
dbsize
info
monitor
shutdown
config get parameter
config set parameter value
debug object key
flushdb
flushall

其中:

  • dbsize:查看当前数据库 key 数量。
  • info:查看 Redis 状态和统计信息。
  • monitor:实时监听 Redis 收到的请求,生产环境谨慎使用。
  • shutdown:保存数据并关闭 Redis。
  • config get/set:查看或设置配置项。
  • flushdb:清空当前数据库,危险命令。
  • flushall:清空所有数据库,危险命令。

debug segfault 这类命令会制造服务崩溃,只能在测试环境理解用途,不能在生产环境随意执行。

40. Redis 使用的网络通信协议是什么?

Redis 客户端和服务端之间使用 Redis Serialization Protocol,通常简称 RESP。课件中写作 RSP,可以理解为同一个协议点。

RESP 是一种简单、高效、易解析的应用层协议,用于客户端和 Redis 服务端之间传输命令和响应。

41. Redis 如何遍历 key?

keys * 可以一次性获取所有 key,但会阻塞 Redis,不适合生产环境。

更推荐使用 scan

bash 复制代码
scan cursor [match pattern] [count count]

scan 是渐进式遍历,每次返回一部分 key,同时返回下一次遍历使用的游标。当游标返回 0 时,说明遍历结束。

示例:

bash 复制代码
scan 0 count 100

同类命令还有:

  • hscan:遍历 hash。
  • sscan:遍历 set。
  • zscan:遍历 zset。

需要注意,scan 遍历过程中如果 key 发生变化,可能出现重复或遗漏,所以业务上要能接受这种弱一致性。

42. Redis 如何实现"查找附近的人"?

可以使用 Geospatial 类型存储地理位置。

写入位置:

bash 复制代码
geoadd people 116.397128 39.916527 user1

查询附近成员:

bash 复制代码
georadius people 116.397128 39.916527 1 km

这样就可以查询某个经纬度附近一定范围内的成员。新版本中也可以使用 GEOSEARCH 等命令完成类似查询。

43. 什么是 Redis 的 bigkey 问题?如何解决?

bigkey 指某个 key 对应的 value 占用空间过大。例如:

  • 一个 String 存了特别大的文本或二进制内容。
  • 一个 Hash 中字段特别多。
  • 一个 Set 或 ZSet 中元素数量特别大。

bigkey 会带来几个问题:

  • 读写耗时增加。
  • 删除时可能阻塞 Redis。
  • 集群模式下容易造成数据倾斜。
  • 网络传输压力变大。

解决思路是拆分:把一个大 key 拆成多个小 key,每个 key 只保存一部分数据。

排查 bigkey 可以使用:

bash 复制代码
redis-cli --bigkeys

删除 bigkey 时不要直接使用 del,因为同步删除可能阻塞 Redis。更推荐使用:

bash 复制代码
unlink key

unlink 会异步释放内存,对 Redis 主线程影响更小。

总结

Redis 面试题虽然覆盖面广,但可以归纳为几条主线:

  • 基础能力:数据结构、内部编码、命令使用。
  • 性能来源:内存存储、单线程模型、IO 多路复用、pipeline。
  • 数据安全:RDB、AOF、过期删除、淘汰策略。
  • 高可用与扩展:主从复制、哨兵、集群、哈希槽。
  • 业务实践:缓存问题、分布式锁、消息队列、双写一致性、热 key、bigkey。

复习时不要只背结论,最好能围绕"为什么这么设计、解决了什么问题、又带来了什么代价"来理解。这样不管面试官从基础命令问起,还是追问线上故障处理,都能把答案串起来。

相关推荐
fengxin_rou1 小时前
【Outbox 事件驱动 + Canal Binlog 增量订阅】:用户关系模块架构实战详解
缓存·架构·canal·outbox
IpdataCloud1 小时前
IP查询工具怎么选?在线API vs IP离线库:精度、速度、成本、隐私全对比
服务器·网络·数据库
闪电悠米1 小时前
黑马点评短信登录01_session_sms_login
java·spring boot·redis·git·spring·面试
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
MySQL选择字符集和排序规则
数据库·mysql
旺仔Sec1 小时前
HBase 分布式集群部署实战:从解压到启动的完整指南
数据库·分布式·hbase
Gauss松鼠会1 小时前
GaussDB(DWS) 资源监控Topsql
java·网络·数据库·算法·oracle·性能优化·gaussdb
小碗羊肉1 小时前
【Redis | 第二篇】Jedis&SpringDataRedis
数据库·redis·缓存
郝学胜-神的一滴1 小时前
系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计
java·数据库·python·缓存·php·软件构建
米高梅狮子1 小时前
01.ELK企业日志分析系统
运维·服务器·网络·数据库·elk·oracle