|
| 1 | +# redis基础理论 |
| 2 | +### 1.什么是redis |
| 3 | +* 全称Remote Dictionary Server |
| 4 | +* redis是一个开源的,基于内存的,key-value类型的**数据结构存储服务器** |
| 5 | +* redis的键(key)只能是字符串,值(value)支持多种数据结构,如字符串(string),列表(list),哈希表(hash),集合(set),有序集合(sorted set),value的最大限制是1G |
| 6 | +* redis的读写都是在内存中操作,性能出色,并且定期进行持久化操作,将数据保存在硬盘上 |
| 7 | + |
| 8 | +### 2.redis支持那几种数据类型 |
| 9 | +字符串(string)最大512M,列表(list),哈希表(hash),集合(set),有序集合(sorted set) |
| 10 | + |
| 11 | +### 3.redis主要消耗什么物理资源 |
| 12 | +内存 |
| 13 | + |
| 14 | +### 4.redis的优缺点 |
| 15 | +#### 优点: |
| 16 | +* 速度快,在内存中读写 |
| 17 | +* 数据结构丰富,string,list,hash,set,sorted set |
| 18 | +* 支持事务,操作原子性,对数据的更改要么全部执行,要么全部不执行 |
| 19 | +* 支持数据持久化 |
| 20 | +* 灵活,可以设置key的过期时间 |
| 21 | + |
| 22 | +#### 缺点: |
| 23 | +* 数据库容量受内存大小限制 |
| 24 | + |
| 25 | +### 5.redis快的原因 |
| 26 | +* 完全基于内存 |
| 27 | +* 数据结构简单 |
| 28 | +* 单线程,避免了多进程多线程的切换导致CPU的开销,不用考虑锁的问题 |
| 29 | +* 使用多路IO复用模型,非阻塞IO |
| 30 | + |
| 31 | +### 6.为什么用redis做缓存 |
| 32 | +1. 性能高,用户第一次访问数据库中的数据是读取硬盘,过程比较慢,将该用户访问的数据在内存中缓存,下次读取就是直接在内存中读取,所以速度比较快 |
| 33 | +2. 高并发,直接操作缓存能够承受的请求是远大于直接访问数据库的 |
| 34 | +3. 支持分布式与持久化,即使服务器出现故障不会导致数据丢失 |
| 35 | + |
| 36 | +### 7.redis的应用场景 |
| 37 | +* 计数器:对于频繁读写的计数量,可以用redis缓存 |
| 38 | +* 缓存:将热点数据放到内存中,设置内存的最大使用量及淘汰策略保证缓存的命中率 |
| 39 | +* 会话缓存:用redis统一保存多台应用服务器的session会话信息,应用服务器不再存储session信息,不具备状态,一个用户可以请求任意一台应用服务器,实现分布式 |
| 40 | +* 消息队列:list可以使用lpush和rpop写入与读取数据 |
| 41 | + |
| 42 | +### 8.什么是redis持久化 |
| 43 | +持久化就是把内存中的数据写到硬盘中,防止服务器宕机了内存数据丢失 |
| 44 | + |
| 45 | +### 9.redis的持久化机制 |
| 46 | +redis提供两种持久化机制,RDB(默认)和AOF、 |
| 47 | +#### 9.1. RDB持久化,redis datebase快照 |
| 48 | +RDB是redis默认的持久化方式,按照一定的时间将内存的数据以快照的形式保存到硬盘上,对应产生的数据文件dump.rdb,通过配置文件中的save参数来定义快照的周期。 |
| 49 | + |
| 50 | + |
| 51 | +**RDB优点** |
| 52 | +* 只有一个dump.rdb文件,方便持久化 |
| 53 | +* 性能最大化,使用单独的子进程来进行持久化操作,主进程不受影响,保证了redis的性能 |
| 54 | +* 对于数据集较大时,比AOF启动效率高 |
| 55 | +* 容灾性好,将数据保存在安全的硬盘上 |
| 56 | + |
| 57 | +**RDB缺点** |
| 58 | +* RDB是间隔一段时间进行持久化,如果这段时间内发生故障,会丢数据 |
| 59 | + |
| 60 | +#### 9.2. AOF持久化,Append Only File |
| 61 | +AOF是将redis执行的每次写命令,追加到缓存区aof_buf记录,再同步到单独的日志文件中,当重启redis会重新从持久化的日志文件中恢复数据,当两种持久化机制同时开启,redis会优先选择AOF恢复。 |
| 62 | + |
| 63 | +**AOF优点** |
| 64 | +* 数据安全,aof 持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次 |
| 65 | +* AOF比RDB更新数据的频率高,也更安全 |
| 66 | + |
| 67 | +**缺点:** |
| 68 | +* AOF的文件比RDB文件大,恢复速度慢 |
| 69 | +* 数据集较大时,比RDB启动效率低 |
| 70 | + |
| 71 | +### 10.redis过期键删除策略 |
| 72 | +**定时过期:** |
| 73 | +每个设置过期时间的key都有一个定时器,到过期时间就会立即清除,该策略可以立即清除过期的数据,对内存友好,但是会占用大量的cpu资源去处理过期的数据,影响redis效率 |
| 74 | + |
| 75 | +**惰性过期:** |
| 76 | +只有当访问一个key时,才判断是否过期,如果过期了再清除。该策略可以节省cpu资源,但是对内存不友好,如果过期的数据没有被再次访问,会一直占用内存。 |
| 77 | + |
| 78 | +**定期过期:** |
| 79 | +每隔一定时间,会扫描一定数量的expiresz字典中的key,并清除过期的数据。通过调整扫描的时间间隔和每次扫描的时间,可以使cpu资源和内存占用达到平衡。 |
| 80 | + |
| 81 | +**Redis中同时使用了惰性过期和定期过期两种过期策略。** |
| 82 | + |
| 83 | +### 11.redis的内存淘汰策略 |
| 84 | +内存淘汰策略是指在redis用于缓存的内存不够用的情况下,对于新写入的数据怎么申请额外的空间 |
| 85 | +* noeviction:当内存不够容纳新写入的数据时,新的写入操作会报错 |
| 86 | +* allkeys-lru:当内存不够容纳新写入的数据时,在键空间中,移除最近最少使用的key(常用) |
| 87 | +* allkeys-random:当内存不够容纳新写入的数据时,在键空间中随机删除某个key |
| 88 | +* volatile-lru:当内存不够容纳新写入的数据时,在设置了过期时间的键空间中,移除最近最少使用的key |
| 89 | +* volatile-random:当内存不够容纳新写入的数据时,在设置了过期时间的键空间中,随机移除某个key |
| 90 | +* volatile-ttl:当内存不够容纳新写入的数据时,优先移除更早过期的key |
| 91 | + |
| 92 | +### 12.redis的内存用完了会发生什么 |
| 93 | +如果内存的使用达到了设置的上限,新数据的写入会报错(读取命令可以正常执行),或者配置内存淘汰策略,当内存达到上限冲刷掉旧内容 |
| 94 | + |
| 95 | +### 数据库里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据? |
| 96 | +redis内存占用到上限,会使用内存淘汰策略 |
| 97 | + |
| 98 | +### 13.redis如何做内存优化 |
| 99 | +合理利用五种数据结构存储数据 |
| 100 | + |
| 101 | +### 14.缓存雪崩 |
| 102 | +缓存层承载着大量请求压力,有效保护了数据库层面,如果缓存在同一时间大面积失效(大部分key在同一时间过期),导致大量请求落在数据库层面上,造成数据库短时间内承受大量请求而崩溃。 |
| 103 | +**解决方案:** |
| 104 | +* 缓存的过期时间设置随机,防止同一时间大量数据同时过期 |
| 105 | + |
| 106 | +### 15.缓存穿透 |
| 107 | +查询一个根本不存在的数据,缓存层和数据库层面都不会命中,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。 |
| 108 | +**解决方案:** |
| 109 | +从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用) |
| 110 | + |
| 111 | +### 16.缓存击穿 |
| 112 | +缓存中没有,数据库中有的数据,这个时间段内对某一个热点key的并发量非常大,同时读取缓存没有读取到数据,于是又同时去查询数据库,引起数据库压力瞬间增大。和缓存雪崩不同,缓存击穿是大量请求查询同一条数据,缓存雪崩是大量的缓存数据都过期了,很多数据都查不到导致查询数据库。 |
| 113 | + |
| 114 | +以下情况可能会造成缓存击穿: |
| 115 | +* 当前key是一个热点key(例如一个秒杀活动),并发量非常大 |
| 116 | +* 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的SQL、多次IO、多个依赖等。 |
| 117 | + |
| 118 | +**解决方案:** |
| 119 | +设置热点数据永不过期,或者加锁,只允许有一个线程重建缓存,其他线程等待缓存重建完成后,重新从缓存中获取数据。 |
0 commit comments