前言
这是 面试 专栏的第二篇文章, 简单的从 Redis 的优缺点开始说了四个常见的面试题
讲一下 Redis 的优缺点
Redis 是 Key-Value 数据库也是内存数据库, 数据都存储在内存中, 和 Redis 一样的还有 Memcached 数据库, 都是定期的将数据刷新到硬盘中
Redis 的性能很高, 读的速度可以达到110000次/s,写的速度可以达到81000次/s, 单个 Key 和 Value 能存储最大 512MB 大小的数据, 这个在 官方文档 是有相关说明的, 但是通常建议 Key 的大小不超过 1kb
而 Memcached 的 Key 最长为 250字节, Value 最大存储数据为 1MB, 如果超过 1MB get/set 都是 false, 并且会引起性能问题
第一个红框: 建议 key 的大小不超过 1kb 第二个红框: key 最大能存储 512MB 的数据 复制代码
红框内容: value 最大能存储 512MB 的数据 复制代码
同时, Redis 相比如 Memcached 支持的数据结构更多, 有 set, string, zset, hash, list 五种, 且可以设置过期时间
Redis 的过期策略是: 定期删除和惰性删除, 定期删除是每隔 100ms 就随机抽取设置了过期时间的 key, 如果过期了就删除, 惰性删除是用到了这个 key 检测一下过期时间, 过期了就删除, Memcached 只有惰性删除
缺点: 因为 Redis 是内存数据库, 所以容量受到物理内存的限制, 如果是大量数据操作要进行优化, 升级 CPU 内存, 或者切片集群
你刚刚说到了内存, 为什么把数据放到内存中
普通数据库在操作的时候, 都是在硬盘内操作, 相对于内存来讲, 非常慢 , 所以放在了内存,
优点: 数据保存快, 缺点: 数据不能长久保存, 如果想数据库 IO操作 快的话, 就要把数据放入到内存中, 再把数据以异步的方式存到硬盘中, 所以, redis 就有了 快速操作 和 硬盘持久化 的特征
如果不把数据放入内存, IO操作就会很慢, 所以 redis 是比较依赖于内存的, 目前 内存越来越便宜, redis 的使用可能会更加常态化
如果 redis 设置了 内存使用数, 一旦记录数到了上线之后就写不进去了, 也是 redis的一个很大的问题
OK, 你有说 Redis 有 持久化 特征, 那么 Redis 的持久化是怎么实现的?
Redis 提供了两种持久化机制, 分别是 RDB 和 AOF:
- RDB 是把内存中的数据以快照的形式写入到磁盘中, 实际操作是通过
fork
子进程执行, 采用二进制压缩存储; 是对 Redis 中的数据执行 周期性 的持久化 - AOF 是写后日志, 是以文本日志的形式记录 Redis 处理的 每一个 写入或删除操作
标题 | RDB | AOF |
优点 | 每份数据文件都代表某一时刻 Redis 中的数据, 适合做冷备RDB 对 Redis 的性能影响小, 恢复速度快 | AOF 是一秒一次去通过后台线程 fsync 操作, 所以最多会丢失一秒的数据, 适合做 灾难性数据误删除 的紧急恢复 |
缺点 | RDB 都是快照文件, 默认五分钟或者更久生成一次, 会丢失数据, 在生成数据快照的时候, 如果文件很大, 客户端可能会停止几毫秒或者几秒 | 一样的数据 AOF 文件比 RDB 文件大, 开启 AOF 后, Redis 支持的 QPS 会有所下降 |
假如 redis 里面有 10亿个 key, 其中 十万个 key 是以某个前缀开头的, 怎么找出来
直接使用 keys
, 指定模式就可以了, 使用 keys 命令的时间复杂度为 O(N), N为数据库中拥有 keys
的个数, 需要注意的是, 如果是生产环境下进行大规模查询, 不能使用 keys
命令
因为 redis 是单线程的, 在大数据量的情况下, 使用 keys 会造成线程的阻塞, 线上服务的卡顿, 如果是在线上环境的话, 可以使用 scan
指令
可以无阻塞的去获取, 但是可能会有部分重复数据, 需要后续给他做个去重操作, 但是这个指令的执行时间要比 keys
长一些