ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # Redis 简介 - Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 - Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。 - Redis 支持数据的备份,即 master-slave 模式的数据备份。 优势: - 性能极高 – Redis 能读的速度是110000 次/s,写的速度是 81000次/s 。 - 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。 - 原子 – Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。 - 丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。 ## 配置 可以通过修改 redis.conf 文件或使用`CONFIG set`命令来修改配置。 ```shell redis 127.0.0.1:6379> CONFIG SET loglevel "notice" ``` ## 数据类型 Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zset(sorted set:有序集合) <span style="font-size:20px;">字符串</span> ```shell redis 127.0.0.1:6379> SET name "runoob" OK redis 127.0.0.1:6379> GET name "runoob" ``` 使用`GET`和`SET`命令可以获取和设置键值对 <span style="font-size:20px;">哈希</span> ```shell redis 127.0.0.1:6379> DEL runoob redis 127.0.0.1:6379> HMSET runoob field1 "Hello" field2 "World" "OK" redis 127.0.0.1:6379> HGET runoob field1 "Hello" redis 127.0.0.1:6379> HGET runoob field2 "World" ``` Redis hash 是一个键值 key=>value 对集合。 Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。 使用 `HMSET`, `HGET`命令,`HMSET`设置了两个 field=>value 对, `HGET`获取对应 field 对应的 value <span style="font-size:20px;">列表</span> Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 ```shell redis 127.0.0.1:6379> DEL runoob redis 127.0.0.1:6379> lpush runoob redis (integer) 1 redis 127.0.0.1:6379> lpush runoob mongodb (integer) 2 redis 127.0.0.1:6379> lpush runoob rabitmq (integer) 3 redis 127.0.0.1:6379> lrange runoob 0 10 1) "rabitmq" 2) "mongodb" 3) "redis" redis 127.0.0.1:6379> ``` `lpush  name  value`在 key 对应 list 的头部添加字符串元素 `rpush  name  value`在 key 对应 list 的尾部添加字符串元素 `lrem name  index`key 对应 list 中删除 count 个和 value 相同的元素 `llen name`返回 key 对应 list 的长度 <span style="font-size:20px;">集合</span> ```shell redis 127.0.0.1:6379> DEL runoob redis 127.0.0.1:6379> sadd runoob redis (integer) 1 redis 127.0.0.1:6379> sadd runoob mongodb (integer) 1 redis 127.0.0.1:6379> sadd runoob rabitmq (integer) 1 redis 127.0.0.1:6379> sadd runoob rabitmq (integer) 0 redis 127.0.0.1:6379> smembers runoob 1) "redis" 2) "rabitmq" 3) "mongodb" ``` `sadd key member`添加一个 string 元素到 key 对应的 set 集合中,成功返回1,如果元素已经在集合中返回 0,如果 key 对应的 set 不存在则返回错误 `smembers runoob`列出集合中的元素 <span style="font-size:20px;">有序集合</span> ```shell redis 127.0.0.1:6379> DEL runoob redis 127.0.0.1:6379> zadd runoob 0 redis (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 mongodb (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 0 redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000 1) "mongodb" 2) "rabitmq" 3) "redis" ``` `zadd key score member `添加元素到集合,元素在集合中存在则更新对应 score Redis zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。 zset 的成员是唯一的,但分数 score 却可以重复。 ## 常用命令 `Keys pattern` 查找所有符合给定模式 pattern 的 key , * 表示匹配所有 `EXISTS key`检查给定的 key 是否存在 `EXPIRE key seconds`为给定 key 设置过期时间,以秒计 `DEL key`该命令用于在 key 存在时删除 key ***** `SET key value`设置指定 key 的值 `GET key`获取指定 key 的值 ## questions <span style="font-size:18px;">什么是 Redis 持久化?Redis 有哪几种持久化方式?优缺点是什么?</span> 持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。 Redis 提供了两种持久化方式:RDB(默认) 和 AOF RDB 是 Redis DataBase 缩写 核心函数: - `rdbSave` 生成 RDB 文件 - `rdbLoad` 从文件加载内存 ![](https://img.kancloud.cn/d7/11/d711b3d43f6af763cf25fde8422214b7_598x126.png =400x) AOF 是 Append-only file 缩写 每当执行服务器(定时)任务或者函数时 flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作 - WRITE:根据条件,将 aof\_buf 中的缓存写入到 AOF 文件 - SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。 ![](https://img.kancloud.cn/b2/b4/b2b433df813c3a37af739d17b14c544d_564x222.png =400x) **比较**: 1、aof 文件比 rdb 更新频率高,优先使用 aof 还原数据。 2、aof 比 rdb 更安全也更大 3、rdb 性能比 aof 好 4、如果两个都配了优先加载 AOF <span style="font-size:18px;">Redis 有哪些架构模式?</span> ![](https://img.kancloud.cn/f0/57/f057cf24447d1ad8f8b9fd397c4ec299_426x241.png =400x) 特点:简单 问题:内存容量有限、处理能力有限、无法高可用 <span style="font-size:18px;">什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?</span> - 缓存穿透 一般的缓存系统,都是按照 key 去缓存查询,如果不存在对应的 value,就应该去后端系统查找(比如 DB)。一些恶意的请求会故意查询不存在的 key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。 如何避免? 1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。 2:对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。 - 缓存雪崩 当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。 如何避免? 1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。 2:做二级缓存,A1 为原始缓存,A2 为拷贝缓存,A1 失效时,可以访问 A2,A1 缓存失效时间设置为短期,A2 设置为长期 3:不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀。 # 参考链接 [https://www.cnblogs.com/jasontec/p/9699242.html](https://www.cnblogs.com/jasontec/p/9699242.html) [https://www.runoob.com/redis/redis-pub-sub.html](https://www.runoob.com/redis/redis-pub-sub.html)