Redis总结

  1. 什么是Redis?

Redis ,全称 Remote Dictionary Server ,是一个基于内存的高性能Key-Value 数据库。Redis 已经成为互联网公司在缓存组件选择的唯一。例如说,在各种公有云上,缓存服务都是提供的 Redis.再例如说,招聘简历要求上,都会要求掌握 Redis 。

  1. Redis优点

  1. 速度快

因为数据存在内存中,类似于HashMap , HashMap 的优势就是查找和操作的时间复杂度都是O(1)

Redis本质上是一个Key-Value类型的内存数据库,很像Memcached ,整

个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush

到硬盘上进行保存。

因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过10万次读写操作,是已知性能最快的 Key-Value数据库。

  1. 支持丰富数据类型

支持String , List,Set,Sorted Set,Hash五种基础的数据结构

Redis 的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个Value 的最大限制是1GB,不像Memcached 只能保存1MB的数据,因此 Redis可以用来实现很多有用的功能。比方说︰

  • 用他的List来做FIFO 双向链表,实现一个轻量级的高性能消息队列服务。

  • 用他的Set可以做高性能的tag系统等等。

  1. 丰富的特性

  • 订阅发布Pub / Sub 功能Key过期策略

  • 事务

  • 支持多个DB

  • 计数

  1. 持久化存储

Redis提供RDB和AOF两种数据的持久化存储方案,解决内存数据库最担心的万一Redis挂掉,数据会消失掉。

  1. 高可用

内置Redis Sentinel ,提供高可用方案,实现主从故障自动转移

内置Redis Cluster ,提供集群方案,实现基于槽的分片方案,从而支持更大的Redis规模

  1. Redis缺点

  1. 内存占用

由于Redis是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然 Redis本身有Key过期策略,但是还是需要提前预估和节约

内存。如果内存增长过快,需要定期删除数据。

另外,可使用Redis Cluster、Codis等方案,对Redis进行分区,从单机 Redis变成集群Redis。

  1. 重同步占用CPU

如果进行完整重同步,由于需要生成RDB文件,并进行传输,会占用主机的CPU,并会消耗现网的带宽。不过Redis2.8版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。

  1. Redis不能提供服务的情况

修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,Redis不能提供服务。

  1. Redis的线程模型

Redis内部使用文件事件处理器file event handler,这个文件事件处理器是单线程的,所以 Redis才叫做单线程的模型。它采用IO多路复用机制同时监听多个Socket,根据Socket 上的事件来选择对应的事件处理器进行处理。

文件时间处理器的结构包含四个部分:

  • 多个Socket

  • IO多路复用程序

  • 文件时间分派器

  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

多个Socket可能会并发产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个socket,会将socket 产生的事件放入队列中

排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器

进行处理。

  1. 为什么Redis单线程模型也能效率这么高

  1. C语言实现:

C语言的执行速度非常快。

  1. 纯内存操作

Redis为了达到最快的读写速度,将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以Redis具有快速和数据持久化的特征。

  1. 基于非阻塞的IO多路复用机制

  1. 单线程,避免了多线程的频繁上下文切换问题

Redis利用队列技术,将并发访问变为串行访问,消除了传统数据库串行控制的开销。

  1. 丰富的数据结构

Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化。例如,压缩表,对短数据进行压缩存储;跳表,使用有序的数据结构加快读取的速度。

也因为Redis是单线程的,所以可以实现丰富的数据结构,无需考虑并发的问题。

  1. Redis是单线程的,如何提高多核CPU的利用率

可以在同一个服务器部署多个Redis的实例,并把他们当作不同的服务器来使用,在某些时候,无论如何一个服务器是不够的,所以,如果你想使用多个

CPU ,你可以考虑一下分区。

  1. Redis持久化方式

Redis提供了两种方式,实现数据的持久化到硬盘

  1. (全量)RDB持久化

是指在指定的时间间隔内将内存中的数据集快照写入磁盘。实际操作过程是,fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

  1. (增量)AOF持久化

以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

  1. RDB优缺点

优点

  • 灵活设置备份频率和周期

  • 非常适合冷备份,对于灾难恢复而言,RDB是非常不错的选择。可以非常轻松地将一个单独的文件压缩后再转移到其它存储介质上。

  • 性能最大化。对于Redis 的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。也就是说,RDB对 Redis 对外提供的读写服务,影响非常小,可以让Redis保持高性能。

  • 恢复更快。相对于AOF机制,RDB的恢复速度更快,更适合恢复数据,特别是在数据集非常大的情况。

缺点

  • 无法保障数据的高可用性,即无法最大限度的避免数据丢失。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

  • 可能会使服务器停止服务几百毫秒。RDB是通过fork子进程来协助完成数据持久化工作的,当数据集比较大时,会导致服务器停止服务。

  1. AOF优缺点

优点

该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种同步策略,即每秒同步每修改(执行一个命令)同步不同步

  • 事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。

  • 而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。

  • 至于不同步,无需多言,我想大家都能正确的理解它。

由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容

  • 因为以append-only 模式写入,所以没有任何磁盘寻址的开销,写入性能非常高

  • 另外,如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在 Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。

如果AOF日志过大,Redis 可以自动启用rewrite 机制即使出现后台重写操作,也不会影响客户端的读写。因为在rewrite log 的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。当新的merge 后的日志文件 ready 的时候,再交换新老日志文件即可。

注意,AOF rewrite 机制,和RDB一样,也需要fork出一次子进程,如果

Redis内存比较大,可能会因为fork 阻塞下主进程。

AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

缺点

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB在恢复

大数据集时的速度比AOF的恢复速度要快。

  • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同

步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

  • 以前AOF发生过bug ,就是通过AOF记录的日志,进行数据恢复的时候,

没有恢复一模―样的数据出来。所以说,类似AOF 这种较为复杂的基于命令日

志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方

式,更加脆弱一些,容易有bug。不过AOF 就是为了避免rewrite过程导致

的 bug ,因此每次rewrite并不是基于旧的指令日志进行merge 的,而是基

于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

  1. 不建议在Redis节点开启RDB功能

因为会带来一定时间的阻塞,特别是数据量大的时候。

  1. 子进程fork相关的阻塞

在bgsave 的时候,Redis主进程会fork一个子进程,利用操作系统的写时复制技术,这个子进程在拷贝父进程的时候理论上是很快的,因为并不需要全拷贝,比如主进程虽然占了10G内存,但子进程拷贝他可能只要200毫秒,我认为也就阻塞了200毫秒(此耗时基本跟主进程占用的内存是成正比的),这个具体的时间可以通过统计项info stats 里的last_fork_usec查看。

  1. CPU单线程相关的阻塞

CPU单线程相关的阻塞︰Redis主进程是单线程跑在单核CPU上的,如果

显示绑定了CPU ,则子进程会与主进程共享一个CPU ,而子进程进行持久化

的时候是非常占CPU(强势90%),因此这种情况也可能导致提供服务的主进程发生阻塞(因此如果需要持久化功能,不建议绑定CPU)

  1. 内存相关的阻塞

虽然利用写时复制技术可以大大降低进程拷贝的内存消耗,但这也导致了父进程在处理写请求时需要维护修改的内存页,因此这部分内存过大的话(修改页数多或每页占空间大)也会导致父进程的写操作阻塞。(而不巧的是,Linux中TransparentHugePage会将复制内存页面单位有4K 变成2M ,这对于Redis来说是比较不友好的,也是建议优化的,具体可百度之)

  1. 磁盘相关的阻塞

极端情况下,假设整个机器的内存已经所剩无几,触发了内存交换(SWAP),则整个Redis的效率将会非常低下(显然这不仅仅针对save/bgsave ) ,因此,关注系统的 io 情况,也是定位阻塞问题的一种方法。

  1. Redis有几种数据“过期”策略?

Redis提供了3种数据过期策略:

  • 被动删除:当读/写一个已经过期的 key时,会触发惰性删除策略,直接删除掉这个过期key。

  • 主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定

期主动淘汰一批已过期的key。

  • 主动删除:当前已用内存超过maxmemory限定时,触发主动清理策略,即数据“淘汰”策略。

  1. Redis有哪些数据结构?

  • 字符串String

  • 字典Hash

  • 列表List

  • 集合Set

  • 有序集合SortedSet

  1. Redis集群如何扩容

  1. 准备新节点

  1. 加入集群

  1. 迁移槽和数据

  1. 什么是Redis主从同步

Redis的主从同步(replication)机制允许Slave 从 Master那里,通过网络传输拷贝到完整的数据备份,从而达到主从机制

  • 主数据库可以进行读写操作,当发生写操作的时候自动将数据同步到从数据

库,而从数据库一般是只读的,并接收主数据库同步过来的数据。

  • 一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

  • 第一次同步时,主节点做一次 bgsave 操作,并同时将后续修改操作记录到内存buffer ,待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

好处

通过Redis 的复制功能可以很好的实现数据库的读写分离提高服务器的负载能力主数据库主要进行写操作,而从数据库负责读操作

实际上,我们不是非常推荐在Redis中,使用读写分离。主要有两个原因:

  • Redis Sentinel只保证主节点的故障的失效转移,而例如说Jedis 库,也只监听了主节点的变化,但是从节点故障的情况,Jedis是不进行处理的。这就会导致,Jedis 读会访问到从节点,导致问题。当然,Redisson库的功能比较强大,已经支持从节点的故障监听。

  • 如果到达需要读写分离的体量,一般写操作也不一定会少,可以考虑上Redis Cluster方案,更加可靠。

  1. Redis哈希槽的概念

Redis Cluster没有使用一致性hash , 而是引入了哈希槽的概念。

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽集群的每个节点负责一部分hash槽

因为最大是16384个哈希槽,所以考虑Redis集群中的每个节点都能分配到一个哈希槽,所以最多支持16384个Redis节点。

为什么是16384呢?主要考虑集群内的网络带宽,而16384刚好是2K字节大小

  1. Redis Cluster 的主从复制模型是怎样的?

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制节点。

所以,Redis Cluster 可以说是Redis Sentinel带分片的加强版。也可以说:

  • Redis Sentinel着眼于高可用,在master宕机时会自动将slave 提升为

master ,继续提供服务

  • Redis Cluster着眼于扩展性,在单个Redis内存不足时,使用Cluster 进行分片存储

  1. Redis Cluster方案什么情况下会导致整个集群不可用?

有A,B,C 三个节点的集群,在没有复制模型的情况下,如果节点B宕机了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用。当然,这种情况也可以配置cluster-require-full-coverage=no ,整个集群无需所有槽位覆盖。

  1. Redis Cluster会有写操作丢失吗?为什么?

Redis 并不能保证数据的强一致性,而是【异步复制】,这意味这在实际中集群在特定的条件下可能会丢失写操作

tips:一定一定一定要注意,无论对于Redis Sentinel还是 Redis Cluster方案,都是通过主从复制,所以在数据的复制方面,都存在相同的情况。

  1. Redis 集群如何选择数据库?

Redis集群目前无法做数据库选择,默认在0数据库。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值