一、Redis简介
是由c语言开发的高性能的基于内存实现的键值型非关系型(NoSQL)数据库。
1.1 Redis的特点
- Redis不仅可以将数据保存在内存中,还可以通过磁盘实现数据的持久存储
- Redis支持丰富的数据类型,包括String、Hash、Set、List、zset等数据类型,因此也被称为“数据结构服务器”
- Redis支持主从同步,即master-slave主从复制模式。数据可以从主服务器向任意数量的从服务器上同步,有效的保证了数据的安全性
- Redis支持多种编程语言,包括C、C++、Java、Python等
- Redis不提供新建数据库的操作,自带16(0-15)个数据库(默认使用0库)
- Redis没有表的概念,它通过不同的数据类型来实现存储数据的需求,不同的数据类型能够适应不同的应用场景,从而满足开发这的需求
二、Redis中Value常用的数据类型
2.1 String(字符串)
- String类型是Redis最基本的数据类型
- 一个字符串类型的值最多能够存储 512 MB 的内容
- 应用场景:存储Session信息、存储缓存信息、存储整数信息、短信验证码等
set key value
get key
MSET key1 value1 key2 value2 //存储多个值
MGET name topic //查询多个 key
2.2 Hash(哈希散列)
- hash 散列是由字符串类型的 field 和 value 组成的映射表,一般被用来存储对象
- 应用场景:存储Session信息、存储商品的购物车,购物车非常适用于哈希字典表示,使用人员唯一编号作为字典的key,value值可以存储商品的id和数量等信息、存储详情页等信息
hmset name key1 value1 key2 value2
hgetall name
2.3 List(列表)
- Redis的List是有序的字符串元素集合,支持双端进行插入和删除操作,允许重复插入,可以用作队列或栈
- 应用场景:消息队列
lpush name value //在 key 对应 list 的头部添加字符串元素
rpush name value //在 key 对应 list 的尾部添加字符串元素
lrem name index //key 对应 list 中删除 count 个和 value 相同的元素
llen name //key 对应 list 的长度
2.4 Set(集合)
- Redis的Set是无序的字符串元素集合,Set 集合中的成员具有唯一性
- 集合是通过哈希表实现的
- 添加成功返回 1,如果元素已经存在,则返回 0
- 应用场景:关注功能,比如关注我的人和我关注的人,使用集合存储,可以保证人员不重复
SADD key member1 member2 member3 ... //向set中添加一个或多个元素
SREM key member1 //移除set中的指定元素
2.5 zset(sorted set:有序集合)
- Redis的zset 是一个字符串类型元素构成的有序集合,集合中的元素不仅具有唯一性,而且每个元素还会关联一 个 double 类型的分数,该分数允许重复。Redis 正是通过这个分数来为集合中的成员排序。
- 应用场景:排行榜
127.0.0.1:6379> zadd biancheng 0 Python (integer) 1 127.0.0.1:6379> zadd biancheng 1 Java (integer) 1 127.0.0.1:6379> zadd biancheng 2 Redis (integer) 1 #重复元素无法添加成功 127.0.0.1:6379> zadd biancheng 2 Redis (integer) 0 #重复分值添加成功 127.0.0.1:6379> zadd biancheng 2 GOLANG (integer) 1 #查看指定成员的分值 127.0.0.1:6379> ZSCORE biancheng Redis "2" 查看zset中的所有成员 127.0.0.1:6379> zrange biancheng 0 2 1) "Python" 2) "Java" 5) "GOLANG" 6) "Redis"
Redis 数据库操作场景实例
Redis 数据库由于其快速的读写能力和丰富的数据结构,适用于多种实际场景。以下是一些常见的 Redis 数据库操作场景实例:
缓存:
场景:应用程序常用的缓存数据,如数据库查询结果、页面内容等,以加快数据访问速度。
操作:使用 Redis 的字符串数据类型存储缓存数据,并设置适当的过期时间,以便定期更新或重新加载数据。
会话存储:
场景:存储用户的会话信息,例如登录状态、购物车内容等。
操作:将用户会话信息存储在 Redis 的hash哈希表中,每个用户一个键,字段存储具体的会话数据,通过 Redis 提供的原子性操作来更新和检索会话信息。
实时数据分析:
场景:需要对实时生成的数据进行快速的分析和聚合。
操作:利用 Redis 的有序集合(Sorted Sets)或者计数器数据类型,例如 HyperLogLog 算法用于基数估计,来进行数据统计和分析。
消息队列:
场景:应用程序需要异步处理任务或者事件通知。
操作:使用 Redis 的list列表数据类型作为消息队列,生产者将任务或消息推送到列表尾部,消费者从列表头部获取任务进行处理,实现简单的发布-订阅模式。
排行榜:
场景:需要展示用户得分或其他指标的排名。
操作:利用 Redis 的有序集合存储用户的得分和标识,通过集合操作(如范围获取)快速获取排名信息,并支持动态更新用户的得分信息。
分布式锁:
场景:确保在分布式环境下对关键资源或操作的互斥访问。
操作:使用 Redis 的字符串数据类型和 SETNX(SET if Not eXists)命令实现分布式锁,通过设置锁键和过期时间来避免死锁和锁过期问题。
发布订阅:
场景:需要实现消息的实时发布和订阅。
操作:Redis 提供了发布-订阅模式,可以通过 PUBLISH 发布消息,通过 SUBSCRIBE 订阅消息频道,用于实现实时消息通信或事件驱动的架构。
Redis的持久化☆
持久化就是把内存的数据写到磁盘中,可以防止服务宕机导致的内存数据丢失。
Redis 提供了两种持久化方式:RDB(默认) 和AOF
RDB快照模式: 全称Redis DataBase。一定时间内将内存数据以快照(记录某一时刻数据,相当于拍了一张照片)形式保存到硬盘中。某个时间点把数据写到临时文件,然后替换上次持久化的文件。
RDB:
rdb是Redis DataBase缩写
功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数
优点: 恢复大的数据集时,比AOF效率更高。
缺点: 不安全,数据丢失。
AOF: 会把每次写的命令记录到日志文件(同一个日志文件,不会替换),redis重启会将持久化的日志文件恢复。如果两种持久化都开启,优先恢复AOF。
优点: 安全,几乎不会丢失数据。
缺点: AOF文件比RDB文件大,且恢复速度慢。
AOF:
Aof是Append-only file缩写
每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作
aof写入保存:
WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件
SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。
存储结构:
内容是redis通讯协议(RESP )格式的命令文本存储。
比较:
aof文件比rdb更新频率高,优先使用aof还原数据。
aof比rdb更安全也更大
rdb性能比aof好
如果两个都配了优先加载AOF
刚刚上面你有提到redis通讯协议(RESP ),能解释下什么是RESP?有什么特点?
RESP 是redis客户端和服务端之前使用的一种通讯协议;
RESP 的特点:实现简单、快速解析、可读性好
For Simple Strings the first byte of the reply is "+" 回复
For Errors the first byte of the reply is "-" 错误
For Integers the first byte of the reply is ":" 整数
For Bulk Strings the first byte of the reply is "$" 字符串
For Arrays the first byte of the reply is "*" 数组
Redis为什么执行这么快?
- 纯内存操作:Redis将所有数据存储在内存中,这意味着对数据的读写操作直接在内存中运行,而内存的访问速度远远高于磁盘。这种设计使得Redis能够已接近硬件极限的速度处理数据读写
- 单线程模型:Redis使用单线程模型来处理客户端请求。这可能听起来效率不高,但是实际上,这种设计避免了多线程频繁切换和过度竞争带来的性能开销。Redis每个请求的执行时间都是很短的,因此单线程下,也能处理大量的并发请求
- I/O多路复用:Redis使用了I/O多路复用技术,可以在单线程的环境下同时监听多个客户端连接,只有当有网络事件(如用户发送一个请求)发生的时候才会进行实际的I/O操作。这样有效的利用了CPU资源,减少了无谓的等待
- 高效数据结构:Redis提供了多种高效的数据结构,如哈希表、有序集合等。这些数据结构的实现都经过了优化,使得Redis在处理这些数据结构的操作是非常高效的
IO多路复用:一个或少量线程重复使用,处理多个TCP连接(或多个Channel)