redis入门笔记 3

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: redis入门笔记

Redis持久化之AOF

AOF(Append Only File)以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

1.AOF持久化流程

(1)客户端的请求写命令会被append追加到AOF缓冲区内;


(2)AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;


(3)AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;

(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;

2.配置

AOF默认不开启,可以在redis.conf中配置文件名称,默认为 appendonly.aof。AOF文件的保存路径,同RDB的路径一致


AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)

3.AOF启动/修复/恢复

AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

  • 正常恢复
    修改默认的appendonly no,改为yes
    将有数据的aof文件复制一份保存到对应目录(查看目录:config get dir)
    恢复:重启redis然后重新加载
  • 异常恢复
    修改默认的appendonly no,改为yes
    如遇到AOF文件损坏,通过/usr/local/bin/redis-check-aof--fix appendonly.aof进行恢复
    备份被写坏的AOF文件
    恢复:重启redis,然后重新加载
AOF同步频率设置

appendfsync always

始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好

appendfsync everysec

每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。

appendfsync no

redis不主动进行同步,把同步时机交给操作系统。

4.Rewrite压缩
(1)是什么:

AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制, 当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。

(2)重写原理,如何实现重写

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),redis4.0版本后的重写,是指上就是把rdb 的快照,以二级制

的形式附在新的aof头部,作为已有的历史数据,替换掉原来的流水账操作。


no-appendfsync-on-rewrite:


如果 no-appendfsync-on-rewrite=yes ,不写入aof文件只写入缓存,用户请求不会阻塞,但是在这段时间如果宕机会丢失这段时间的缓存数据。(降低数据安全性,提高性能)

如果 no-appendfsync-on-rewrite=no, 还是会把数据往磁盘里刷,但是遇到重写操作,可能会发生阻塞。(数据安全,但是性能降低)


触发机制,何时重写:


Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。

Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。


重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。


auto-aof-rewrite-percentage:设置重写的基准值,文件达到100%时开始重写(文件是原来重写后文件的2倍时触发)


auto-aof-rewrite-min-size:设置重写的基准值,最小文件64MB。达到这个值开始重写。


例如:文件达到70MB开始重写,降到50MB,下次什么时候开始重写?100MB


系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为base_size,


如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。

(3)重写流程

(1)bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。

(2)主进程fork出子进程执行重写操作,保证主进程不会阻塞。


(3)子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。


(4)


1).子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。


2).主进程把aof_rewrite_buf中的数据写入到新的AOF文件。


(5)使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

ac7d30d29d864ff1bc40c279f6d0a657.png

5.优势

  • 备份机制更稳健,丢失数据概率更低。
  • 可读的日志文本,通过操作AOF稳健,可以处理误操作。

6.劣势

比起RDB占用更多的磁盘空间。

恢复备份速度要慢。

每次读写都同步的话,有一定的性能压力。

存在个别Bug,造成恢复不能。

7.总结

RDB和AOF用哪个好

官方推荐两个都启用。

如果对数据不敏感,可以选单独用RDB。

不建议单独用 AOF,因为可能会出现Bug。

如果只是做纯内存缓存,可以都不用。

官网建议:

RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储

AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.

Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大


只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.


同时开启两种持久化方式


在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据, 因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.


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


建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份), 快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。


性能建议


因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。


如果使用AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。


代价,一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。


只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。


默认超过原大小100%大小时重写可以改到适当的数值。

Redis_主从复制

主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

1.作用
  • 读写分离,性能扩展
  • 容灾快速恢复

2.搭建
  • 复制多个redis.conf配置文件,分别修改其中如下参数:
# xxx 表示每一个redis实例的配置都不相同
port xxx   
protected-mode no
daemonize yes
pidfile /var/run/redis_xxx.pid
dbfilename dumpxxx.rdb
  • 分别启动每个redis实例

为了操作简单,我本地使用单台服务器,通过不同端口号启动3个redis进程

  • 使用info replication查看redis状态

这时每个redis进程都是主节点,3个redis没有任何关系

  • 使用slaveof redis主节点IP redis主节点端口号将当前redis作为对应redis的从节点

  • 使用info replication再查看redis状态,确认集群建立成功

3.特点

这种主从复制集群不能自动进行主从切换(主节点挂掉后,从节点不能变成主节点)。

从节点只能读,不能写。

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。


中途变更转向:会清除之前的数据,重新建立拷贝最新的


风险是一旦某个slave宕机,后面的slave都没法备份


主机挂了,从机还是从机,无法写数据了


当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。


用 slaveof no one 将从机变为主机

4.复制原理
  1. Slave启动成功连接到master后会发送一个sync命令
  2. Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
  1. 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  2. 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
  3. 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

哨兵模式(sentinel)

还有哨兵集群模式,解决单个哨兵挂掉的问题。

能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。


1.搭建

1). 参考主从复制章节搭建redis主从复制集群。

2). 新建sentinel.conf文件,名字绝不能错。

文件内容如下(其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量。 )

sentinel monitor mymaster 127.0.0.1 6379 1

3). 执行redis-sentinel sentinel.conf路径

2.复制延时

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


Redis集群

1.搭建

如果redis之前已经有数据,需要删除原来的rdb文件

修改每个redis.conf关于集群配置的参数

xxx 表示每一个redis实例的配置都不相同

port xxx

protected-mode no

daemonize yes

pidfile /var/run/redis_xxx.pid

dbfilename dumpxxx.rdb

cluster-enabled yes #打开集群模式

cluster-config-file nodes-xxx.conf #设定节点配置文件名

cluster-node-timeout 15000 #设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换。

  • 启动各个redis


  • 组合成集群
redis-cli --cluster create --cluster-replicas 1  127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385
# --cluster-replicas 1  表示1个主对应1个从

2a3763e4ff7d432c9ad850e5b4c0a285.png

2.操作

在redis-cli每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。

redis-cli客户端提供了 –c 参数实现自动重定向。

如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。

不在一个slot下的键值,是不能使用mget,mset等多键操作。

可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去。

查询集群中的值:

CLUSTER GETKEYSINSLOT 返回 count 个 slot 槽中的键。

3.集群扩容
  1. 新创建一个redis服务
  • 按照第1步搭建中的方法新创建一个redis.conf的配置文件。

我这里将这个文件命名为redis7.conf

  • 启动redis服务。

对应我这里就是redis-server redis7.conf;我们这里新建的节点是127.0.0.1:6386

  1. 将新建的节点加入到原来的集群中
#redis-cli --cluster add-node 新创建的redis服务ip:port  原redis集群中服务中任意一个ip:port
redis-cli --cluster add-node 127.0.0.1:6386 127.0.0.1:6380

6a0e4d31e78f4279b3c2b379d035637c.png

重新分派槽号

  • 新加入集群的节点默认是没有分配槽号的,也就是不会存放数据。
    可以使用redis-cli --cluster check 集群中服务任意一个ip:port查看

c2177e494a0542278013078baf1d37ca.png

分配槽号

使用redis-cli --cluster reshard 集群中服务任意一个ip:port命令重新分配槽号

0762bd01af3f4745b4e4d909f9338051.png

22ebcc49704140bba4180f2faaa37b1e.png

  • 查看结果

  1. 从新加入的主节点添加从节点
  • 继续按照第1步搭建中的方法新创建一个redis.conf的配置文件。

我这里将这个文件命名为redis8.conf

  • 启动redis服务,将这个服务作为我们的要加入的从节点。

对应我这里就是redis-server redis8.conf; 节点是127.0.0.1:6387

  • 执行命令添加从节点
#redis-cli --cluster add-node 上一步新建的要作为从节点的ip:port     集群中任意一个节点ip:port   --cluster-slave --cluster-master-id 新主机节点ID
#在我这里:
#上一步新建的要作为从节点的ip:port  我这里新建的节点的ip:port   127.0.0.1:6387
#集群中任意一个节点ip:port    我这里输入的是127.0.0.1:6386
#新主机节点ID   就是127.0.0.1:6386的ID  这里551981f8a318875d5b4c0a024857b1e532a1e29e

c1f455d3d9e044f6b736a2f86ae17f2c.png

  • 进行确认

4.集群缩容

这里我们删除在上面添加的集群中的127.0.0.1:6386(主节点),127.0.0.1:6387(从节点)这两个节点

删除节点的命令如下:

#redis-cli --cluster del-node 集群中任一节点ip:port  要删除的节点id
redis-cli --cluster del-node 127.0.0.1:6387  551981f8a318875d5b4c0a024857b1e532a1e29e

由于主节点上分配了槽,所以这里不能直接删除主节点,

但是可以直接删除从节点。

现在来移除主节点:

1.首先执行reshard,将当前要移除的节点的槽迁移到其他主节点上去。

后面会有一步确认,直接输入yes就会进行迁移操作了。

2.下面我们确认下当前要删除的节点已经没有分配到槽,然后删除主节点就OK了。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
NoSQL Java 关系型数据库
【Redis系列笔记】分布式锁
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
130 2
|
3天前
|
NoSQL 关系型数据库 MySQL
redis 入门01
redis 入门01
14 0
|
3天前
|
存储 NoSQL Redis
【Redis系列笔记】Redis总结
Redis是一个基于内存的 key-value 结构数据库。 Redis 是互联网技术领域使用最为广泛的存储中间件。 Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。 它存储的value类型比较丰富,也被称为结构化的NoSql数据库。
68 0
|
3天前
|
缓存 NoSQL Java
【Redis系列笔记】Redis入门
本文介绍了Redis常用命令,以及SpringBoot集成Spring Data Redis和Spring Cache。Spring Data Redis 提供了对 Redis 的操作方法,而 Spring Cache 则提供了基于注解的缓存功能,可以方便地将方法的返回值缓存到 Redis 中,以提高性能和减少对数据源的访问次数。这样的集成可以帮助开发者更便捷地利用 Redis 来管理应用程序的数据和缓存。
94 4
|
3天前
|
存储 缓存 NoSQL
Redis笔记 | 青训营
Redis笔记 | 青训营
|
3天前
|
缓存 NoSQL Java
【Redis系列笔记】Redis事务
Redis事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
68 3
|
3天前
|
缓存 NoSQL 算法
【Redis系列笔记】内存淘汰及过期删除
Redis是一个内存键值对数据库,所以对于内存的管理尤为重要。Redis内部对于内存的管理主要包含两个方向,过期删除策略和数据淘汰策略。内存淘汰策略指在Redis内存使用达到一定阈值的时候,执行某种策略释放内存空间,以便于接收新的数据。数据过期删除策略是指在数据的有效时间到期后,如何从内存中删除这些数据的规则。
47 0
|
3天前
|
存储 缓存 NoSQL
Redis入门到通关之Redis内存淘汰(内存过期)策略
Redis入门到通关之Redis内存淘汰(内存过期)策略
32 3
|
3天前
|
存储 NoSQL Linux
Redis入门到通关之多路复用详解
Redis入门到通关之多路复用详解
21 1
|
3天前
|
存储 NoSQL Linux
Redis入门到通关之Redis5种网络模型详解
Redis入门到通关之Redis5种网络模型详解
32 1