1. 基础考点
1.1 什么是Redis?
Redis 本质上是一个 Key-Value 类型的内存数据库,很像 Memcached,整个数据库加载在内存当中操作,定期通过异步操作把数据库中的数据 flush 到硬盘上进行保存。
因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的 Key-Value 数据库。
优点:
- 读写性能极高
- 支持数据持久化,支持 AOF 和 RDB 两种持久化方式。
- 支持事务, Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
- 数据结构丰富
- 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
缺点:
- 数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上。
- 主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后还会引入数据不一致的问题,降低了系统的可用性。
1.2 Redis为什么这么快?
- 基于内存:由于数据存储在内存中,Redis能够快速执行各种操作,如读取、写入、计算和聚合等。内存的高速访问速度使得这些操作能够在毫秒级别完成。
- 单线程模型:Redis采用单线程模型,通过避免多线程之间的锁竞争和上下文切换,减少了系统开销。这使得Redis能够高效地处理并发请求。
- I/O多路复用:当有一个或多个I/O事件准备就绪时,I/O多路复用机制会通知Redis,然后Redis会根据事件类型进行相应的处理。例如,当有新的客户端连接时,Redis会接受连接并进行处理;当有数据可读时,Redis会读取数据并进行相应的操作;当可以写入数据时,Redis会将数据发送给客户端。
- 大大减少了系统资源的开销,使得Redis能够处理大量的并发连接
- 可以高效地响应事件并进行相应的处理,提高了系统的吞吐量和响应速度。
- 优化的数据结构:Redis 有诸多可以直接应用的优化数据结构的实现,应用层可以直接使用原生的数据结构提升性能。例如 简单动态字符串SDS、Hash、跳表等。
1.3 Redis 相比 Memcached 有哪些优势?
- 数据类型:Memcached 所有的值均是简单的字符串,Redis 支持更为丰富的数据类型
- 持久化:Redis 支持数据落地持久化存储,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。 memcache 不支持数据持久存储
- 性能对比:Redis 的速度比 Memcached 快很多。
- 集群模式:Redis 提供主从同步机制,以及 Cluster 集群部署能力,能够提供高可用服务。Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据
1.4 为什么用redis做缓存而不用map?
- Redis 可以用几十 G 内存来做缓存,Map 不行
- Redis 的缓存可以持久化,Map 是内存对象,程序一重启数据就没了;
- Redis 可以实现分布式的缓存,Map 只能存在创建它的程序里;
- Redis 可以处理每秒百万级的并发,是专业的缓存服务,Map 只是一个普通的对象;
- Redis 缓存有过期机制,Map 本身无此功能;Redis 有丰富的 API,Map 就简单太多了;
- Redis 可单独部署,多个项目之间可以共享,本地内存无法共享;
1.5 Redis的应用场景有哪些?
- 缓存:缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis 提供了键过期功能,也提供了灵活的键淘汰策略。
- 排行榜:很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis 提供的 有序集合zset 能实现各种复杂的排行榜应用。
比如,用户每天上传视频,获得点赞的排行榜可以这样设计:
- 用户Jay上传一个视频,获得6个赞: zadd user:ranking:2021-03-03 Jay 3
- 过了一段时间,再获得一个赞,可以这样: zincrby user:ranking:2021-03-03 Jay 1
- 如果某个用户John作弊,需要删除该用户: zrem user:ranking:2021-03-03 John
- 展示获取赞数最多的3个用户: zrevrangebyrank user:ranking:2021-03-03 0 2
- 计数器:什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览都得给 1,并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis 提供的 incr 命令来实现计数器功能,内存操作,性能非常好,非常适用于这些计数场景。
- 分布式锁:在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如全局 ID、减库存、秒杀等场景,并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利用 Redis 的 setnx 功能来编写分布式的锁,如果设置返回 1 说明获取锁成功,否则获取锁失败,实际应用中要考虑的细节要更多。
- 社交网络:点赞、踩、关注 / 被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且传统的关系数据库类型不适合存储这种类型的数据,Redis 提供的哈希、集合等数据结构能很方便的的实现这些功能。如在微博中的共同好友,通过 Redis 的 set 能够很方便得出。
- 消息系统:消息队列是大型网站必用中间件,如 ActiveMQ、RabbitMQ、Kafka 等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis 提供了发布 / 订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。
- 位操作:用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做? 千万别说给每个用户建立一个key,然后挨个记,你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。 这里要用到位操作——使用setbit、getbit、bitcount命令。 原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。
我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表