redis分布式锁面试题,redis面试题及答案
本文参考你好客网Redis面试问题
Redis哨兵模式Redis哨兵模式Redis Sentinel是一个分布式系统,可以在一个体系结构中执行多个Sentinel进程“进程”。 这些进程使用流言协议“gossip protocols”接收主服务器是否离线的信息,并使用投票协议“agreement protocols”
Redis Sentinel作为单独的可执行文件Redis-sentinel发布,但实际上只是Redis服务器在特殊模式下运行。 启动常规redis服务器时- -可以使用--sentinel选项启动Redis Sentinel
哨兵模式概述Sentinel (哨兵)是一种用于监控redis群集中主控器状态的工具,是一种redis高可用性解决方案,Sentinel哨兵模式已集成到redis2.4或更高版本中。 sentinel是redis的高可用性解决方案,sentinel系统可以监视一个或多个redis master服务以及这些master服务的所有从服务。 当主服务器脱机时,它会自动将该主服务器下的主服务器升级为主服务器以继续处理请求,而不是脱机的主服务器。
sentinel可以使redis实现主从复制。 一个集群中的主服务器失效后,sentinel可以选择新的主服务器自动接管主服务器的工作,集群中的其他redis服务器自动指向新的主同步数据。 一般来说,为了防止由于某个sentinel无法连接到master而导致的错误切换,sentinel建议使用奇数台。
Redis Sentinel角色Sentinel系统用于管理多个Redis服务器(实例),它执行以下三项任务:
监视: Sentinel会不断检查主服务器和从属服务器是否正常运行。 提醒:如果受监视的Redis服务器出现问题,Sentinel可以通过API向管理员或其他APP应用程序发送通知。 自动故障转移(Automatic failover )在某个主服务器无法正常工作时,Sentinel会将其中一个无效的主服务器升级到新的主服务器,然后将其作为无效的主服务器当客户端尝试连接到无效的主服务器时,群集会向客户端返回新的主服务器地址,以便群集可以使用新的主服务器代替无效的服务器。 Sentinel的机制每个Sentinel都会以每秒一次的频率向Master、Slave和其他Sentinel实例发送PING命令。 对于自上次有效回复PING命令以来超过down-after-milliseconds选项指定值的实例(instance ),Sentinel会将其标记为主观下划线。 如果一个主节点被标记为主观下划线,则所有监视此主节点的Sentinel必须确保主节点以每秒一次的频率确实进入了主观下划线状态。 如果有足够数量的英特尔(大于或等于配置文件中指定的值)确保主机在指定的时间范围内处于主观下划线状态,则主机将被标记为客观下划线。 通常,每个Sentinel每10秒向所有已知的Master、Slave发送一次INFO命令。 如果Master被Sentinel标记为客观下划线,则Sentinel向下划线Master中的所有Slave发送INFO命令的频率将从每10秒一次更改为每秒一次。 如果没有足够数量的Sentinel同意Master脱机,则Master的客观脱机状态将被删除。 如果主机再次回复sentinel ping命令的有效回复,则主机的主观脱机状态将被删除。 可以监视Redis Sentinel的优缺点主数据库和从数据库是否正常运行,并在主数据库发生故障时自动将从数据库转换为主数据库。 如果实现自动切换的redis服务器发生问题,则会向缺陷主数据库发送一条消息,告知发生了故障。 在切换选举时容易出现瞬间断线现象,Redis Sentinel的原理是首先哨兵模式是一种特殊模式,实现了redis的高可用性,首先哨兵是一个独立的过程,可以实现redis实例的监控、通知和自动故障切换
实际上,每个哨兵节点每秒ping一次心率监测,包括所有redis实例和sentinel同伴,根据答案判断节点是否在线。
如果一个sentinel线程发现主库在指定时间(down-after-milliseconds )内没有对此PING做出响应,则该线程将确定主库不可用这种情况称为“主观无效化”)。 ) )即SDOWN ); 这通常不会立即引起故障切换,但当多个sentinel线程发现主库不可用时
超过 sentinel.conf 里面的配置项 sentinel monitor mymaster {#ip} {#port} {#number} 中的 #number 时候(这里实际上采用了流言协议),一般其余 sentinel 线程会通过 RAFT 算法推举领导的 sentinel 线程负责主库的客观下线并同时负责故障自动转移,这种情况叫 “客观失效”(即 ODOWN)。
具体流程如下图所示:
哨兵模式的配置项 配置项参数类型作用port整数启动哨兵进程端口dir文件夹目录哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限sentinel down-after-milliseconds<服务名称><毫秒数(整数)>指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒)sentinel parallel-syncs<服务名称><服务器数(整数)>指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高sentinel failover-timeout<服务名称><毫秒数(整数)>指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟sentinel notification-script<服务名称><脚本路径>指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用Redis哨兵模式配置 说明
Redis 三主三从可以最完整的保证数据的完整性,但是所需要的服务器资源也是最多的。在一般情况,统筹兼顾数据完整性和方案经济性,一般最优解是采用一主两从三哨兵的模式,我们使用的配置如下所示:
实例IP端口备注Redis(主)192.168.33.1359500Redis(从)192.168.33.1369501Redis(从)192.168.33.1339502Sentinel(1)192.168.33.13526379默认端口Sentinel(2)192.168.33.13626379默认端口Sentinel(3)192.168.33.13326379默认端口创建目录
首先,我们在 135 机器上,创建配置存放的目录,命令如下:
mkdir -p /usr/local/redis/mastermkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
接着,我们在 136 机器上,创建类似的目录,命令如下:
mkdir -p /usr/local/redis/slavemkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
最后,我们在 133 机器上,创建目录,命令如下:
mkdir -p /usr/local/redis/slavemkdir -p /usr/local/redis/sentinel
创建完毕,如下图所示:
至此,所有的目录都创建完毕。
创建主从配置
我们首先,在 135 机器上,创建 master 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/master/redis-master.conf
接着,我们写入如下配置内容:
bind 0.0.0.0port 9500logfile "9500.log"dbfilename "dump-9500.rdb"daemonize yesrdbcompression yes
接着,我们在 136 机器上,配置从的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0port 9501logfile "9501.log"dbfilename "dump-9501.rdb"daemonize yesrdbcompression yesslaveof 192.168.33.135 9500
我们再次配置 133 机器上的从配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/slave/redis-slave.conf
接着,我们写入如下配置内容:
bind 0.0.0.0port 9502logfile "9502.log"dbfilename "dump-9502.rdb"daemonize yesrdbcompression yesslaveof 192.168.33.135 9502
至此,我们的主从配置已经配置完毕了。
创建sentinel配置
我们首先,在 135 机器上,创建 sentinel 的配置,使用 vim 创建对应的配置文件,具体命令如下:
vim /usr/local/redis/sentinel/sentinel.conf
接着,我们写入如下配置内容:
port 26379logfile "26379.log"daemonize yes# 这里定义主库的IP和端口,还有最后的2表示要达到2台sentinel认同才认为主库已经挂掉sentinel monitor mymaster 192.168.33.135 9500 2# 主库在30000毫秒(即30秒)内没有反应就认为主库挂掉(即主观失效) sentinel down-after-milliseconds mymaster 30000# 若新主库当选后,允许最大可以同时从新主库同步数据的从库数 sentinel parallel-syncs mymaster 1 # 若在指定时间(即180000毫秒,即180秒)内没有实现故障转移,则会自动再发起一次 sentinel failover-timeout mymaster 180000
接着,在 136 和 133 机器创建同样的配置文件,写入一模一样的配置内容。
启动
我们首先,在 135 机器启动 Redis 主,具体命令如下:
redis-server /usr/local/redis/master/redis-master.conf
接着,我们在 136 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
同样,我们在 133 机器启动 Redis 从,具体命令如下:
redis-server /usr/local/redis/slave/redis-slave.conf
至此,我们的主从已经启动完毕,现在,我们启动哨兵,首先在 135 机器启动,具体命令如下:
redis-server /usr/local/redis/sentinel/sentinel.conf --sentinel
接着,在 133 和 136 输入相同的命令启动即可。注意,这里我们直接使用了 redis-server 命令启动了 sentinel,也可以直接使用 redis 提供的 redis-sentinel 工具直接启动。全部启动完毕之后,我们可以使用 ps 命令,查看,具体命令如下:
ps -ef | grep redis-server
全部启动成功,则输出如下:
主从数据同步
我们首先,使用 redis-cli 登录 redis master,即 135 机器的 9500 端口,具体命令如下:
redis-cli -p 9500
接着,我们使用 GET 命令,查看键 URL 的内容,具体命令如下:
GET URL
执行完毕后,如下图所示:
同时,我们在 136 机器的 slave 上即 9501 端口,同样查看 URL 的值,执行完毕后,如下图所示:
最后,我们同样在 133 的 slave 上即 9502 端口查看 URL 的值,执行完毕后,如下图所示:
我们看到,此时三个机器上的 URL 都为空,现在,我们在 135 机器的 9500 端口也就是 redis master 上设置 URL 的值,具体命令如下:
SET URL www.haicoder.net
执行完毕后,如下图所示:
现在,我们可以在两台 slave 上,再次查看 URL 的值,我们发现,这两台 slave 都有对应的值了,如下图所示:
即,我们的主从配置完毕了。
高可用主从切换
现在,我们验证高可用,也就是能够实现自动的主动切换,我们首先停掉 master,也就是 135 机器的 9500 端口,我们执行如下命令即可:
shutdown
执行完毕后,如下图所示:
此时,我们模拟了主节点宕机了,现在,我们分别查看两个 slave 节点的配置,我们分别登录 133 和 136 机器的 slave,执行如下命令:
INFO Replication
在 9501 端口执行后,输出如下:
我们看到,此时原来是 slave 的已经自动切换为了 master,这就是哨兵在起作用,实现了故障后的主备切换,如果这时候我们在新的 9501 的 master 上设置数据,并在 9502 端口查看数据,此时也是可以同步数据的。