Redis 介绍
一、什么是Redis?
从官网复制下来的
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串
、哈希表
、列表
、集合
、有序集合
,位图
,hyperloglogs
等数据类型。内置复制、Lua脚本
、LRU收回、事务
以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区
二、Redis的核心特点
- 基于内存:基于内存存储,读写速度极快。单秒可处理数十万甚至百万级请求,适合高并发场景。
- 丰富的数据结构:支持字符串、哈希、列表、集合、有序集合、位图、超日志、地理空间等多种数据结构。
- 持久化:提供 RDB 和 AOF 两种持久化方式,可以将内存中的数据写入磁盘,防止数据丢失。
- 高可用:通过主从复制、哨兵(Sentinel)机制实现高可用,支持分布式部署。
- 丰富的功能:包括事务、Lua脚本、发布订阅、限流、统计等。
二、Redis的应用场景
场景类别 | 具体场景说明 |
---|---|
缓存系统 | 网站页面缓存、数据缓存、热点数据缓存 |
会话管理 | 用户登录会话信息存储、分布式会话管理 |
实时统计 | 游戏排行榜、积分排名、PV/UV统计、广告点击统计、实时分析 |
消息队列 | 任务调度、事件通知、异步处理 |
分布式锁 | PV/UV统计、广告点击统计、实时分析 |
地理空间信息处理 | 根据地理位置查找附近商户 |
限流和防刷 | 用户请求限制、反作弊、防刷机制 |
三、Redis的局限性
- 内存限制:数据量受服务器内存限制
- 单线程模型:虽然 6.0+ 支持多线程 I/O,但命令执行仍是单线程
- 持久化开销大:持久化操作可能影响性能
- 不支持复杂查询:不支持复杂的关系查询和 JOIN 操作
四、 Redis vs 其他数据库
特性 | Redis | MySQL | MongoDB | Memcached |
---|---|---|---|---|
数据存储 | 内存 + 持久化 | 磁盘 | 磁盘 | 内存 |
数据结构 | 丰富(8种+) | 行式存储 | 文档 | 键值对 |
性能 | 极高 | 中等 | 中等 | 极高 |
持久化 | 支持 | 支持 | 支持 | 不支持 |
集群 | 原生支持 | 需要配置 | 原生支持 | 需要客户端 |
事务 | 支持 | 支持 | 支持 | 不支持 |
五、相关面试题
Redis 为什么这么快?
Redis之所以如此快速,主要归功于其设计特点和工作原理:
- 基于内存存储:Redis的数据主要存储在RAM(随机存取存储器)中,对于内存存储,基本操作几乎是常数时间(O(1)),确保了极快的响应
- 高效的数据结构:
- 字符串(String):基本操作在常数时间内完成
- 哈希、列表、集合等数据结构都经过优化,支持快速的插入、删除和查找
- 单线程模型(事件驱动I/O):
- 单线程处理:Redis采用单线程架构,避免了多线程模型中的上下文切换和锁竞争问题
- I/O 多路复用技术:Redis采用epoll作为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了时间,不在I/O上浪费过多的时间
Redis 是单线程吗?
网上的资料大部分都是简单的说Redis 是单线程的,但这句话严格来说是不正确的。Redis 程序并不是单线程的,只是对于数据的操作是单线程处理的,Redis 在启动的时候,是会启动后台线程的,用于关闭文件、AOF刷盘等。
那为什么对于数据的操作要使用单线程呢
大家之前可能会有一个误区:就是多线程一定比单线程的速度快。
首先多线程的优势在于充分利用了多核CPU的资源,但对于单个CPU而言,多线程就意味着上下文切换以及锁竞争。
这个问题 官网上其实有回答,其中的核心点就是 Redis 的性能瓶颈不在 CPU,主要在内存和网络,并且单线程情况下不存在上下文切换、锁竞争等问题,实现起来更加简单,在单线程不影响效率并且可以避免并发问题的情况下,自然是要选在单线程了