redis的五种数据类型
1、string(字符串);
2、hash(哈希);
3、list(列表);
4、set(集合);
5、sort set (有序集合)。
其中,string(字符串)是redis中最基本的数据类型,一个key对应一个value,string 可以包含任何数据。
Redis为什么这么快?
(1)完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销。
(2)数据结构简单,对数据操作也简单。Redis中的数据结构是专门进行设计的,每种数据结构都有一种或多种数据结构来支持。Redis正是依赖这些灵活的数据结构,来提升读取和写入的性能。
(3)采用单线程,省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,也不会出现死锁而导致的性能消耗。
(4)使用基于IO多路复用机制的线程模型,可以处理并发的链接。
Redis 基于 Reactor 模式开发了自己的网络事件处理器,这个处理器被称为文件事件处理器 file event handler。由于这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型,但是它采用IO多路复用机制同时监听多个Socket,并根据Socket上的事件来选择对应的事件处理器进行处理。文件事件处理器的结构包含4个部分
Redis两种持久化方式AOF和RDB对比
RDB
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里,RDB方式要比AOF方式更加的高效,RDB的缺点是最后一次持久化后的数据可能丢失。
AOF
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文
redis分布式锁怎么使用?
原理:基于setNX命令,防止死锁需要设置过期时间(早版本setNX和过期时间是两条指令,不是原子操作,需要引入lua,变成一条指令后就不用了),防止过期时程序未完成,需要自动续期。自动续期可以使用redision的watchdog实现。
使用流程:先上锁,如果上锁成功则执行业务,最后释放锁。如果上锁失败则返回或重试等,根据业务情况而定。
什么是Redis的脑裂现象
当Redis主从集群环境出现两个主节点为客户端提供服务,这时客户端请求命令可能会发生数据丢失的情况。
脑裂带来的影响
脑裂出现后带来最严重的后果就是数据丢失,为什么会出现数据丢失的问题呢,主要原因是新主库确定后会向所有的实例发送slave of命令,让所有实例重新进行全量同步,而全量同步首先就会将实例上的数据先清空,所以在主从同步期间在原主库执行的命令将会被清空(上面场景二是同样的道理,在网络分区恢复后原主节点将被降级为从节点,并且执行全量同步导致数据丢失),所以这就是数据丢失的具体原因。
如何应对脑裂
脑裂的主要原因其实就是哨兵集群认为主节点已经出现故障了,重新选举其它从节点作为主节点,而原主节点其实是假故障,从而导致短暂的出现两个主节点,那么在主从切换期间客户端一旦给原主节点发送命令,就会造成数据丢失。
所以应对脑裂的解决办法应该是去限制原主库接收请求,Redis提供了两个配置项。
min-slaves-to-write:与主节点通信的从节点数量必须大于等于该值主节点,否则主节点拒绝写入。
min-slaves-max-lag:主节点与从节点通信的ACK消息延迟必须小于该值,否则主节点拒绝写入。
这两个配置项必须同时满足,不然主节点拒绝写入。
在假故障期间满足min-slaves-to-write和min-slaves-max-lag的要求,那么主节点就会被禁止写入,脑裂造成的数据丢失情况自然也就解决了。
总结
Redis脑裂可以采用min-slaves-to-write和min-slaves-max-lag合理配置尽量规避,但无法彻底解决,Redis脑裂最本质的问题是主从集群内部没有共识算法来维护多个节点的强一致性,它不像Zookeeper那样,每次写入必须大多数节点成功后才算成功,当脑裂发生时,Zookeeper节点被孤立,此时无法写入大多数节点,写请求会直接失败,因此Zookeeper才能保证集群的强一致性。
Redis的各种集群方案、及优缺点对比
1.主从模式
redis单节点虽然有通过RDB和AOF持久化机制能将数据持久化到硬盘上,但数据是存储在一台服务器上的。
如果服务器出现硬盘故障等问题,会导致数据不可用,而且读写无法分离,读写都在同一台服务器上,请求量大时会出现I/O瓶颈。为了避免单点故障和读写不分离,Redis 提供了复制(replication)功能。
如上redis主从结构特点:一个master可以有多个salve节点;salve节点可以有slave节点,从节点是级联结构。
主从模式优缺点
1.优点: 主从结构具有读写分离,提高效率、数据备份,提供多个副本等优点。
2.不足: 最大的不足就是主从模式不具备自动容错和恢复功能,主节点故障,集群则无法进行工作,可用性比较低,从节点升主节点需要人工手动干预。
普通的主从模式,当主数据库崩溃时,需要手动切换从数据库成为主数据库:
1.在从数据库中使用SLAVE NO ONE命令将从数据库提升成主数据继续服务。
2.启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可同步数据。
2.哨兵模式
第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。哨兵模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来。
哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个sentinel进程。
如上图,哨兵本身也有单点故障的问题,所以在一个一主多从的Redis系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。
(1)哨兵模式的作用:
监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,处理监控主服务器、从服务器外,哨兵之间也相互监控。
故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。
(2)哨兵实现原理
哨兵在启动进程时,会读取配置文件的内容,通过如下的配置找出需要监控的主数据库:
master-name:主数据库的名字
ip和port:当前主数据库地址和端口号
quorum:在执行故障切换操作前,需要多少哨兵节点同意。
(3)主观下线和客观下线
哨兵节点发送ping命令时,当超过一定时间(down-after-millisecond)后,如果节点未回复,则哨兵认为主观下线。主观下线表示当前哨兵认为该节点已经下面,如果该节点为主数据库,哨兵会进一步判断是够需要对其进行故障切换,这时候就要发送命令(SENTINEL is-master-down-by-addr)询问其他哨兵节点是否认为该主节点是主观下线,当达到指定数量(quorum)时,哨兵就会认为是客观下线。
当主节点客观下线时就需要进行主从切换,主从切换的步骤为:
(1)选出领头哨兵。
(2)领头哨兵所有的slave选出优先级最高的从数据库。优先级可以通过slave-priority选项设置。
(3)如果优先级相同,则从复制的命令偏移量越大(即复制同步数据越多,数据越新),越优先。
(4)如果以上条件都一样,则选择run ID较小的从数据库。
选出一个从数据库后,哨兵发送slave no one命令升级为主数据库,并发送slaveof命令将其他从节点的主数据库设置为新的主数据库。
(4)哨兵模式优缺点
1.优点
哨兵模式是基于主从模式的,解决可主从模式中master故障不可以自动切换故障的问题。
2.缺点
(1)是一种中心化的集群实现方案:始终只有一个Redis主机来接收和处理写请求,写操作受单机瓶颈影响。
(2)集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响master的性能。
(3)Redis主机宕机后,哨兵模式正在投票选举的情况之外,因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。
主从模式或哨兵模式每个节点存储的数据都是全量的数据,数据量过大时,就需要对存储的数据进行分片后存储到多个redis实例上。此时就要用到Redis Sharding技术。
4.Redis Cluster
Redis 的哨兵模式虽然已经可以实现高可用,读写分离 ,但是存在几个方面的不足:
哨兵模式下每台 Redis 服务器都存储相同的数据,很浪费内存空间;数据量太大,主从同步时严重影响了master性能。
哨兵模式是中心化的集群实现方案,每个从机和主机的耦合度很高,master宕机到salve选举master恢复期间服务不可用。
哨兵模式始终只有一个Redis主机来接收和处理写请求,写操作还是受单机瓶颈影响,没有实现真正的分布式架构。
redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。
如上图,官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。Redis Cluster集群具有如下几个特点:
集群完全去中心化,采用多主多从;所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
每一个分区都是由一个Redis主机和多个从机组成,分片和分片之间是相互平行的。
每一个master节点负责维护一部分槽,以及槽所映射的键值数据;集群中每个节点都有全量的槽信息,通过槽每个node都知道具体数据存储到哪个node上。
redis cluster主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster,数据量不是很大时,使用sentinel就够了。redis cluster的性能和高可用性均优于哨兵模式。
Redis Cluster采用虚拟哈希槽分区而非一致性hash算法,预先分配一些卡槽,所有的键根据哈希函数映射到这些槽内,每一个分区内的master节点负责维护一部分槽以及槽所映射的键值数据。
Redis Cluster 着眼于扩展性,在单个 Redis 内存不足时,使用 Cluster 进行分片存储。
redis cluster需要哨兵吗?
需要
Redis 提供 6 种数据淘汰策略:
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
Redis 如何实现延时队列?
使用 sortedset,拿时间戳作为score,消息内容作为 key 调用 zadd 来生产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。