Redis是什么
Redis 是由C语⾔编写的⼀个远程内存数据库 ,它不仅性能强劲,⽽且还具有复制特
性以及为解决问题⽽⽣的独⼀⽆⼆的数据模型。
Redis是完全开源免费的,遵守 BSD 协议,是⼀个⾼性能的 key-value 数据库,并提供
多种语⾔的 API。
Redis的特点
- 性能极⾼ -- Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 -- Redis⽀持⼆进制的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原⼦ -- Redis的所有操作都是原⼦性的,同时Redis还⽀持对⼏个操作全部的原⼦ 性执⾏。
- 丰富的特性 -- Redis还⽀持 publish/subscribe, 通知, key 过期等等特性。
- ⾼速读写-Redis使⽤⾃⼰实现的分离器,代码量短,没有使⽤Lock(锁MySQL), 因此效率⾼
- 持久化-Redis直接将数据存储到内存中,要将数据保存到磁盘上,Redis可以通 过两种⽅式实现持久化。
定时快照(snapshot) :每隔⼀段时间将整个数据库内容写⼊到磁盘上,因为 每次都是全部数据,代价⽐较⾼ 。
基于语句追加(aof) :只追踪变化的数据,但是追加的 log可能很⼤,同时所有的操作均重新执⾏⼀次,恢复 速度慢 。
- 线程安全-因为Redis所有操作都是原⼦性(要么都成功,要么都失败),同时还没有锁,所以Redis的每个命令都是线程安全的
Redis优势
高性能
假设下如果所有的数据都从数据库中读取,特别是是⼀些复杂的数据,每次都查询
mysql 性能必定⾮常差。所以对于 ⼀些复杂操作耗时查出来的结果且确定后⾯不怎
么变化的数据放到缓存,能⼤幅提⾼系统响应。(多查询少修改的数据)
高并发
mysql 单机⼀般只能⽀撑到 2000Qps ,而 Redis 由于是 K/V 式的操作,单机可以⽀撑并
发量可达到⼏万到⼗⼏万。
Redis缺点
1、数据库容量受到物理内存的限制,不能⽤作海量数据的⾼性能读写,因此
Redis 适合的场景主要局限在较⼩数据量的⾼性能操作和运算上。
2. Redis 不具备⾃动容错和恢复功能,主机从机的宕机都会导致前端部分读写请
求失败,需要等待机器重启或者⼿动切换前端的 IP 才能恢复。
3. 主机宕机,宕机前有部分数据未能及时同步到从机,切换 IP 后还会引⼊数据不
⼀致的问题,降低了系统的可⽤性。
4. Redis 较难⽀持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为
避免这⼀问题,运维⼈员在系统上线时必须确保有⾜够的空间,这对资源造成
了很⼤的浪费。
Redis应⽤场景
- 缓存
- 秒杀
- 计数器
- 排⾏榜
- 热点数据(经常查询,但是不经常修改或者删除的数据)
- 分布式锁
- 分布式ID
- 消息系统
Redis快的真正原因
-
内存存储: Redis将所有数据保存在内存中,内存读写速度⾮常快,远快于硬盘。这也是Redis最主要的性能优势。
-
数据结构简单: Redis⽀持的数据结构⽐较简单(例如字符串,哈希,列表, 集合和有序集合),这也在⼀定程度上提⾼了其效率。
-
非阻塞IO : Redis使⽤单线程和⾮阻塞I/O多路复⽤库处理并发连接。在处理大量并发连接时,这种模型⽐多线程和阻塞I/O的模型要⾼效。
-
持久化策略: Redis提供了多种灵活的数据持久化⽅式,包括RDB快照和AOF⽇志。⽤户可以根据需求选择最合适的持久化策略,以平衡性能和数据安全之间的关系。
-
优化的数据结构: Redis为了⾼效地实现其命令,使⽤了许多优化的数据结构 和算法,例如快速列表,跳跃列表和压缩列表
如何理解Redis是单线程的
Redis在处理命令请求时是单线程的,也就是说在任意时刻, Redis 只会使⽤⼀个 CPU核⼼。Redis 的作者 Antirez ( Salvatore Sanfilippo )设计 Redis 时,就选择了这种单线程模型,因为在很多场景下,单线程能够更好地避免竞态条件和复杂的同步问题, 简化了系统的设计和运⾏机制。
然⽽,这并不意味着Redis 的所有操作都是单线程的。例如, Redis 的某些后台操 作,如持久化、数据清理和复制等,是由单独的线程完成的。另外,从Redis 4.0 开 始,某些耗时的操作,如删除⼤key 和 LRU 过期等,也可以由后台线程异步处理。
所以,在理解 Redis 是单线程的时候,需要理解这是指 Redis 主线程 处理⽹络请求和执⾏命令是单线程的。这种设计充分利⽤了CPU 和内存的⾼速性能,避免了 多线程 之间的上下⽂切换和资源 竞争,保证了极⾼的执⾏效率。
Redis数据类型
Redis 有 5 种基础数据结构,分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。
Redis 所有的数据结构都是一个key对应一个value,不同类型的数据结构之间的差异就在于value的结构不同,例如string数据类型,他的value就是一个字符串,list数据类型,他的value是一个链表。
String类型
String 是 Redis 最简单的数据结构,可以存储字符串、整数或者浮点数。最常见的应用场景就是对象缓存,例如缓存用户对象,key是"userInfo"+#{用户ID},value是用户信息对象的JSON字符串。
案例:
key:userInfo123
value:{"gender":1,"nickname":"java程序鱼","userId":123}
list类型
Redis 的列表相当于 Java 语言里面的 LinkedList。
LinkedList优点:插入性能高,不管是从末尾插入还是中间插入
LinkedList缺点:随机读性能差,例如LinkedList.get(10),这种操作,性能就很低,因为他需要遍历这个链表,从头开始遍历这个链表,直到找到index = 10的这个元素为止。
set类型
Redis的set集合相当于Java的HashSet。Redis 中的 set 类型是一种无序集合,集合中的元素没有先后顺序。
补充:HashSet就是基于HashMap来实现的,HashSet,他其实就是说一个集合,里面的元素是无序的 ,他里面的元素不能重复的,HashMap的key是无顺序的,你插入进去的顺序,跟你迭代遍历的顺序是不一样的,而且HashMap的key是没有重复的,HashSet直接基于HashMap实现的。
hash类型
Redis的Hash结构相当于Java语言的HashMap,内部实现结构上与JDK1.7的HashMap一致,底层通过数据+链表实现。
zset类型
sorted set 有序集合,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。使得它类似于Java的TreeSet和HashMap的结合体。