Redis详解(五)高级话题(事务、持久化、主从复制、安全设置)

第四章 Redis 高级话题

1. redis事务

1.1 什么是事务

​ 事务是指一系列操作步骤。这一系列的操作步骤,要么完全地执行,要么完全地不执行。

​ redis中的事务(transaction)是一组命令的集合,至少是两个或两个以上的命令,redis事务保证这些命令被执行时中间不会被任何其他操作打断。

对比sql,sql是执行不成功的时候才回滚。

1.2 事务操作的命令

(1)mulit
  • 语法:multi
  • 作用:标记一个事务的开始。事务内的多条命令会按照先后顺序被放进一个队列当中。
  • 返回值:总是返回ok
(2)exec
  • 语法:exec
  • 作用:执行所有事务块内的命令。
  • 返回值:事务内的所有执行语句内容,事务被打断,返回nil
(3)discard
  • 语法:discard
  • 作用:取消事务,放弃执行事务块内的所有命令
  • 返回值:总是返回ok
(4)watch
  • 语法:watch key [key …]
  • 作用:监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。
  • 返回值:总是返回ok
(5)unwatch
  • 语法:unwatch
  • 作用:取消watch命令对所有key的监视。如果在执行watch命令之后,exec命令或discard命令先被执行了的话,那么就不需要在执行unwatch了
  • 返回值:总是返回ok

1.3 事务的实现

(1)正常执行事务
  • 事务的执行步骤:
    1. 首先开启事务
    2. 其次向事务队列中加入命令
    3. 最后执行事务提交
## 清空数据库
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)

## 开启事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sadd works john
QUEUED   # 代表入队
127.0.0.1:6379(TX)> sadd works rose
QUEUED
127.0.0.1:6379(TX)> smembers works
QUEUED
##  执行事务
127.0.0.1:6379(TX)> exec
1) (integer) 1
2) (integer) 1
3) 1) "rose"
   2) "john"

Redis-cli客户端的命令要发给redis-server来执行,mulit命令执行后,在服务端开启一个小内存空间,存放每条命令。

(2)事务执行exec之前,入队命令错误(语法错误)

严重错误导致服务器不能正常工作(例如内存不足),放弃事务。

  • 执行事务步骤:
    1. multi 正常命令
    2. set key value 正常错误
    3. incr 命令语法错误
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name lisi
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> incr k1 k2
(error) ERR wrong number of arguments for 'incr' command  
(3)事务执行exec命令后,命令执行错误,事务
  • 执行步骤:
    1. multi正常命令。
    2. set username zhangsan正常命令
    3. lpop username 正常命令(移除并返回列表中第一个元素),语法没有错误,执行命令时才会有错误。
    4. exec正常执行,发现错误可以在事务提交前放弃事务,执行discard。

在exec执行后产生的错误,即使事务中有某个/某些命令在执行时产生了错误,事务中的其他命令仍然会继续执行。

redis在事务失败时不进行回滚,而是继续执行余下的命令。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set name lisi
QUEUED
127.0.0.1:6379(TX)> lindex k1 1 ## 语法上没错,执行时出错。
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) "lisi"
(4)放弃事务
  • 执行步骤:
    1. multi 开启事务
    2. set age 25 命令入队
    3. set age 30 命令入队
    4. discard放弃事务,则命令队列不会被执行。
127.0.0.1:6379> set age 10
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set age 20
QUEUED
127.0.0.1:6379(TX)> set age 30
QUEUED
127.0.0.1:6379(TX)> discard  ## 放弃事务
OK
127.0.0.1:6379> get age
"10"
(5)redis的watch机制
1. 原理
  • 原理:
    • watch机制:使用watch监视一个或多个key,跟踪key的value修改情况,如果有key的value值在事务exec执行之前被修改了,整个事务被取消。exec返回提示信息,表示事务已经失败。
  • watch机制使事务exec变的有条件,事务只有在被watch的key没有修改的前提下才能执行。不满足条件,事务被取消。使用watch监视了一个带过期时间的键,那么即使这个键过期了,事务仍然可以正常执行。

为了高效,redis并没有给数据上锁。

  • 大多数情况下,不同的客户端会访问不同的键,相互同时竞争同一key的情况一般都很少,watch能很好解决数据冲突的问题。
2. 何时取消key的监视(watch)?
  1. watch命令可以被调用多次。对键的监视从watch执行之后开始生效,直到调用exec为止。不管事务是否成功执行,对所有键的监视都会被取消。
  2. 当客户端断开连接时,该客户端对键的监视也会被取消。
  3. unwatch命令可以手动取消对所有键的监视。
3.watch的事例
  • 执行步骤

    1. 首先启动redis-server,在开启两个客户端连接。分别叫A客户端和B客户端。
    2. 启动redis服务器。

    客户端a,设置登录人数10,监视。开启事务设置为11

    客户端b,修改为15,客户端a

事务还未执行exec,另外一个客户端修改了数据,事务提交返回nil,代表事务中断。

2.持久化

2.1 持久化概述

  • 持久化可以理解为存储,就是将数据存储到一个不会丢失的地方,如果把数据放在内存中,电脑关闭或重启数据就会丢失,所以放在内存中的数据不是持久化的,而放在磁盘就算是一种持久化
  • redis的数据存储在内存中,内存是瞬时的,如果linux宕机或重启,又或者redis崩溃或重启,所有的内存数据都会丢失,为解决这个问题,redis提供两种机制对数据进行持久化储存,便于发生故障后迅速恢复数据。

2.2 持久化方式

(1)RDB方式
  1. 什么是RDB方式?

    • redis database (rdb),就是在指定的时间间隔内将内存中的数据集快照写入磁盘,数据恢复时将快照文件直接再度到内存。
    • rdb保存了某个时间点的数据集(全部数据)。
    • 储存在一个二进制文件中,只有一个文件。默认是dump.rdb。
    • rdb技术非常适合做备份,可以保存最近一个小时,一天,一个月的全部数据。
    • 保存数据是在单独的进程中写文件,不影响redis的正常使用。
    • rdb恢复数据时比其他aof速度快。
  2. 如何实现?

    • rdb方式的数据持久化,仅需在redis.conf文件中配置即可,默认配置是启用的。

    • 在配置文件redis.conf中搜索SNAPSHOTTING,查找在注释开始和结束之间的关于rdb的配置说明。配置SNAPSHOTTING地方有三处。

    1. 配置执行rdb生成快照文件的时间策略。

      1. 对redis进行设置,让它在"n秒内数据集至少有M个key改动"这一条件被满足时,自动保存一次数据集。
      save <seconds> <changes>
      save 900 1
      ## save 20 3  如果20秒钟只保存了2个数据就有丢失数据的可能
      
    2. dbfilename:设置rdb的文件名,默认围巾啊名为dump.rdb

    3. dir:指定rdb文件的储存位置,默认是./当前目录。

    配置步骤:
    
    ## 如果redis服务启动,先停止
    ps -ef | grep redis
    ## 修改redis.conf文件,修改前先备份
    cp redis.conf bak_redis.conf
    ## 查看默认启用的rdb文件
    ll dump.rdb
    
    
(2)AOF方式
  1. 什么是AOF方式?

    Append-only file, redis每次接收一条改变数据的命令时,它将把该命令写到一个AOF文件中(只记录写操作,读操作不记录),当redis重启时,它通过执行aof文件中所有的命令来恢复数据。

  2. 如何实现

    1. aof方式的数据持久化,仅需在redis.conf文件中配置即可
    2. 配置项
      • appendonly:默认是no,改成yes即开启了aof持久化。
      • appendfilename: 指定AOF文件名,默认文件名为appendonly.aof
      • dir: 指定RDB和AOF文件存放的目录,默认是 ./
      • appendfsync: 配置向aof文件写命令数据的策略。
        • no: 不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),比较快但不是很安全。
        • always:每次执行写入都会执行同步,慢一些但是比较安全。
        • everysec :每秒执行一次同步操作,比较平衡,介于速度和安全之间。这是默认项。
      • Auto-aof-rewrite-min-size : 允许重写的最小AOF文件大小,默认是64M。当aof文件大于64M时,开始整理aof文件,去掉无用的操作命令。缩小aop文件。

aof的重写机制:把无效命令删掉,减小文件的大小。

(3)总结
  • aof能确保数据的安全性,性能上没有rdb快
  • aof是文本文件,占得空间大,读写速度比rdb要慢

3.主从复制(读写分离)

3.1 主从复制-读写分离

​ 通过持久化的功能,redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,但是由于数据是存储在一台服务器上的,如果这台服务器出现故障,比如硬盘坏了,也会导致数据丢失。

​ 为了避免单点故障,需要将数据复制多份部署在多台不同的服务器上,即使有一台服务器出现故障,其他服务器依然可以继续提供服务。

​ 要求当一台服务器上的数据更新后,自动将更新的数据同步到其他服务器上,可以使用redis的主从复制。

  • redis提供了复制功能来自动实现多台redis服务器的数据同步。
  • 可以通过部署多台redis,并配置文件中指定这几台redis之间的主从关系。
  • 主负责写入数据,同时把写入的数据实时同步到从机器,这种模式叫做主从复制,即master/slave
    • 并且redis默认master用于写
    • slave用于读,向slave写数据会导致错误
(1)新建三个redis的配置文件

如果redis启动,先停止

作为master的redis的端口是6380

作为slaver的redis端口分别是6382,6384

redis.conf 拷贝三份,redis6380.conf\redis6382.conf\redis6384.conf

## 复制配置文件
$ cp redis.conf redis6380.conf
## 重定向清空文件
$ > redis6380.conf
## 输出文件发现清空
$ cat redis6380.conf
## 复制文件
$ cp redis6380.conf redis6384.conf
(2)编辑Master配置文件

编辑Master的配置文件redis6380.conf : 在空文件加入如下内容

include /usr/local/redis-4.0.13/redis.conf
daemonize yes
port 6380
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump6380.rdb

配置项说明

## 包含原来的配置文件内容。按照自己的目录设置
include /usr/local/etc/redis6380.conf

## 后台启动应用,相当于 ./redis-server &的作用
daemonize yes
## 自定义端口号
port 6380
## 自定义的文件,表示当前程序的pid,进程id.
pidfile /var/run/redis_6380.pid
## 日志文件
logfile 6380.log
## rdb持久化的文件名称。
dbfilename dump6380.rdb
(3)编辑Slave配置文件
include /usr/local/etc/redis6382.conf 
daemonize yes
port 6382
pidfile /var/run/redis_6382.pid
logfile 6382.log
dbfilename dump6382.rdb
slaveof 127.0.0.1 6380

## 主ip 主端口
include /usr/local/etc/redis6384.conf 
daemonize yes
port 6384
pidfile /var/run/redis_6384.pid
logfile 6384.log
dbfilename dump6384.rdb
slaveof 127.0.0.1 6380
(4)启动文件
./redis-server ../redis6380.conf
./redis-server ../redis6382.conf
./      redis-server ../redis6384.conf
## mac下我没有启动成功 linux下应该没问题
## mac在redis/bin下新建终端 执行命令 报 Segmentation fault: 11 暂时无解
./redis-server /usr/local/etc/redis6380.conf 
./redis-server /usr/local/etc/redis6382.conf 
./redis-server /usr/local/etc/redis6384.conf 
## 欢迎大佬提示。
FVFC81YQL414:bin bytedance$ ps -ef | grep redis
  501   555     1   0  9:57上午 ??         0:32.83 /usr/local/opt/redis/bin/redis-server 127.0.0.1:6379 
  501 18565 18522   0  7:36下午 ttys001    0:00.01 grep redis
(5)连接客户端
redis-cli -p 6380
## 客户端查看主从信息
info replication

新建终端窗口

redis-cli -p 6382
## 客户端查看主从信息
info replication
redis-cli -p 6384
## 客户端查看主从信息
info replication

3.2 容灾处理

当master服务出现故障,需手动将slave中的一个提升为master,剩下的slave挂至新的master上(冷处理:机器挂掉,再处理)

命令:

## 将一台slave服务器升至为master(提升至slave为master)
slaveof no one

## 将 Master 6380 停止 模拟挂掉
shutdown
## 查看所有redis进程
ps -ef |grep redis
## 链接到6380
./redis-cli -p 6380
## 展示关键信息
info replication
## 将slave 挂至新的master上。
slaveof 127.0.0.1 6382
## 查看主从信息发现编程从
info replication

## 在6384 上
set k7 v7
## 会报错  读写分离,不能写入 , 6832为主 可以写入

3.3 高可用Sentine哨兵

​ Sentine哨兵是redis官方提供的高可用方案,可以用它来监控多个redis服务实例的运行情况。Redis Sentinel是一个运行在特殊模式下的redis服务器。Redis Sentinel是在多个Sentinel进程环境下互相协作工作的。

Sentinel系统有三个主要任务:

  • 监控:Sentinel不断的检查主服务器和从服务器是否按照预期正常工作。
  • 提醒:被监控的redis出现问题时,Sentinel会通知管理员或其他应用程序。
  • 自动故障转移:监控的主redis不能正常工作,Sentinel会开始进行故障迁移操作。将一个从服务器升级新的主服务器,让其他从服务器挂到新的主服务器。Redis Sentinel是在多个Sentinel进程环境下互相协助工作的。

多个sentinel哨兵之间可以相互交流,哨兵可以监控主从redis,当两个或多个哨兵监测到哨兵不能正常工作后,就会进行故障处理。

少数服从多数原则:认为主服务器出现故障的哨兵多于判定为无故障的哨兵数量时,即可判定出现故障。

(1)哨兵的配置

我用brew安装的redis,哨兵的配置文件在mac的local/etc中。redis-sentinel.conf

# Example sentinel.conf

port 26379

daemonize no

# location here.
pidfile /var/run/redis-sentinel.pid

# output for logging but daemonize, logs will be sent to /dev/null
logfile ""

# sentinel announce-ip <ip>
# unmounting filesystems 哨兵存储文件的目录
dir /tmp

# The valid charset is A-z 0-9 and the three characters ".-_".
# 哨兵 监控 两个关键字 2 是redis哨兵认为主redis不能工作生效的数量(投票数)
sentinel monitor mymaster 127.0.0.1 6379 2
# Default is 30 seconds.
sentinel down-after-milliseconds mymaster 30000

acllog-max-len 128


# Default is 3 minutes.
sentinel failover-timeout mymaster 180000

SENTINEL resolve-hostnames no

SENTINEL announce-hostnames no

复制三份

redis-sentinel26380.conf

redis-sentinel26382.conf

redis-sentinel26384.conf

开三个shell窗口

## 复制哨兵文件
cp sentinel.conf sentinel26380.conf

cp sentinel.conf sentinel26382.conf
cp sentinel.conf sentinel26384.conf
vim sentinel26380.conf
## 修改port 
## 修改 监控信息 主是6382
port 26380
sentinel monitor mymaster 127.0.0.1 6382 2

## 在不同终端下重启redis
./redis-cli -p 6384
## 在linux不同终端上启动哨兵 (出于保护mac系统,建议虚拟机操作)
./redis-sentinel ../sentinel26380.conf
./redis-sentinel ../sentinel26382.conf
./redis-sentinel ../sentinel26384.conf
## 停掉 主 6382
shutdown
## 哨兵把从升级为主
## 切换到 6380redis终端
info replication
set k7 v7
## 加入成功 证明变为主

## 切换成 6382
set k8 v8 ## 失败(主从读写分离)

## 通过6382验证主从信息
./redis-server ../redis6382.conf
./redis-cli -p 6382
info replication

哨兵的高可用方案:

哨兵自动化进行故障处理,哨兵是高度自动化的,可以减轻管理员的工作,但是哨兵本身也是程序,也有故障的几率,也不能完全都依赖哨兵。一般系统都会使用,但是哨兵系统应该是独立的,单个哨兵放到独立服务器上,不能影响其他哨兵,或者独立的虚拟机中。

4.安全设置

(1)设置密码

1.开启密码设置
  • 访问redis默认是没有密码的,这样不安全,任意用户都可以访问。可以启用使用安全密码才能访问redis.
    • 修改 redis.conf 中 requirepass。
  • redis速度相当快,外部用户可以一秒钟进行150k次的密码尝试,需要复杂密码防止密码爆破。也可以定期修改密码。
vim redis.conf
## vim中搜索 shift+:
/requirepass
## 把注释去掉
requirepass 123456
2.访问有密码的redis
  1. 连接到客户端后,使用命令auth密码,命令执行成功后,可以正常使用redis。

    ./redis-cli
    auth 123456
    
  2. 在连接客户端时使用 -a密码。例如 ./redis-cli -h ip -p port -a password

(2)修改默认端口

  • 修改redis端口,使用默认端口是十分危险的。
  • redis.conf中修改port 6379。
  • 将其修改为自己指定的端口,端口1024是保留给操作系统用的。
  • 用户可以使用的范围是 1024-65535

也可以使用 -p 参数指定端口,例如:./redis-cli -p 新设置的端口号

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值