Redis二:主从复制、事务功能、发布与订阅、持久化、高可用

在Redis中如何实现认证功能?

    (1) 在redis.conf文件中开启并且设置密码
    (2) redis-cli登陆后,在命令行中执行AUTH"设置的密码"即可
# vim /etc/redis.conf
    requirepass testredis                        #此处是设置redis密码的地方,默认是被注释的,"foobared"是默认的密码,此处设置为testredis
# systemctl restart redis                        #当然修改完配置文件后是要重新启动服务来使其生效
# redis-cli                                      #如果设置完密码后不输入密码连接,登录后执行任何指令都会提示没有认证
127.0.0.1:6379> SELECT 0                         #这是切换数据库的命令,此处就是做个命令测试
(error) NOAUTH Authentication required.          #如果未输入密码登陆登陆交互式执行命令的话就会报此错误
127.0.0.1:6379> AUTH testredis                   #在交互式中可以直接输入此命令认证
OK
127.0.0.1:6379> SELECT 0                         #再次使用SELECT 0即可
OK

清空数据库:
(1) FLUSHDB:清空当前库
(2) FLUSHALL:清空所有库

Redis中所支持的事务功能:

    Note:Mysql中的事务(一组相关的操作是原子性的,要么都执行,要么都不执行,为了保证事务的特性,还可以撤销事务中的某个操作)
         Redis中的事务(能保证将多个命令请求打包成一个操作,一次性按顺序执行每一个命令,事务执行期间,服务器不会中断事务),通过"MULTI","EXEC","WATCH"等命令实现事务功能,不支持回滚)
    MULTI:开启事务,当事务完成之前,其他的客户端请求都会被阻塞,执行完毕后才会接受其它客户端请求
    EXEC:当处于阻塞状态的客户端像服务器发送EXEC命令时,EXEC将立即被服务器执行,并且服务器会遍历客户端的事务队列,执行保存事务队列中所有的命令,最终将执行结果全部返回给客户端
127.0.0.1:6379> MULTI                            #开启一个事务
OK
127.0.0.1:6379> SET ip 192.168.1.1               #定义名为ip的键,值为192.168.1.1
QUEUED                                           #会返回此结果,意味着,这一条命令被加到了队列中
127.0.0.1:6379> GET ip                           #获取名为ip键的值
QUEUED                                           #还是会返回此结果,因为没有执行EXEC,还是放到了队列中
127.0.0.1:6379> SET port 8080                    #定义名为port的键,值为8080
QUEUED                                           #还会返回此消息,将GET port命令放到了队列中等待接收EXEC指令一起执行
127.0.0.1:6379> GET port                         #获取名为port的键
QUEUED                                           #还是放到队列中
127.0.0.1:6379> EXEC                             #执行EXEC指令,也就是说事务定义完毕,从第一条逐一执行
1)OK                                             #这些结果分别对应的就是第一条指令到最后一条指令的结果
2)'192.168.1.1'
3)OK
4)'8080'

    WATCH:乐观锁(在WATCH命令与EXEC命令之间,用于监视指定数量的键,监视的键中有任何一个发生改变,服务器将拒绝执行事务)
127.0.0.1:6379> WATCH                            #开启乐观锁功能
OK 
127.0.0.1:6379> MULTI                            #开启事务功能
OK 
127.0.0.1:6379> SET ip 10.0.0.1                  #此时定义名为ip的键值为10.0.0.1,因为我们上边定了了值为192.168.1.1
QUEUED                                           #处于队列状态
127.0.0.1:6379> GET ip                           #用来获取名为ip的键的值
QUEUED                                           #同样在队列中
复制一个终端,登陆进redis交互式中(为了验证效果)   
127.0.0.1:6379> GET ip                           #获取ip的键的值
'192.168.1.1'                                    #值为之前定义的192.168.1.1
127.0.0.1:6379> SET ip 192.168.1.2               #重新定义值为192.168.1.2
OK 
127.0.0.1:6379> GET ip                           #获取ip键的值
'192.168.1.2'                                    #结果是我们新定义的值
返回到第一个终端中继续执行 
127.0.0.1:6379> EXEC                             #键入EXEC执行事务
(nil)                                            #结果为此,就是拒绝了事务的执行,参照概念理解

Redis连接相关命令:

(1) AUTH    :实现认证
(2) PING    :测试服务器是否在线
(3) ECHO    :直接打印一个简单的信息
(4) QUIT    :退出连接
127.0.0.1:6379> HELP @connection                 #查看连接组中相关的命令
127.0.0.1:6379> AUTH testredis                   #认证,后面跟设置的密码
OK
127.0.0.1:6379> PING                             #测试服务器是否在线
PONG                                             #显示PONG则说明在线
127.0.0.1:6379> ECHO "hello redis"               #打印出后方指定的字符串
"hello redis"

Redis服务器端相关命令:

    (1) BGSAVE             :用于实现异步将数据集同步到磁盘上(启动RDB持久机制命令)
    (2) LASTSAVE           :获取最新一次SAVE执行的时间戳
    (3) CLIENT SETNAME     :设定连接名
    (4) CLIENT GETNAME     :获取当前客户端的连接名
    (5) CLIENT LIST        :列出当前的客户端连接信息
    (6) CLIENT KILL        :KILL掉CLIENT,指明ip:port
    (7) INFO               :获取Redis的详细信息
    (8) CONFIG RESETSTAT   :重置INFO中的相关信息
    (9) CONFIG SET         :运行时修改,只会在内存中修改
    (10) CONFIG REWRITE    :在内存中修改的所有值同步到配置文件中
    (11) DBSIZE            :显示当前选定数据库中键的数量
    (12) MONITOR           :实时接收客户端的数据操作请求
    (13) SHUTDOWN          :把所有数据从内存同步到磁盘中后安全关闭
    (14) SLAVEOF           :配置主从
    (15) SLOWLOG           :查看Redis的man查询日志
    (16) TIME              :反馈当前时间
    (17) SYNC              :内建命令
127.0.0.1:6379> CLIENT SETNAME localconn         #指定当前连接的名称
OK 
127.0.0.1:6379> CLIENT GETNAME                   #获取当前连接的名称
"localconn" 
127.0.0.1:6379> INFO                             #键入此命令会显示很多信息,并且信息按模块分类
#Server
....
#Clients
....
#...                                             #等更多信息,此处不再一一列举,如果单独查看某个模块可以在INFO后面指明

Redis发布与订阅(publish/subscribe)

频道:消息队列

    (1) SUBSCRIBE  :定义一个或多个队列(subscriber为订阅者)
    (2) PUBLISH    :像频道发送消息
    (3) UNSUBSCRIBE:退订此前订阅的频道,后方跟订阅的名称
    (4) PSUBSCRIBE :根据正则表达式订阅
127.0.0.1:6379> HELP SUBSCRIBE               #查看关于订阅帮助
127.0.0.1:6379> SUBSCRIBE news               #定义一个名为news的频道
127.0.0.1:6379> PUBLISH news hello           #像news频道中发送hello信息,news订阅者会接收到
127.0.0.1:6379> PSUBSCRIBE "news.i[to]"      #同时定义了it,io两个频道

Redis如何实现持久化:

目的:为了方便日后数据恢复
RDB和AOF
    RDB:snapshot机制,存的数据是二进制文件,默认启动,按事先定制的策略周期性将数据从内存中读出保存至磁盘,默认数据文件为"dump.rdb"
        保存机制:
            (1)靠配置文件中定义的save,符合机制保存
            (2)客户端也可以显示SAVE或BGSAVE命令启动快照保存机制
                SAVE  :同步,在主线程保存快照,在SAVE保存完成前,会阻塞所有客户端请求
                BGSAVE:异步方式实现,启动命令后会立即返回结果,并且自动在后台开始操作,不会占用子进程
    配置文件:
        SAVE 900 1
        SAVE 300 10
        SAVE 60 10000
        stop-writes-on-bgsave-error yes          #当在做基于RDB方式备份时,出现问题是否停止,默认为yes
        rdbcompression yes                       #是否压缩RDB备份文件
        rdbchecksum yes                          #是否对RDB的校验码检测,能够判定对应数据是否产生错误
        dbfilename  dump.rdb                     #RDB文件,指明文件名
        dir /var/lib/redis                       #RDB文件的保存位置,可修改至别的目录

    AOF:Append Only File,把redis的每一个写命令按照顺序以附加的方式追加到文件末尾,比RDB方式有更好的持久化,实时同步状态
            通过记录每一次写操作追加文件尾部实现持久化机制,当Redis重启时,可通过重新执行文件中的命令在内存中重建数据库
                BGREWRITEAOF:AOF文件重写,不会读取曾经使用的AOF文件,而通过将内存中的数据以命令方式保存到临时文件中,完成后去替换原来的AOF文件
    重写过程:
        (1) Redis主进程通过fork创建子进程
        (2) 子进程根据Redis内存中的数据创建数据库重建命令序列于临时文件中
        (3) 父进程继续接收客户端请求,并会把写请求继续追加至原来的AOF文件,额外的,这些新的写请求会放置于一个缓存队列中
        (4) 子进程重写完成后会通知父进程,父进程把缓存队列中的命令写到临时文件中
        (5) 父进程用临时文件替换老的AOF文件

    配置文件:
        appendonly no                             #是否开启AOF功能,默认是关闭的
        appendfilename "appendonly.aof"           #AOF文件名称
        #appendfsync always                       #默认注释,每次收到写命令就立即写到磁盘上的aof文件; 
        appendfsync everysec                      #每秒钟往AOF文件中写一次
        #appendfsync no                           #append功能自行不会自发写到aof文件中
        no-appendfsync-on-write no                #如果设置为yes,rewrite期间对新的写操作不做fsync,暂存在缓存队列中
        auto-aof-rewrite-percentage 100           #当前aof文件大小是上次aof文件大小二倍时,再重新触发一次重写操作     
        auto-aof-rewrite-min-size 64mb            #当前aof文件启动aof后的最小值,防止频繁重写

    RDB与AOF同时启用:
        (1) BGSAVE和BGREWRITEAOF不会同时执行
        (2) 在Redis服务器启动用于恢复数据时,会优先使用AOF

Redis主从复制:

特点:
    (1) 一个Master可以有多个Slave
    (2) 一个Slave还可以做别的Slave的Master
    (3) Master以非阻塞方式同步数据至Slave

工作过程:
    A:Master
    B:SlaveA
    C:SlaveB
        刚开始的时候,A会根据"PINGCHECK"的方式检查B是否在线,如果B在线,则同步数据文件至B,B也可以像A发送请求去同步数据库或同步数据命令,A启动数据持久化的时候,也会不断的把数据同步到磁盘上,
    B像A发送同步请求,A把内存中的数据同步给B,B收到后会保存在文件中,然后将新文件装载到内存中,完成数据同步,B与C也是如此,但前提是要设置C的主为B;

主从复制案例: 
环境准备:
    (1) Master:192.168.27.102
    (2) Slave: 192.168.27.103
    (3) Redis3.2分别装在Master与Slave上,并且都是用yum的方式安装

配置文件
    slaveof <masterip> <masterport>                                #指定master的IP以及端口,自己作为Master的Slave工作
    slave-server-stale-data yes                                    #当Master连不上了,Slave发起读请求,仍然可以使用过期数据相应
    slave-read-only yes                                            #slave默认开启后就是只读的
    repl-diskless-sync no                                          #是否基于diskless方式sync,
    repl-diskless-sync-delay 5                                     #延迟时间为多少秒
    repl-disable-tcp-nodelay no                                    #是否启用tcp-nodely功能
    slave-priority 100                                             #指明slave优先级,值越大优先级越高
    min-slaves-to-write 3                                          #如果从服务器小于3个,将禁止主服务器接收写请求
    min-slaves-max-log 10                                          #从服务器不能滞后在主服务器后的10秒钟,否则主服务器将拒绝接收写请求

操作在Slave
    # redis-cli
    127.0.0.1:6379> SLAVEOF 192.168.27.102 6379                    #指明Master的IP以及端口,前提是
    OK
    127.0.0.1:6379> GET name                                       #获取名为name的键的值,会发现值与Master上定义的相同,说明已经同步
    "centos"  

Note:如果master使用requirepass认证机制的话,那么从服务器就要使用masterauthen <PASSWORD>来连入服务请求使用此密码进行认证

Redis高可用

sentinel:监控一个或多个master,可以自动发现redis环境中谁是master谁是slave,并且当master宕掉的时候会从slave中选取一个成为master,可以监控整个主从复制架构,客户端像sentinel发送查询请求
         sentinel会返回给客户端谁是新的master,为防止sentinel与主节点连接出现问题,也需要在sentinel上做这种集群,多个sentinel节点同时去监控master
    作用:
        (1) 用于管理多个redis服务实现高可用
        (2) 监控多个主服务
        (3) 能够通知
        (4) 自动故障转移
        流言协议:判断master是否还在正常工作
        投票协议:决定是否执行故障迁移,选择哪个slave成为master
命令:
    redis-server --sentinel "指明sentinel自己的配置文件"  
    redis-sentinel  "指明sentinel自己的配置文件"              #两个命令都可以

启动sentinel过程:
    (1) 服务器自身初始化(运行redis-server中专用与sentinel功能的代码)
    (2) 初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表
    (3) 创建连向master的连接

专用配置文件:/etc/redis-sentinel.conf
    port 26379                                              #sentinel监听端口
    logfile /var/log/redis/sentinel.log                     #sentinel的日志文件存放位置
    dir  /tmp                                               #sentinel的临时目录
    sentinel monitor mymaster 127.0.0.1 6379 2              #可以出现多次,用来监控多组主从环境的命令
        sentinel monitor:监控的主节点是谁
        mymaster:自己取的名字
        127.0.0.1:主节点的ip地址
        6379:主节点的端口号
        2(quorum):法定票数,指定sentinel数量的服务器在线时,才认为sentinel做的决定是有效的
    sentinel down-after-milliseconds mymaster 30000         #sentinel认为服务器不在线的话至少经过的秒数,默认单位为毫秒
    sentinel parallel-syncs myaster 1                       #刚设定为新主服务器时,允许多少从服务器发送请求
    sentinel failover-timeout mymaster 180000               #master出现故障时,新服务器在启动时的超时时间,超过此时间则提示失败

主观下线以及客观下线:
    主观下线:一个sentinel实例判断出某节点下线
    客观下线:多个sentinel实例协商后判断出某节点下线

Note:sentinel每秒钟像所有redis实例发送PING请求,redis实例必须回复PONG否则sentinel就会认为redis实例主观下线了

专用命令:
    (1) SENTINEL masters                                 #获取所有监控的主服务器
    (2) SENTINEL slaves <master name>                    #获取只能主服务器的从节点
    (3) SENTINEL get-master-addr-by-name <master name>   #根据主服务器获取地址
    (4) SENTINEL reset                                   #重置所有master节点状态
    (5) SENTINEL failover <master name>                  #手动执行故障转移

猜你喜欢

转载自blog.csdn.net/kaikai0720/article/details/81168011