(NoSQL)02_Redis(下)

一、分布式事务锁(了解)

解决高并发问题:使用jdk synchrinized 或者lock 使用线程安全的类
核心做法:首先判断key是否存在 不存在则写入 存在则返回失败
使用的命令:setnx
在这里插入图片描述

redis中如何解决死锁问题

方式一  主动释放锁 
方式二 给锁设置一个过期时间(推荐)

在这里插入图片描述
命令的组合使用
在这里插入图片描述

二、redis的持久化

redis的持久化方式:RDB, AOF

2.1.快照持久化RDB

在某一个时刻  所有数据写入到硬盘中持久化。该方式 何时写入  写入的时间间隔
该方式存在数据丢失的风险
该持久化方式 适用于即使丢失小部分数据 也不会影响系统的稳定性和使用的环境中。

在这里插入图片描述

RDB的持久化方式:配置方式 命令方式

2.1.1.自动生成RDB(配置)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

rdb方式的具体的体现

修改配置文件:

  1. 将启动方式改为前台启动
    在这里插入图片描述
  2. 将rdb的持久化策略改为 10秒钟 1次改变
    在这里插入图片描述
    重启服务和客户端
    进行数据的写入
    在这里插入图片描述
    测试:
  3. 将dump.rdb先备份 在这里插入图片描述
  4. 清空所有数据 flushAll在这里插入图片描述
  5. 停止服务
    在这里插入图片描述
  6. 删除dump.rdb
    在这里插入图片描述
  7. 回复备份文件为dump.rdb
    在这里插入图片描述
  8. 重启服务
    在这里插入图片描述
  9. 查看数据 发现数据恢复
    在这里插入图片描述
    redis默认的持久化方式rdb

2.1.2.命令方式

在这里插入图片描述
在这里插入图片描述

2.1.3.命令的同步方式

bgsave 和save

bgsave 在执行该命令的时候 会在后台启动一个子进程 通过子进程来进行快照的写入
save 在快照创建完成前 是一种阻塞式的 如果保存没有完成 此时时不能执行其他命令的

在这里插入图片描述
save 与 bgsave 对比

命令 save bgsave
IO类型 同步 异步
阻塞? 是(阻塞发生在fock(),通常非常快)
复杂度 O(n) O(n)
优点 不会消耗额外的内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fock子进程,消耗内存

2.1.4. RDB的优点

  1. RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集。
  2. RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复。
  3. RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能。
  4. 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些。

2.1.5. RDB的缺点

  1. 耗时、耗性能。RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度。
  2. 不可控、丢失数据。如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你。虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据。

2.2. AOF持久化

日志形式的持久化方式
AOF的配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.1.AOF的持久化方式

采用日志形式 追加写的方式 记录操作过程中的所有的命令 追加写入文件末尾
当redis重启的时 ,就可以通过执行aof文件中的命令 来达到数据恢复的目的
在这里插入图片描述

2.2.2.AOF持久化的三种策略

可以通过配置文件配置 Redis 多久才将数据 fsync 到磁盘一次。
always
每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。
在这里插入图片描述
everysec
每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
在这里插入图片描述
no
从不 fsync :将数据交给操作系统来处理,由操作系统来决定什么时候同步数据。更快,也更不安全的选择。
在这里插入图片描述
always、everysec、no对比

命令 优点 缺点
always 不丢失数据 IO开销大,一般SATA磁盘只有几百TPS
everysec 每秒进行与fsync,最多丢失1秒数据 可能丢失1秒数据
no 不用管 不可控

推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。

2.2.3.AOF 重写

当执行的命令越来越多 此时aof文件也会变得越来越大
此时aof 可以采用bgrewriteaof命令 来重写aof文件 将其中一些重复命令 进行合并

在这里插入图片描述
在这里插入图片描述
具体内容:

如果一个子Redis是通过磁盘快照创建的,AOF重写将会在RDB终止后才开始保存。这种情况下BGREWRITEAOF任然会返回OK状态码。从Redis 2.6起你可以通过INFO命令查看AOF重写执行情况。
如果只在执行的AOF重写返回一个错误,AOF重写将会在稍后一点的时间重新调用。

Redis 的配置项为:

auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100

当AOF文件的体积大于64Mb,并且AOF文件的体积比上一次重写之久的体积大了至少一倍(100%)时,Redis将执行 bgrewriteaof 命令进行重写。

2.2.4.AOF的优点

  1. 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync。使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据。
  2. AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题。
  3. Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  4. AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

2.2.5. AOF的缺点

  1. 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
  2. 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

2.3.RDB和AOF的抉择

2.3.1. RDB 和 AOF 对比

- RDB AOF
启动优先级
体积
恢复速度
数据安全性 丢数据 根据策略决定

2.3.2. 如何选择使用哪种持久化方式?

  1. 一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
  2. 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
  3. 如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
  4. 有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快
    redis的 持久 面试必考?

三、redis的主从复制

复制(master/slave)
在这里插入图片描述
主要解决两个问题:

读写分离:master写  slave读
容灾恢复:

3.1.redis主从复制的集群规划:

一主二从:都在当前虚拟机中
一个master:p:6379
两个slave: p:6380   p:6381

3.2. 配置

配置原则:配从不配主 
配置方式:slaveof 主库ip  主库port
可以通过命令 或者设置都可以进行配置  被复制的服务器称为主服务器(master)
对主服务器进行复制的服务器则称为从服务器(slave)

3.3.实战

3.3.1.主从复制的环境准备

  1. 在redisconf目录下 复制出三分配置文件 这三份配置文件分别对应三台redis服务器
    在这里插入图片描述
  2. 修改配置文件redis.cof
    首先修改redis79.conf
    修改端口
    在这里插入图片描述
    修改启动模式 改为后端启动
    在这里插入图片描述
    pid文件的名称
    在这里插入图片描述
    日志文件的名称
    在这里插入图片描述
    rdb的文件名称
    在这里插入图片描述
    aof文件的名称
    在这里插入图片描述
    将80和81的配置文件按照上述方式进行修改 只是在上边凡事79都改为对应的端口号

3.3.2.主从复制的使用

启动测试配置是否正确
在这里插入图片描述
进行主从配置 slaveof 主库ip 主库port
命令配置 该配置是临时的 当服务器重启之后 测试主从配置信息会丢失
在这里插入图片描述
在这里插入图片描述
主从复制的测试 主机写入 从机可以复制主机的数据 和主机保持一致
在这里插入图片描述
只能主机写入 从机不允许写入数据 从机可以读取数据:
在这里插入图片描述

3.3.3.主从问题演示:

  1. 切入点问题: slave1 和slave2 从头开始复制还是从切入点开始复制?
    从头复制 无论从机何时切入 都将最终和主机保持一致
  2. 从机是否可以写入?
    不可以
  3. 如果master shutdown 之后 ?slave是原地等待master归来 还是从机上位 接替master?
    此时 slave 并没有上位 而是等待master归来
  4. 如果master归来 此时master写入数据 slave时候还依然能和master保持同步?
    可以保持数据同步
  5. 其中一台slave down掉 回归大部队之后 是否依然能够跟上大部队的节奏?
    可以 完全没问题

3.3.4.主从配置的三种策略:

薪火相传:
80跟随79 81 跟随80
中途变更跟随者 会清楚之前的数据 重新建立连接 重新回去数据 同步
凡客为主(容灾处理):
master出现故障,此时手动的将一台slave 提升为master 剩下的slave挂载到新的master上
在这里插入图片描述

3.4.主从复制原理

在这里插入图片描述

3.4.1.全量同步

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:

-  从服务器连接主服务器,发送SYNC命令; 
-  主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令; 
-  主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
-  从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
-  主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
-  从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

在这里插入图片描述

3.4.2.增量同步

Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令

但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

3.5.哨兵模式

**哨兵模式:**反客为主的自动版 当主机宕机或故障之后 不再手动的来提升slave为master 而是 采用一种自动机制 监视机制 监视 master 是否故障或宕机 是否能够于master建立正常连接。 如果检测到不能连接到master 此时 就会通过投票选举机制 来在slave中来选举出新的master

将之前的临时的master slave 改为永久 采用配置方式
(配从不配主,只改80和81)
在这里插入图片描述
在这里插入图片描述
复制配置文件(将redis5下的哨兵配置文件复制三份到自己的配置目录下)
在这里插入图片描述
配置 绑定的ip地址
在这里插入图片描述
哨兵的运行端口
在这里插入图片描述
配置启动模式
在这里插入图片描述
pid文件名称
在这里插入图片描述
log文件名称

在这里插入图片描述
配置监控

在这里插入图片描述
启动服务

在这里插入图片描述
启动哨兵

在这里插入图片描述
关闭79master
等待一段时间 选举出了新的master 81
在这里插入图片描述

  1. 当原来的master 79重新开工 此时79重新回到master还是做一个slave?
    79重启之后 当回归之后 此时的79就是slave 选举产生的master81 不会变更

主从复制的问题:

主从复制 会存在延时的问题
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

四、常见配置redis.conf介绍

参数说明
redis.conf 配置项说明如下:
1). Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

  daemonize no

2). 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

 pidfile /var/run/redis.pid

3). 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字

  port 6379

4). 绑定的主机地址

  bind 127.0.0.1

5).当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

  timeout 300

6). 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

  loglevel verbose

7). 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null

  logfile stdout

8). 设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id

  databases 16

9). 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

  save <seconds> <changes>

Redis默认配置文件中提供了三个条件:

save 900 1
  save 300 10
  save 60 10000

分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
10). 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大

  rdbcompression yes

11). 指定本地数据库文件名,默认值为dump.rdb

  dbfilename dump.rdb

12). 指定本地数据库存放目录

  dir ./

13). 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步

  slaveof <masterip> <masterport>

14). 当master服务设置了密码保护时,slav服务连接master的密码

  masterauth <master-password>

15). 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH 命令提供密码,默认关闭

  requirepass foobared

16). 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

  maxclients 128

17). 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区

  maxmemory <bytes>

18). 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
appendonly no

19). 指定更新日志文件名,默认为appendonly.aof

   appendfilename appendonly.aof

20). 指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)

  appendfsync everysec

21). 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)
vm-enabled no

22). 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享

   vm-swap-file /tmp/redis.swap

23). 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0

   vm-max-memory 0

24). Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值

   vm-page-size 32

25). 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。

   vm-pages 134217728

26). 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4

   vm-max-threads 4

27). 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

  glueoutputbuf yes

28). 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法

  hash-max-zipmap-entries 64
  hash-max-zipmap-value 512

29). 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)

  activerehashing yes

30). 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件

 include /path/to/local.conf
发布了67 篇原创文章 · 获赞 6 · 访问量 1911

猜你喜欢

转载自blog.csdn.net/weixin_45801537/article/details/104952759
今日推荐