Redis详解

一.什么是Redis?

Redis是高性能的非关系型键值对(key-value)数据库。我们来对这个概念解读下:

Redis键值对数据结构

Redis键是string类型,而值主要有五种类型,分别是String,hash,List,Set,Zset。

1)string 字符串类型  可做简单的键值对缓存(最大值512M)

2)hash 哈希类型  可存放对象

3)list 有序集合     存放列表,比如粉丝列表,评论列表等

4)set 散集合   去重复,比如两个人的粉丝列表

5)Zset   去重复排序,可列出排行旁等

Redis是非关系型数据库

我们都接触过关系型数据库,比如Orcal.mysql等都是关系型数据库。那么关系型数据库和非关系型数据库有什么区别呢?

关系型数据库:由二维表及其之间的联系所组成的一个数据组织。支持sql,数据存储在磁盘的文件中;

非关系型数据库:由键值对来存储数据,数据与数据之间都是独立的,不存在关系,数据存储在内存中。

Redis的高性能

1.Redis相比于关系型数据库,它的数据存放在内存中,所以读写速度非常快;

注:当数据存放在磁盘的文件中,我们获取数据时需要先去内存的地址表获取地址,再根据地址去磁盘文件寻找数据,数据以流的形式返回;而数据存放在内存中,我们可以直接在内存中获取地址指针运行

2.Redis的数据结构是键值对,数据相对简单,对数据操作也简单;

3.采用单线程,内存消耗少且避免了线程之间的竞争,也不需要考虑锁的问题;

 

二,Redis缓存

根据以上Redis特点,我们通常把Redis作为缓存来使用,此时我们获取数据的过程如下:

 

 

由于Redis每秒可以处理超过 10万次读写操作,能够承受的请求是远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库,减少服务器对数据源的访问频率,从而提高数据库的稳定性。

 

这时候我们会发现Redis作为内存数据库用作缓存会有一些问题,我总结了以下几点:

1.因为redis是一个内存数据库它的数据是存放在内存中,所以当redis服务器重启,获取电脑重启,数据会丢失。那么怎么防止服务宕机了内存数据丢失;

2.内存数据库的存储数据量有限,我们肯定需要充分利用Redis内存空间,如何保证缓存的数据都是热点数据,并清除掉冷门数据;

3.如何保证缓存中的数据与数据库的数据一致性;

 

下面来看看Redis是怎么处理以上三个问题的。

 

三,Redis持久化

为了解决上述的第一个问题,需要将redis内存中的数据持久化保存到硬盘的文件中,这个动作就叫持久化。

所以聪明的开发者提供了两种机制:RDB(默认)和AOF;

 

RDB:是Redis DataBase缩写快照,按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

缺点:RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。

 

AOF:是Append Only File持久化,是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

缺点:AOF 文件比 RDB 文件大,且恢复速度慢。数据集大的时候,比 rdb 启动效率低。

 

RDB与AOF对比

1.AOF文件比RDB更新频率高,优先使用AOF还原数据。

2.AOF比RDB更安全也更大

3.RDB性能比AOF好

4.当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

 

选择合适的持久化方式

只开启RDB:以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。

只开启AOF:不推荐,因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,

同时开启两种持久化方式:可保证数据的安全性,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,也可使用RDB进行数据备份。

 

 

四。Redis的过期键的删除策略及内存淘汰策略

而为了解决以上第二个问题。即如何保证缓存的数据都是热点数据,并清除掉冷门数据;redis提供了两套策略:过期键的删除策略(设置过期时间)及内存淘汰策略(不设置过期时间)

 

redis过期键的删除策略

过期策略通常有以下三种:

1.定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应

时间和吞吐量。

2.惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,

占用大量内存。

3.定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以

在不同情况下使得CPU和内存资源达到最优的平衡效果。

(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)

Redis中同时使用了惰性过期和定期过期两种过期策略。

Redis的内存淘汰策略

Redis的内存淘汰策略是指不对数据键设置过期时间,而是在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。

 

全局的键空间选择性移除

 

1.noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

2.allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(这个是最常用的)

3.allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

设置过期时间的键空间选择性移除(对设置了过期时间的数据)

1..volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。

2..volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。

3.volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

 

LRU:(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”

LFU:(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”

 

Redis内存优化

设置Redis最大使用内存是必须的。可以好好利用Hash,list,sorted set,set等集合类型数据,因为通常情况下很多小的Key-Value可以用更紧凑的方式存放到一起。尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面

 

五,redis缓存名称解释

缓存穿透

缓存穿透,是指查询一个数据库一定不存在的数据。

为了避免缓存穿透,采用缓存空值的方式,如果从数据库查询的对象为空,也放入缓存,只是设定的缓存过期时间较短,比如设置为60秒。

 

缓存雪崩

缓存雪崩,是指在某一个时间段,缓存集中过期失效.解决方式就是上面设置过期时间中使用的方式,灵活设置过期时间。

 

缓存击穿

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。解决方式直接设置为永久key就可以了。

 

 

六.Redis主从复制

对于缓存来说,一般都是用来支撑读高并发的,同时为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以Redis做成主从(master-slave)架构就显得很有必要性,一主多从,主负责写,并且将数据复制到其它的 slave 节点,从节点负责读。所有的读请求全部走从节点。这样也可以很轻松实现水平扩容,支撑读高并发。同时也实现了数据备份。

Redis主从复制过程原理:

当从库和主库建立MS关系后,会向主数据库发送SYNC命令
主库接收到SYNC命令后会开始在后台保存快照(RDB持久化过程),并将期间接收到的写命令缓存起来
当快照完成后,主Redis会将快照文件和所有缓存的写命令发送给从Redis
从Redis接收到后,会载入快照文件并且执行收到的缓存的命令(全量同步)
之后,主Redis每当接收到写命令时就会将命令发送从Redis,从而保证数据的一致(增量同步)

 

七,哨兵模式

上面提到的主从复制,如果master宕机了,那么整个服务就不可以使用了,此时我们希望系统能在还运行的slave中从新选举新的节点作为mater这样我们就不用重启服务了。能够显著的提高我们系统的稳定性,这里就需要用到我们将要介绍的哨兵模式。

 

哨兵的作用是监控Redis系统的运行状态,功能包括以下两个:

1.监控master和slave是否正常运行;

2.master出现故障就自动将slave转为master;

 

在一主多从的Redis系统中,可以使用多个哨兵进行监控任务以保证系统的问题。

1.当master因故障下线后,哨兵会进一步判断是否需要对其进行故障恢复,哨兵发送命令询问其他哨兵节点以了解他们是否也认为master下线,如果达到指定数量时,哨兵会认为master下线并选举领头的哨兵       节点对主从系统发起故障恢复。

2.领头哨兵将从停止服务的master的slave中挑选一个来充当新的master,

3.最后一步则是更新内部的记录,将已经停止服务的旧的主数据库更新为新的主数据库的从数据库,使得当其恢复服务时自动以从数据库的身份继续服务

 

八,redis集群

集群实现了对redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N。redis集群通过分区提供一定程度的可用性:即使集群中有一部分节点失效或无法进行通讯,集群也可以继续处理命令请求。相比于单体Redis,Redis集群的压力呈几何倍数减小。但Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能。

一个集群至少要有3个主节点,一个主节点至少一个从节点,所以使用至少6台服务器;整个集群分成16384个槽,平均分布到主服务器中,每个键按照一定算法储存在对应的槽中;

 

posted @ 2020-04-15 07:27  长木木弓  阅读(277)  评论(0编辑  收藏  举报