【9k字+】第二篇:进阶:掌握 Redis 的一些进阶操做(Linux环境)

九 Redis 经常使用配置文件详解

可以合理的查看,以及理解修改配置文件,能帮助咱们更好的使用 Redis,下面按照 Redis 配置文件的顺序依次往下讲redis

  • 1k 和 1kb,1m 和 1mb 、1g 和 1gb 的大小是有区别的,同时其对大小写不敏感

  • include 至关于 import 的概念,能够引入,而后组合多个配置文件

  • 网络配置以下(为了解决远程链接问题,会注释掉 bind 127.0.0.1,以及将保护模式 protected-mode 改成 no)
    • bind 127.0.0.1 —— 绑定的ip
    • protected-mode yes —— 保护模式
    • port 6379 —— 端口设置

  • 以守护进程的方式运行,默认为 no,自行开启为 yes

  • 后台运行,须要指定 pid 文件

  • 日志相关
    • loglevel 指定日志级别:debug ,verbose,notice,warning,其中 notice 是生产环境
    • logfile —— 具体的日志名
    • database —— 数据库的数量,默认为 16
    • always-show-logo —— 是否老是显示 logo

  • 持久化相关:因为 Redis 是基于内存的数据库,因此持久化就是将数据持久化到具体的文件中去
    • 有两种方式,RDB、AOF 下面咱们会具体的讲持久化的概念,这里简单说起
    • save 900 1 :若是 900 s 内,若是至少有 1 个 key 被修改,则进行持久化操做,下面两个同理
    • stop-writes-on-bgsave-error:持久化出错,是否还要继续工做
    • rdbcompression:是否压缩 rdb 文件(会消耗 CPU)
    • rdbchecksum:保存 rdb 文件的时候,进行错误的检查校阅
    • dir: rdb 文件保存的目录

  • 主从复制会在下面专门讲解,这里暂时略过算法

  • 接下来的 SECURITY 部分,注释中有说起到关于密码的设置,这里多提一下在客户端中设置密码的方式shell

127.0.0.1:6379> ping PONG 
127.0.0.1:6379> config get requirepass # 获取redis的密码 
1) "requirepass" 
2) "" 

127.0.0.1:6379> config set requirepass "123456" # 设置redis的密码 
OK
127.0.0.1:6379> config get requirepass # 发现全部的命令都没有权限
(error) NOAUTH Authentication required. 
127.0.0.1:6379> ping
(error) NOAUTH Authentication required. 

127.0.0.1:6379> auth 123456 # 使用密码进行登陆
OK
127.0.0.1:6379> config get requirepass 
1) "requirepass" 
2) "123456"
  • CLIENTS 客户端链接部分,注释太多,这里很差截图,就简单说一说数据库

    • maxclients —— 最大客户端数量vim

    • maxmemory —— 最大内存限制centos

    • maxmemory-policy noeviction —— 内存达到限制值的处理策略缓存

    • redis 中的默认的过时策略是 volatile-lru ,设置方式以下:服务器

      • config set maxmemory-policy volatile-lru

maxmemory-policy 六种方式

  • volatile-lru:只对设置了过时时间的key进行LRU(默认值)网络

  • allkeys-lru : 删除lru算法的key架构

  • volatile-random:随机删除即将过时key

  • allkeys-random:随机删除volatile-ttl :删除即将过时的

  • noeviction: 永不过时,返回错误

  • APPEND ONLY 部分为持久化方式之一的 AOF 的配置方式,下面会细讲这两种持久化,因此这里也是说起一下便可
    • appendonly no —— 默认是不开启 AOF 模式的,默认是使用 RDB 方式持久化的,RDB 通常够用
    • appendfilename "appendonly.aof" —— 持久化文件的名字
    • appendfsync always —— 每次修改都会 sync(消耗性能 )
    • appendfsync everysec —— 每秒执行一次 sync,可能会丢失这1s的数据
    • appendfsync no —— 不执行 sync,操做系统本身同步数据,速度最快

十 Redis 持久化

前面已经讲过,Redis是一个内存数据库,也就是说,咱们的数据所有存储在内存中,而咱们常见的MySQL和Oracle等SQL数据库会将数据存储到硬盘中,凡事都是有利有弊,虽然内存数据库读写速度要比在硬盘中读写的数据库快的多,可是却出现了一个很麻烦的问题,也就是说,当 Redis 服务器重启或者宕机后,内存中的数据会所有丢失,为了解决这个问题,Redis提供了一种持久化的技术,也就是将内存中的数据存储到硬盘中去,往后方便咱们使用这些文件恢复数据库中的数据

在配置文件的解释中,提到了两种持久化方式 RDB、AOF ,下面咱们具体来说解一下:

(一) RDB 方式

(1) 概念

在指定时间间隔后,将内存中的数据集快照写入数据库 ,在恢复时候,直接读取快照文件,进行数据的恢复

简单理解:必定的时间内,检测key的变化状况,而后持久化数据

默认状况下, Redis 将数据库快照保存在名字为 dump.rdb 的二进制文件中。

文件名能够在配置文件中进行自定义,例如:dbfilename dump.rdb

(2) 工做原理

在进行 RDB 的时候,redis 的主线程是不会作 io 操做的,主线程会 fork 一个子线程来完成该操做(这也是保证了其极大性能的特色)

  1. Redis 调用forks,同时拥有父进程和子进程。
  2. 子进程将数据集写入到一个临时 RDB 文件中。
  3. 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工做方式使得 Redis 能够从写时复制(copy-on-write)机制中获益(由于是使用子进程进行写操做,而父进程依然能够接收来自客户端的请求。

咱们知道了一个进程如何采用请求调页,仅调入包括第一条指令的页面,从而可以很 快开始执行。然而,经过系统调用 fork() 的进程建立最初能够经过使用相似于页面共享的技术,绕过请求调页的须要。这种技术提供了快速的进程建立,并最小化必须分配给新建立进程的新页面的数量。

回想一下,系统调用 fork() 建立了父进程的一个复制,以做为子进程。传统上,fork() 为子进程建立一个父进程地址空间的副本,复制属于父进程的页面。然而,考虑到许多子进程在建立以后当即调用系统调用 exec(),父进程地址空间的复制可能没有必要。

所以,能够采用一种称为写时复制的技术,它经过容许父进程和子进程最初共享相同的页面来工做。这些共享页面标记为写时复制,这意味着若是任何一个进程写入共享页面,那么就建立共享页面的副本。

(3) 持久化触发条件

  1. 知足 save 条件会自动触发 rdb 原则

    • 如:save 900 1 :若是 900 s 内,若是至少有 1 个 key 被修改,则进行持久化操做
  2. 执行save / bgsave / flushall命令,也会触发 rdb 原则

    • save:当即对内存中的数据进行持久化,可是会阻塞,即再也不接受其余任何操做,这是由于 save 命令为同步命令,会占用 Redis 主进程,若 Redis 数据很是多,阻塞时间会很是长
    • bgsave:异步请求,持久化时,能够持续响应客户端请求,阻塞发生在 fock 阶段,一般很快,可是消耗内存
    • flushall:此命令也会触发持久化 ;
  3. 退出 Redis,也会自动产生 rdb 文件(默认生成位置就是 redis 的启动目录)

(4) 恢复 RDB 文件

只要将 rdb 文件,放在 Redis 的启动目录,Redis 会自动在这个目录下检查 dump.rdb 文件,而后恢复其中的数据

查询配置文件中位置的命令

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"

(5) 优缺点

优势:

  1. 适合大规模的数据恢复
  2. 对数据的完整性要求不高

缺点:

  1. 易丢失最后一次操做,由于其须要必定的时间间隔进行操做,若是 Redis 意外宕机了,这个最后一次修改的数据就没有了
  2. fork进程的时候,会占用必定的内存空间

(二) AOF 方式

(1) 概念

以日志的形式来记录每一个写的操做,将Redis执行过的全部指令记录下来(读操做不记录),只许追加文件但不能够改写文件,redis启动之初会读取该文件从新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工做。

若是你不深究其背后的操做,能够简单理解为:每个操做执行后,进行持久化操做

想要使用 AOF 方式,须要主动打开,由于默认使用的是 RDB

在配置文件中,咱们找到这两行,能够设置 aof 的启动,以及其持久化文件的名字

  • appendonly no :no 表明关闭 aof,改成 yes 表明开启

  • appendfilename "appendonly.aof" —— 持久化文件的名字

这里能够修改其持久化的一个方式

  • appendfsync always —— 每次修改都会 sync(消耗性能 )

  • appendfsync everysec —— 每秒执行一次 sync,可能会丢失这1s的数据

  • appendfsync no —— 不执行 sync,操做系统本身同步数据,速度最快

其默认是无限追加模式的,若是 aof 文件大于 64m,就 fork一个新的进程来将咱们的文件进行重写

no-appendfsync-on-rewrite no
aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

(2) aof 文件错位的解决方案

若是这个 aof 文件有错位,这时候redis是启动不起来的

Redis 给咱们提供了一个工具 redis-check-aof --fix

# 命令示例
redis-check-aof --fix appendonly.aof

(3) 优缺点

优势

  1. 文件的完整性会更加好,由于每一次修改都会同步
  2. 若使用 appendfsync no 速度最快,效率最高

缺点

  1. aof 文件大小远大于 rdb,修复速度所以比 rdb慢
  2. aof 运行效率也要比 rdb 慢,因此咱们redis默认的配置就是rdb持久化
  3. 若使用每秒同步一次,可能会丢失一秒的数据

(三) 扩展要点(来源于网络,侵删)

  1. 若是你只但愿你的数据在服务器运行的时候存在,你也能够不使用任何持久化,即只当作缓存使用

  2. 同时开启两种持久化方式

    在这种状况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,由于在一般状况下AOF

    文件保存的数据集要比RDB文件保存的数据集要完整。

    RDB 的数据不实时,同时使用二者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?做者

    建议不要,由于RDB更适合用于备份数据库(AOF在不断变化很差备份),快速重启,并且不会有

    AOF可能潜在的Bug,留着做为一个万一的手段。

  3. 性能建议

    由于RDB文件只用做后备用途,建议只在Slave上持久化RDB文件,并且只要15分钟备份一次就够

    了,只保留 save 900 1 这条规则。

    若是Enable AOF ,好处是在最恶劣状况下也只会丢失不超过两秒数据,启动脚本较简单只load自

    己的AOF文件就能够了,代价以下:

    • 一是带来了持续的IO,

    • 二是AOF rewrite 的最后将 rewrite 过程当中产生的新数据写到新文件形成的阻塞几乎是不可避免的。

    所以只要硬盘许可,应该尽可能减小AOF rewrite的频率,AOF重写的基础大小默认值64M过小了,能够设到5G以上,默认超过原大小100%大小重写能够改到适当的数值。

    若是不Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也能够,能省掉一大笔IO,也

    减小了rewrite时带来的系统波动。

    • 代价是若是Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB文件,载入较新的那个,微博就是这种架构。

十一 Redis 发布与订阅

(一) 概念

这部分,用的不是特别多,做为一个补充。 下面是我在 菜鸟教程(runoob)贴过来的定义,重制了一下图

定义:Redis 发布订阅 (pub/sub) 是一种消息通讯模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

Redis 客户端能够订阅任意数量的频道。

下图展现了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

当有新消息经过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

(二) 命令

  • PSUBSCRIBE pattern [pattern..] —— 订阅一个或多个符合给定模式的频道。
  • PUNSUBSCRIBE pattern [pattern..] —— 退订一个或多个符合给定模式的频道。
  • PUBSUB subcommand [argument[argument]] —— 查看订阅与发布系统状态。
  • PUBLISH channel message —— 向指定频道发布消息
  • SUBSCRIBE channel [channel..] —— 订阅给定的一个或多个频道。
  • SUBSCRIBE channel [channel..] —— 退订一个或多个频道

演示

------------订阅端----------------------
127.0.0.1:6379> SUBSCRIBE ideal-20 # 订阅ideal-20频道
Reading messages... (press Ctrl-C to quit) # 等待接收消息
1) "subscribe" # 订阅成功的消息
2) "ideal-20"
3) (integer) 1

1) "message" # 接收到来自 ideal-20 频道的消息 "hello ideal"
2) "ideal-20"
3) "hello ideal"

1) "message" # 接收到来自 ideal-20 频道的消息 "hello i am ideal-20"
2) "ideal-20"
3) "Hi,i am BWH_Steven"

--------------消息发布端-------------------
127.0.0.1:6379> PUBLISH ideal-20 "hello ideal" # 发布消息到ideal-20频道
(integer) 1
127.0.0.1:6379> PUBLISH ideal-20 "Hi,i am BWH_Steven" # 发布消息
(integer) 1

-----------------查看活跃的频道------------
127.0.0.1:6379> PUBSUB channels
1) "ideal-20"

(三) 原理简述

说明:每一个 Redis 服务器进程都维持着一个表示服务器状态的 redis.h/redisServer 结构,而结构的 pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息

  • 其中,字典的键为正在被订阅的频道, 而字典的值则是一个链表链表中保存了全部订阅这个频道的客户端

例子示意图:在下图展现的这个 pubsub_channels 示例中, client2 、 client5 和 client1 就订阅了 channel1(频道1) ,其余 channel (频道)同理

有了这个结构上的概念,订阅以及发布的动做就很好理解了:

  • 订阅:当客户端调用 SUBSCRIBE 命令执行订阅频道操做时,程序就会把一个个客户端(client)和要订阅的频道(channel)在 pubsub_channels 中关联起来

  • 发布: 程序首先根据 channel 定位到字典的键(例如找到 channel1), 而后将信息发送给字典值链表中的全部客户端(例如 client二、client五、client1)。

(四) 缺点

  1. 依赖于数据传输的可靠性,订阅方断线,会致使其丢失在断线期间发布者发布的消息
  2. 客户端若是读取所订阅频道发来消息的速度不够快,积压的消息会使得 Redis 输出缓存区说起变得愈来愈大,轻则下降 Redis 速度,重则崩溃

(五) 应用

  1. 多人在线聊天室
  2. 消息订阅,如公众号那种形式,可是实际大部分都用 MQ 来作(后面会写)

十二 Redis主从复制

(一) 使用缘由

首先,在一个项目中,使用一台 Redis 服务器确定是有问题的:

  • 一台服务器处理全部请求,压力过大,且容易出现故障,会致使整个相关服务出现问题

  • 一台服务器的内存是有限的,不可能将全部内存用做 Redis 存储(推荐不该该超过 20g)

  • 大部分场景下,大部分都是读的操做,写的操做会相对少一点,因此对读取的要求会大一些

而主从复制就能够将读写分离,下面来一块儿了解一下

(二) 概念

主从复制,是指将一台Redis服务器的数据,复制到其余的Redis服务器

  • 前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower)

  • 数据的复制是单向的!只能由主节点复制到从节点(主节点以写为主、从节点以读为主)

简单理解一下就是:一台服务器做为主机器,其余服务器做为从机器,他们经过命令或配置进行了链接,这样从机就能获取到主机的数据了,从机能够帮主机分担不少读的请求等等

(三) 做用

  1. 数据冗余:主从复制实现了数据的热备份,是持久化以外的一种数据冗余的方式。
  2. 故障恢复:当主节点故障时,从节点能够暂时替代主节点提供服务,是一种服务冗余的方式
  3. 负载均衡:在主从复制的基础上,配合读写分离,由主节点进行写操做,从节点进行读操做,分担服务器的负载;尤为是在多读少写的场景下,经过多个从节点分担负载,提升并发量。
  4. 高可用基石:主从复制仍是哨兵和集群可以实施的基础。

(四) 集群环境搭建(模拟)

正常的状况,应该是多台不一样的服务器,为了演示方便,这里使用几个不一样的端口来模拟不一样的 Redis 服务器

首先,要使用不一样的端口,天然须要多个不一样的配置文件了,咱们先将原先的配置文件,复制三份(分别表明等会的一台主机和两台从机)

# 一段都是为了告诉你们个人配置文件的目录,即redis 启动目录下面的 myconfig 目录下
[root@centos7 ~]# cd /usr/local/bin 
[root@centos7 bin]# ls
appendonly.aof  dump.rdb  myconfig  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server  temp-2415.rdb
[root@centos7 bin]# cd myconfig/
[root@centos7 myconfig]# ls
redis.conf

# 复制三份,分别按照等会的端口号起名
[root@centos7 myconfig]# cp redis.conf redis6379.conf
[root@centos7 myconfig]# cp redis.conf redis6380.conf
[root@centos7 myconfig]# cp redis.conf redis6381.conf

# 这样三份就赋值好了
[root@centos7 myconfig]# ls
redis6379.conf  redis6380.conf  redis6381.conf  redis.conf

复制后,就须要分别经过 vim 修改每一个配置文件的 port 、daemonize、pid 、 logfile、dbfilename

例如:

port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile "6380.log"
dbfilename dump6380.rdb

在 XShell 中再打开两个窗口,而后分别运行不一样端口号的 Redis

在第一个窗口运行 Redis 服务,使用 6379 这个配置文件

[root@centos7 bin]# redis-server myconfig/redis6379.conf

其余两个也是同理,分别启动 6380、6381

查看一下,三个端口的 Redis 都启动了

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1b4bf5017e5d4e2781d83fe698f9a67c~tplv-k3u1fbpfcp-zoom-1.image)

(五) 一主二从

一主二从,就是表明一台主机,还有两台是从机,而 Redis 默认都是主机,也就是说,咱们上面模拟搭建出来的几台 Redis 服务器,如今还都是主机,并且相互之间并不存在什么关系

在客户端中经过 info replication 命令能够查看当前的一个信息

127.0.0.1:6379> info replication
# Replication
role:master # 当前是一个 master 主机
connected_slaves:0
master_replid:bfee90411a4ee99e80ace78ee587fdb7b564b4b4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

说明:如下演示中主机端口号为 6379,两台从机分别为 6380、6381

(1) 命令的方式(暂时)

配置一主二从,只须要配置从机,使用 SLAVEOF 127.0.0.1 6379 便可

分别在 6380 和 6381 的窗口中执行

而后查询从机自身的信息,例如查询 6380 这台

127.0.0.1:6380> info replication
# Replication
role:slave # 当前身份变成了一台从机
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:364
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:364
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:85
repl_backlog_histlen:280

一样在主机中查询,也能看到有两台从机已经链接

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=84,lag=0 # 第一台
slave1:ip=127.0.0.1,port=6380,state=online,offset=84,lag=0 # 第二台
master_replid:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84

(2) 修改配置文件的方式(永久)

上面使用命令的方式,须要每一次重启等都须要执行命令,而将其写到配置文件中的时候,就能够每次根据配置自动加载了,首先修改从机配置文件中的 replicaof 后面跟随主机的 ip 和 端口

若是主机的 Redis 设置了密码,别忘了在从机中的 masterauth 中加上主机的密码

(3) 规则说明

  1. 从机只能读,不能写,主机可读可写可是多用于写。

    • 从机执行写操做会报错 (error) READONLY You can't write against a read only replica.
  2. 主机断电/宕机后,默认角色不变,从机还是从机,集群只是失去了写操做,等待主机恢复,会从新回到原来的状态

    • 主机故障后,若须要一台从机做为主机,有两种方式可选
      • ① 从机手动执行命令 slaveof no one 使其成为主机
      • ② 使用哨兵模式自动选举(下面接着讲解哨兵模式)
  3. 从机断电/宕机后,若以前使用的是命令的方式称为从机,则启动后没法获取主机,从新配置或者是使用配置文件的方式成为从机,重启后,能够从新获取到主机全部数据

(4) 复制原理

Slave(从机) 启动成功链接到 Master(注解) 后会发送一个 sync(同步命令)

Master 接到命令,启动后台的存盘进程,同时收集全部接收到的用于修改数据集命令,在后台进程执行,完毕以后,master将传送整个数据文件到slave,并完成一次彻底同步。

全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。

增量复制:Master 继续将新的全部收集到的修改命令依次传给slave,完成同步

可是只要是从新链接master,一次彻底同步(全量复制)将被自动执行,从机中就能看到全部数据

十三 哨兵模式

(一) 概念

在前面的主从复制的概念中,咱们知道,一旦主服务器宕机,就须要使用手动的方式,将一台从服务器切换为主服务器,这种方式很麻烦,还有一种方式就是哨兵模式,也是一种比较推荐的方式

定义:哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,做为进程,它会独立运行。其原理是哨兵经过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

其做用以下:

  • 经过发送命令,让Redis服务器返回监控包括主服务器和从服务器的运行状态,。
  • 当哨兵监测到master宕机,会自动将slave切换成master,而后经过发布订阅模式通知其余的从服务器,修改配置文件,让它们切换主机。

单哨兵与多哨兵模式:

单哨兵模式:以独立的进程监控3台 Redis 服务器是否正常运行

多哨兵模式:除了监控Redis 服务器,哨兵之间也会互相监控

(二) 配置以及启动

Redis 启动目录下的 redis-sentinel 就是咱们要启动的哨兵,可是咱们须要为其指定配置文件,这样哨兵太知道要监控谁

我在个人 Redis 启动目录 /usr/local/bin/ 下的 myconfig 目录中,建立了一个名为 sentinel.conf 的配置文件

[root@centos7 bin]# vim myconfig/sentinel.conf

里面写入了其核心配置内容,即指定监控咱们本地 6379 端口的主机,后面的数字1,表明主机宕机后,会使用投票算法机制选择一台从机做为新的主机

# sentinel monitor 被监控的名称 host port 1 
sentinel monitor myredis 127.0.0.1 6379 1

接着咱们回到 Redis 启动目录,以刚才那个配置文件启动哨兵

[root@centos7 bin]# redis-sentinel myconfig/sentinel.conf

启动成功以下图:

一旦将主机断开链接,等待一下,哨兵监测到,就会发起投票(这里只有一个哨兵,因此是 100%的),而后切换一台从机成为新的主机,而主机一旦从新上线后,也只能做为新主机的一台从机了

能够根据哨兵这边自动弹出来的日志看到,首先 6379 这台主机断开后,1 个哨兵认为其断开,而后下面的 switch 即选择了新的 6380 做为新的主机,6379 从新上线后,只能做为 6380 的从机了

查看一下 6380 的信息,其果真已经成为了主机

127.0.0.1:6380> info replication
# Replication
role:master # 主机
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=147896,lag=0
slave1:ip=127.0.0.1,port=6379,state=online,offset=147764,lag=0
master_replid:d32e400babb8bfdabfd8ea1d3fc559f714ef0d5a
master_replid2:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_repl_offset:147896
second_repl_offset:7221
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:85
repl_backlog_histlen:147812

(三) 完整配置文件

实际上最核心的也就是咱们刚才演示中的那一句即下面的:sentinel monitor mymaster 127.0.0.1 6379 1

还有端口修改会用到,其余的能够根据状况设置

其配置文件仍是比较复杂的

# Example sentinel.conf
 
# 哨兵sentinel实例运行的端口 默认26379
port 26379
 
# 哨兵sentinel的工做目录
dir /tmp
 
# 哨兵sentinel监控的redis主节点的 ip port 
# master-name  能够本身命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 1
 
# 当在Redis实例中开启了requirepass foobared 受权密码 这样全部链接Redis实例的客户端都要提供密码
# 设置哨兵sentinel 链接主从的密码 注意必须为主从设置同样的验证密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
 
 
# 指定多少毫秒以后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
 
# 这个配置项指定了在发生failover主备切换时最多能够有多少个slave同时对新的master进行 同步,
这个数字越小,完成failover所需的时间就越长,
可是若是这个数字越大,就意味着越 多的slave由于replication而不可用。
能够经过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
 
 
 
# 故障转移的超时时间 failover-timeout 能够用在如下这些方面: 
#1. 同一个sentinel对同一个master两次failover之间的间隔时间。
#2. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所须要的时间。  
#4.当进行failover时,配置全部slaves指向新的master所需的最大时间。不过,即便过了这个超时,slaves依然会被正确配置为指向master,可是就不按parallel-syncs所配置的规则来了
# 默认三分钟
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
 
# SCRIPTS EXECUTION
 
#配置当某一事件发生时所须要执行的脚本,能够经过脚原本通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有如下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#若是脚本在执行过程当中因为收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,若是超过这个时间,脚本将会被一个SIGKILL信号终止,以后从新执行。
 
#通知型脚本:当sentinel有任何警告级别的事件发生时(好比说redis实例的主观失效和客观失效等等),将会去调用这个脚本,
#这时这个脚本应该经过邮件,SMS等方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,
#一个是事件的类型,
#一个是事件的描述。
#若是sentinel.conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,而且是可执行的,不然sentinel没法正常启动成功。
#通知脚本
# sentinel notification-script <master-name> <script-path>
  sentinel notification-script mymaster /var/redis/notify.sh
 
# 客户端从新配置主节点参数脚本
# 当一个master因为failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
# 如下参数将会在调用脚本时传给脚本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>老是“failover”,
# <role>是“leader”或者“observer”中的一个。 
# 参数 from-ip, from-port, to-ip, to-port是用来和旧的master和新的master(即旧的slave)通讯的
# 这个脚本应该是通用的,能被屡次调用,不是针对性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

十四 Redis 缓存穿透、击穿、和雪崩

此部分为一个补充知识点,本文重点仍是 Redis 的一个基本入门,而下面的这些知识点,更多的是在具体场景中产生的一些问题,并且其每个内容展开讲都是很是复杂的,因此这里只作一个基本概念的介绍,不作详细说明

(一) 缓存穿透

用户查询数据,首先在 Redis 缓存中去查,若是没有,也就是缓存没有命中,就会去持久层数据库,例如 MySQL 中去查。

缓存穿透:大量缓存未命中的状况下,大量请求持久层数据库,持久层数据库承载很大的压力,出现问题。

常看法决方案有两种:

  • 布隆过滤器
  • 缓存空对象

① 布隆过滤器:

对全部可能查询的参数以Hash的形式存储,以便快速肯定是否存在这个值,在控制层先进行拦截校验,校验不经过直接打回,减轻了存储系统的压力。

② 缓存空对象:

次请求若在缓存和数据库中都没找到,就在缓存中方一个空对象用于处理后续这个请求

不过此方法存在两种问题:

  • 空值也能被缓存的话,就会须要更多的空间来存储更多的空值
  • 即便对空值设置了过时时间,仍是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于须要保持一致性的业务会有影响

(二) 缓存击穿

定义:缓存击穿,是指一个key很是热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞

解决方案:

  1. 设置热点数据永不过时

    这样就不会出现热点数据过时的状况,可是当 Redis 内存空间满的时候也会清理部分数据,并且此种方案会占用空间,一旦热点数据多了起来,就会占用部分空间。

  2. 加互斥锁(分布式锁)

    在访问 key 以前,采用SETNX(set if not exists)来设置另外一个短时间key来锁住当前key的访问,访问结束再删除该短时间 key 。保证同时刻只有一个线程访问。这样对锁的要求就十分高。

(三) 缓存雪崩

大量的key设置了相同的过时时间,致使在缓存在同一时刻所有失效,形成瞬时DB请求量大、压力骤增,引发雪崩。

解决方案:

① redis高可用

  • 这个思想的含义是,既然redis有可能挂掉,那我多增设几台redis,这样一台挂掉以后其余的还能够继续工做,其实就是搭建的集群

② 限流降级

  • 这个解决方案的思想是,在缓存失效后,经过加锁或者队列来控制读数据库写缓存的线程数量。好比对某个key只容许一个线程查询数据和写缓存,其余线程等待

③ 数据预热

  • 数据加热的含义就是在正式部署以前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不一样的key,设置不一样的过时时间,让缓存失效的时间点尽可能均匀
相关文章
相关标签/搜索