通过FAQ简单了解Redis

1. Redis与其他的键值对存储有什么不同?

2个主要原因。(1) Redis支持多种复杂的数据类型,并且在这些数据类型上定义了原子操作。可直接暴露给程序员;(2) Redis不仅是一个内存数据库,还支持数据持久化到磁盘。实现了在内存容量内的高速读写数据。

2. Redis的内存占用量是多少?

64 bit计算机为例。

  • 一个空的Redis实例使用约3MB的内存。
  • 1百万个小键->字符串值对使用〜85MB的内存。
  • 1百万个键->哈希值(代表具有5个字段的对象)使用约160 MB的内存。

3. 无法拥有比内存更大的数据集。 能改变这一点吗?

过去,Redis开发人员曾尝试使用虚拟内存和其他系统来允许大于RAM的数据集。 因此,目前尚无计划为Redis创建磁盘后端。 毕竟,Redis的大部分功能都是其当前设计的直接结果。

如果你真正的问题不是所需的总RAM,而是需要将数据集拆分为多个Redis实例的事实,请阅读Redis官方文档 分区以获取更多信息。

4. 将Redis与持久化数据库一起使用是一个好主意吗?

是的。一个常见的设计模式是:有少量数据需要经常写,将这些数据放到Redis中,最终与磁盘数据库中的数据保持一致。

5. 有什么办法可以降低Redis的内存使用量?

见官方的 Redis内存优化

6. 如果Redis内存不足,会发生什么?

Redis可能会被Linux内核OOM Killer杀死,由于错误而崩溃,或者开始变慢。

Redis具有内置保护功能,允许用户使用配置文件中的maxmemory选项设置Redis可以使用的内存限制,从而设置内存使用的最大限制。 如果达到此限制,Redis将会只接受只读命令,发送错误给写命令。

INFO命令返回Redis当前的内存使用量,可以据此写脚本监控Redis服务。

7. Redis磁盘快照是原子操作吗?

对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。

Redis 支持将当前数据的快照存成一个数据文件的持久化机制。Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件,而主进程继续接受读写请求。Redis持久化与数据库持久化

Redis持久化:RDB(快照)和AOF(写命令)

8. Redis是单线程的。 如何利用多个CPU /内核?

通常而言,CPU并不是Redis的使用瓶颈。 主要瓶颈是内存或网络限制。所以,如果使用的Redis命令多为O(N)O(log(N))时间复杂度,那么基本上不会出现CPU瓶颈的情况。

为了最大程度地利用CPU,可以在同一机器中启动多个 Redis 实例,并将它们视为不同的服务器。详情见 Redis官方文档 Partitioning page

在Redis 4.0之后,后端删除对象、blocking commands 实现了多线程。

9. 一个Redis实例可以容纳的最大key数是多少? 哈希,列表,集合,排序集合中元素的最大数量是多少?

Redis最多可以处理232 个key。实验表明,每一个Redis实例至少可以处理2.5亿个key。

每一个hashlistsetsorted set最多可容纳232 个元素。

换句话说,您的限制可能是系统中的可用内存,而不是Redis本身。

10. 为什么我的slave 和master中的key数量不同?

redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF持久化(原理是将Reids的操作日志以追加的方式写入文件)。

如果你为这些key设置了 Redis 过期时间,那么这是正常现象。

  • Master在与slave的第一次同步时生成RDB文件。
  • RDB文件不包括master中已过期但仍在内存中的key。这些key仍然存在于master的内存中(逻辑上,这些key已经过期了,所以在master上认为这些key已经不存在了),但是通过INFO命令DBSIZE命令能都看到这些信息。
  • slave读取RDB文件时,并不会加载这些过期的key。

11. Redis实际上是什么意思?

REmote DIctionary Server的缩写。

12. Redis如何保证原子性?

Redis是单线程的,这也就是为什么Redis能够保证原子性。

对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。

问题来了,既然Redis是单线程,可以保证原子性,那么它的异步和非阻塞是什么?单线程如何实现异步和非阻塞?

13. Redis单线程,如何实现异步和非阻塞

再查阅了很多资料之后,我发现我对于同步/异步阻塞/非阻塞以及单线程/多线程的概念有些不清晰,下面给出简单解释。

同步/异步:首先同步和异步主要是从消息通知机制来讲起的。

同步:一个任务的完成必须依赖另一个任务,两个要么都成功要么都失败,是一种可靠的任务序列。当一个同步调用发生后,调用者必须等待返回结果,才能继续后面任务的执行。

异步:不需要等待被依赖任务的完成,只需要完成自己的任务就可以,所以是不可靠任务序列。当一个异步调用发生后,调用者不必等待返回结果,调用者可以去做其他的事情,被调用部件在处理完成后,通过(状态、通知、回调)来通知调用者。

阻塞/非阻塞:阻塞和非阻塞和调用者等待消息通知时的状态有关。很重要,不要和同步混淆。

阻塞:调用者在等待通知的过程中,不能执行其他业务,傻傻的等待通知到来。

非阻塞:和阻塞相反,调用者可以去执行其他业务。

14. RDB持久化和AOF持久化

原文 redis的持久化方式RDB和AOF的区别
原文 Redis详解(六)------ RDB 持久化
原文 Redis持久化:RDB(快照)和AOF(写命令)

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
RDB持久化可以手动触发和自动触发,保存RDB数据有两个命令,一个是save,一个是bgsave(常用这个,会fork一个子进程来实现生成RDB文件,不阻塞主进程)。
在这里插入图片描述
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
在这里插入图片描述

二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就有些最终一致性(eventually consistent)的意思了。不过生产环境其实更多都是二者结合使用的。

15. 如何保证Redis的主从数据一致?

详情见 原文 Redis主从复制原理总结

假设 Redis 的主从架构如下:
在这里插入图片描述
对其总结一下:
Redis主从复制可以根据是否是全量分为全量同步增量同步

  • 全量同步。一般发生在slave初始化节点,因为slave需要把master上的所有数据都复制一份。具体过程如下:
    在这里插入图片描述
  • 增量同步mater的写操作要同步到slave上。master每执行一个写命令就向slave发送相同的写命令,slave接收并执行收到的写命令。

redis 的策略是,无论如何,首先会尝试进行增量同步,如不成功,要求slave进行全量同步。

master为复制流维护一个内存缓冲区(in-memory backlog)masterslave都维护一个复制偏移量(replication offset)master run id,当连接断开时,slave会重新连接上master,然后请求继续复制,假如master和slave的两个master run id相同,并且指定的偏移量在内存缓冲区中还有效,复制就会从上次中断的点开始继续。如果其中一个条件不满足,就会进行完全重新同步(在2.8版本之前就是直接进行完全重新同步)。因为主运行id不保存在磁盘中,如果slave重启了的话就只能进行完全同步了。

部分同步这个新特性内部使用PSYNC命令,旧的实现中使用SYNC命令。Redis2.8版本可以检测出它所连接的服务器是否支持PSYNC命令,不支持的话使用SYNC命令。

16. Redis如何保证高可用?

详情见原文 Redis系列八:redis主从复制和哨兵

Redis 主从的缺点

  1. 主从复制。若主节点出现问题,则不能提供服务,需要人工修改配置将从变主
  2. 主从复制。主节点的写能力单机,能力有限
  3. 单机节点的存储能力也有限

主从故障如何故障转移(failover

  1. 主节点(master)故障,从节点slave端执行slaveof no one后变成新主节点;
  2. 其它的节点成为新主节点的从节点,并从新节点复制数据;
  3. 需要人工干预,无法实现高可用。

基于Redis主从的确定,所以 Redis通过Redis Sentinel来保证高可用。

Redis Sentinel 也叫哨兵机制。原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。

Sentinel的功能如下:

  • 监控(monitoring)。Sentinel会不断检查master和slave是否按预期工作。
  • 通知(notification)。若Redis实例出现问题,Sentinel可以通过API通知系统管理员或其他计算机程序。
  • 自动故障转移(automatic failover)。如果master未按预期工作,则Sentinel可以启动故障转移,将slave升级为master,其他slave从新的master进行同步,当应用程序连接时候,通知使用Redis服务器的应用程序要使用的新地址。
  • 配置提供者(configuration provider)。

Redis哨兵(Sentinel)模式
Redis 官方文档 sentinel

17. Redis主从不一致怎么办

详情见 原文 redis 数据库主从不一致问题解决方案

18. 如何保证数据库和redis一致

详情请见 Redis 如何保持和MySQL数据一致

读请求:先Redis,后Mysql。
写请求:先Mysql,后删Redis,重新写入。

MySQL处理实时性数据,例如金融数据、交易数据
Redis处理实时性要求不高的数据,例如网站最热贴排行榜,好友列表等

19. Redis集群

详情见 Redis集群详解

Redis 有3中集群模式:

  1. 主从模式。单机数据基本上就是全部数据。
  2. sentinel模式。单机数据基本上就是全部数据。
  3. cluster模式。所有Redis节点的数据之和才是全部数据。

主从模式

特点:

master可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给slave

slave一般都是只读的,并且接收master同步过来的数据

一个master可以拥有多个slave,但是一个slave只能对应一个master

slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来

master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务。master挂了以后,不会自动在slave节点中重新选一个master,需要手动操作。

工作机制:

当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。

全量复制完成后,进行增量复制,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。

Sentinel(哨兵) 模式

由于上面的主从模式没有failover,master挂了(Redis不在对外提供写操作),需要手动切换,不满足高可用性,所以产生了Sentinel模式

特点:

sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义

当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master

当旧的master重新启动后,它将不再是master而是做为slave接收新的master的同步数据

因为sentinel也是一个进程有挂掉的可能(单点故障),所以sentinel也会启动多个形成一个sentinel集群。多sentinel配置的时候,sentinel之间也会自动监控

当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心

一个sentinelsentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个Redis

sentinel最好不要和Redis部署在同一台机器,避免当这台机器出问题时,RedisSentinel都挂了。

工作机制:

每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令。心跳检测

如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线。 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态

当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线

在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令 。 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次

若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除。

当使用sentinel模式的时候,client 就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。

Cluster模式

主从模式和Sentinel模式应对的是请求相当多而数据完全能够存放在一台机器中的情况。在大数据的情况下,就需要将数据分布在不同的机器上,这也就是Redis Cluster。

特点:

多个Redis节点网络互联,数据共享

所有的节点都是一主一从(也可以是一主多从,),其中从不提供服务,仅作为备用。

不支持同时处理多个key(如MSET/MGET),因为Redis需要把key均匀分布在各个节点上,
并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为(见 Redis的分布式锁

支持在线增加、删除节点

客户端可以连接任何一个主节点进行读写

Redis cluster集群是去中心化的,每个节点都是平等的,连接哪个节点都可以获取和设置数据。

20. Redis数据丢失

详情见 Redis主从集群切换数据丢失问题

无法做到数据100%不丢失。

主要是两种情况:

  1. 异步复制同步丢失。master的增量数据同步给slave之前,master挂了。此时,上一次同步到这一次同步之间的数据丢失了,即是开启了持久化也不行。
  2. 集群产生脑裂。由于某种原因,比如网络原因,集群出现了分区,master与slave节点之间断开了联系,sentinel监控到一段时间没有联系认为master故障,然后重新选举,将slave切换为新的master。但是master可能并没有发生故障,只是网络产生分区,此时client任然在旧的master上写数据,而新的master中没有数据,如果不及时发现问题进行处理可能旧的master中堆积大量数据。在发现问题之后,旧的master降为slave同步新的master数据,那么之前的数据被刷新掉,大量数据丢失。

其余关于Redis的问题 见 面试中关于Redis的问题看这篇就够了

猜你喜欢

转载自blog.csdn.net/besmarterbestronger/article/details/106964007
FAQ
今日推荐