1. SQL | NoSQL 之间的区别?
- 干货 | SQL 与 NoSQL还在傻傻分不清?
- MongoDB与 MySQL:什么时候使用?mongodb的数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存中,这样会提高查询效率,所以mongodb本身很吃内存
- redis和memcached的区别和使用场景。mc的核心职能是key-value键值对数据管理,value最大为1M,value只支持String类型,不支持复杂的数据结构(set,list,zset)。mc数据完全存储在内存中,不支持持久化到磁盘中
2. Redis 是单进程单线程的?
3. 一个字符串类型的值能存储的最大容量是多少?
- 主要考察字符串底层实现:SDS 结构,其中有一个字段记录了字符串的长度,int类型,因此理论上支持2^32-1字节,即4GB,但在Redis中,字符串类型的值除了存储数据外,还需要存储一些元数据信息(例如长度等),所以实际上字符串类型的值能存储的最大容量是512MB
- 简单动态字符串(SDS)
4. Redis 的持久化机制是什么?各自的优缺点?
5. Redis 常见性能问题和解决方案?
内存压力、热key、网络带宽不够等,解决方案:redis集群、持久化 | LRU 淘汰释放内存、主从复制读写分离。
6. Redis 过期键删除策略与内存淘汰策略?
7. 为什么 Redis 需要把所有数据放到内存中?
为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以Redis具有快速和数据持久化的特性。如果不将数据放到内存中,磁盘的I/O速度会严重影响redis的性能。在内存越来越便宜的今天,redis将会越来越受欢迎。
8. Redis 的主从同步机制?
9. Pipeline 有什么好处,为什么要用 pipeline?
redis 中 pipeline 有什么好处,为什么要用 pipeline?
10. Redis 集群的原理是什么?
11. Redis 集群方案什么情况下会导致整个集群不可用?
答案见上一问题。
12. Jedis 与 Redisson 对比有什么优缺点?
13. 说说 Redis 哈希槽的概念?
答案见第10问。
14. Redis 集群会有写操作丢失吗?为什么?
会,主从同步过程中如果发生故障,就可能产生数据丢失,详见:
15. Redis 集群最大节点个数是多少?
- 最大主节点数 16384 个。因为有16384个哈希槽
- redis作者不建议redis cluster节点数量超过1000个,集群节点越多,心跳包的消息体内携带的数据越多。 如果节点过1000个,会导致网络拥堵
- 一般Redis集群至少需要3个master节点,1个master至少对应2个slave
16. Redis集群如何选择数据库?
通常是用select命令的,但是在集群模式下是不起作用的,集群是不支持多数据库的,只能使用数据库0。至于为什么会有多个数据库可参考下文:为什么redis有多个数据库?
17. 怎么理解Redis事务?
- Redis系列(九):Redis的事务机制
- 没有一致性、原子性,只有隔离性(事务一旦开始运行,则不再运行其他客户端请求的命令),由于Redis支持数据持久化,因此也可以理解为拥有持久性吧
- Redis 中的原子操作:事务与 Lua 脚本
18. Redis中哪种数据结构基于跳表实现?跳表又是什么?
有序集合,关于跳表的实现:漫画:什么是跳表?
19. Redis中的rehash过程?什么是渐进式rehash?
20. 如何使用Redis实现分布式锁?实现过程中需要注意什么事情,以及锁失效场景都有哪些?
- 七种方案!探讨Redis分布式锁的正确使用姿势
- 设计分布式锁时,需要注意保证锁应该有持有人标记(可以设置到value上),否则可能被别的线程释放
- 需要保证锁有过期时间,否则可能在一些异常情况下,锁永远不会被释放,设置锁过期时间时,要保证其原子性,可以使用SET的扩展命令以及lua脚本(对于锁可能过期的问题,可以将锁的过期时间设置的长一点,或者采用Redisson的成熟方案(看门狗)去解决这个问题)
- 除了使用Redis的Set命令可以实现分布式锁,像MySQL的唯一索引,基于CAS+缓存的思想,都可以设计一个分布式锁
- Redis分布式锁失效场景分析
- 锁失效场景:锁超时时间过短,事务未执行完,就释放了锁;Redis主从切换,锁未同步slave,造成锁失效。
21. 如何设计一个秒杀系统?
- 基本的流程:下订单、扣库存、支付
- 最基本的架构:服务端 + DB(MySQL),MySQL单机TPS也就1w
- 高并发情况下必须保证不能超卖,考虑引入分布式锁(悲观锁),保证并发情况下商品数是正确的
- 考虑高性能:悲观锁优化为乐观锁(基于MySQL实现),还是直接操作DB,性能很差。考虑引入Redis,Redis单机支撑QPS 10w
- Redis如何实现高性能:请求量很大,但实际要做的库存扣减很少,典型的读多写少场景。考虑用Redis做限流,将大部分读请求由Redis承接,数据库承接真正的扣减库存请求即可。因此将库存扣减,以及判断库存是否足够的逻辑前移至Redis实现
- Redis在进行库存预减的时候,要保证Redis中的数据也不要发生超卖的场景,可用Redis请求队列 + decr或lua脚本实现
- 在Redis中预扣减成功后,在进行各种DB操作,包括创建订单记录,DB扣库存等,实际上就是一部分限流交由了Redis实现
- 除了高并发、高性能外,还要保障高可用,即不发生缓存击穿等情况,一旦发生缓存击穿,要注意不能将所有请求全落在数据库上,需要使用分布式锁保证一段时间内只有一个客户端访问数据库
- 还有就是订单少卖的问题,如果用户下单后超时未支付,那么需要对库存进行补充,有了订单记录后,虽然可以设计一个job对进行中的订单进行支付状态检测,但实时性不好,可以考虑引入mq的延迟队列,下单后即发送一个延迟消息,一定时间后对消息进行消费,判断订单是否已支付,若未支付则进行库存补充
- 其他的一些优化:前端的优化、防爬、负载均衡、熔断等,基本都是围绕过滤无用请求,降低并发度,提高服务可用性等方面进行的优化手段
22. 如何保证缓存和DB的数据一致性?
23. 一个对象存储在 Redis 中,选用 str 结构还是 hash 结构?
主要看使用场景:可以将整个对象序列化为 JSON 后存储为字符串,也可以将对象中的每个字段序列化后,用 HMSET 存储在哈希表中,两种方式各有优劣,一个是读取整个对象比较方便,一个是读取对象中的单个字段比较方便。
24. Redis 缓存击穿,穿透是什么?如何解决?
25. 大Key会带来什么问题,怎么解决?
26. Redis集群、主从架构,如何保证数据一致性?
这个问题再思考思考。