Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【数据库】Redis进阶篇

【数据库】Redis进阶篇

作者头像
用户3467126
发布于 2019-07-03 10:29:30
发布于 2019-07-03 10:29:30
46400
代码可运行
举报
文章被收录于专栏:爱编码爱编码
运行总次数:0
代码可运行

事务

为了保证多条命令组合的原子性,Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。简单介绍Redis中事务的使用方法以及它的局限性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
127.0.0.1:6379> multi
OK
127.0.0.1:6379> sadd user:a:follow user:b
QUEUED
127.0.0.1:6379> zadd user:b:fans 1 user:a
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> sismember user:a:follow user:b
(integer) 1

Redis提供了简单的事务功能,将一组需要一起执行的命令放到multi和 exec两个命令之间。

multi命令代表事务开始。 exec命令代表事务结束。 它们之间的命令是原子顺序执行的。 它不支持事务中的回滚特性。

Lua脚本

在Redis中执行Lua脚本有两种方法:eval和evalsha。

发布订阅

Redis提供了基于“发布/订阅”模式的消息机制,此种模式下,消息发布 者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息。

1. 发布消息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
publish channel:sports "Tim won the championship"

2 2.订阅消息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
subscribe channel:sports

有关订阅命令有两点需要注意:

•客户端在执行订阅命令之后进入了订阅状态,只能接收subscribe、 psubscribe、unsubscribe、punsubscribe的四个命令。•新开启的订阅客户端,无法收到该频道之前的消息,因为Redis不会对 发布的消息进行持久化。

Redis发布订阅与成熟MQ的比较

(1)MQ支持多种消息协议,包括AMQP,MQTT,Stomp等,并且支持JMS规范,但Redis没有提供对这些协议的支持;

(2)MQ提供持久化功能,但Redis无法对消息持久化存储,一旦消息被发送,如果没有订阅者接收,那么消息就会丢失;

(3)MQ提供了消息传输保障,当客户端连接超时或事务回滚等情况发生时,消息会被重新发送给客户端,Redis没有提供消息传输保障。

总之,MQ所提供的功能远比Redis发布订阅要复杂,毕竟Redis不是专门做发布订阅的,但是如果系统中已经有了Redis,并且需要基本的发布订阅功能,就没有必要再安装MQ了,因为可能MQ提供的功能大部分都用不到,而且你可以容忍redis发布订阅的缺点的话,可以考虑用它。

持久化

Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复

RDB持久化

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持 久化过程分为手动触发和自动触发。

手动触发和自动触发操作方法参考这位大神的文章:https://www.cnblogs.com/ysocean/p/9114268.html[3]

RDB的优缺点

优点:

•RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。•Redis加载RDB恢复数据远远快于AOF的方式。

缺点:

•RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运 行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过•RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决。

AOF持久化

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。 AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

开启AOF,通过修改redis.conf配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
appendonly yes    ##默认不开启。

AOF文件名通过appendfilename配置设置,默认文件名appendonly.aof。保存路径同RDB持久化方式一致,通过dir配置指定。

AOF的工作流程如下图:

1)所有的写入命令会追加到aof_buf(缓冲区)中。

2)AOF缓冲区根据对应的策略向硬盘做同步操作。

3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。

4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

更详细的工作原理可以参考书籍【Redis开发与运维(付磊)】 或者参考这篇文章:https://redisbook.readthedocs.io/en/latest/internal/aof.html[4]

温馨提示

场景:AOF文件可能存在结尾不完整的情况,比如机器突然掉电导致AOF尾部文件命令写入不全。

解决方法:

•对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof --fix命令进行修复,修复后使用diff-u对比数据的差异,找出丢失的数据,有些可以人工修改补全。• Redis为我们提供了aof-load-truncated配置来兼容这种情况,默认开启。加载AOF时,当遇到此问题时会忽略并继续启动,同时打印如下警告日志:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 397856725 !!!
# AOF loaded anyway because aof-load-truncated is enabled

持久化的优化

Redis持久化功能一直是影响Redis性能的高发地。主要有以下方面

1. fork操作

原因:对于高流量的Redis实例OPS可达5万以上,如果fork操作耗时在秒级别将拖慢Redis几万条命令执行,对线上应用延迟影响非常明显。正常情况下fork耗时应该是每GB消耗20毫秒左右。可以在info stats统计中查latest_fork_usec指标获取最近一次fork操作耗时,单位微秒。

优化:

1)优先使用物理机或者高效支持fork操作的虚拟化技术,避免使用Xen。

2)控制Redis实例最大可用内存,fork耗时跟内存量成正比,线上建议每个Redis实例内存控制在10GB以内。

3)合理配置Linux内存分配策略,避免物理内存不足导致fork失败。

4)降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等。

2. CPU

CPU开销分析。子进程负责把进程内的数据分批写入文件,这个过程属于CPU密集操作,通常子进程对单核CPU利用率接近90%。

CPU消耗优化。Redis是CPU密集型服务,不要做绑定单核CPU操作。由于子进程非常消耗CPU,会和父进程产生单核资源竞争。

不要和其他CPU密集型服务部署在一起,造成CPU过度竞争。如果部署多个Redis实例,尽量保证同一时刻只有一个子进程执行重写工作。

3. 内存

内存消耗优化:

1)同CPU优化一样,如果部署多个Redis实例,尽量保证同一时刻只有一个子进程在工作。

2)避免在大量写入时做子进程重写操作,这样将导致父进程维护大量页副本,造成内存消耗。

4. 硬盘

优化方法如下:

a)不要和其他高硬盘负载的服务部署在一起。如:存储服务、消息队列服务等。

b)AOF重写时会消耗大量硬盘IO,可以开启配置no-appendfsync-on-rewrite,默认关闭。表示在AOF重写期间不做fsync操作。

c)当开启AOF功能的Redis用于高流量写入场景时,如果使用普通机械磁盘,写入吞吐一般在100MB/s左右,这时Redis实例的瓶颈主要在AOF同步硬盘上。

d)对于单机配置多个Redis实例的情况,可以配置不同实例分盘存储AOF文件,分摊硬盘写入压力。

注:配置no-appendfsync-on-rewrite=yes时,在极端情况下可能丢失整个AOF重写期间的数据,需要根据数据安全性决定是否配置。

5.AOF追加阻塞

当开启AOF持久化时,常用的同步硬盘的策略是everysec,用于平衡性能和数据安全性。对于这种方式,Redis使用另一条线程每秒执行fsync同步硬盘。当系统硬盘资源繁忙时,会造成Redis主线程阻塞,

阻塞流程分析:

1)主线程负责写入AOF缓冲区。

2)AOF线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间。

3)主线程负责对比上次AOF同步时间:如果距上次同步成功时间在2秒内,主线程直接返回。如果距上次同步成功时间超过2秒,主线程将会阻塞,直到同步操作完成。

优化AOF追加阻塞问题主要是优化系统硬盘负载,优化方法参考第4点。

总结

本文主要学习Redis的事务、发布订阅、以及持久化。 后续会继续学习Redis集群等方面的知识。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱编码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面试中经常被问到的 Redis 持久化与恢复
本文主要讲了 Redis 的持久化相关功能,持久化一直是影响 Redis 性能的高发地,也是面试中经常被问到的。
java思维导图
2019/05/08
7460
面试中经常被问到的 Redis 持久化与恢复
Redis笔记
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的API。是NoSQL技术之一,也被称为结构化数据库!
技术交流
2022/11/18
3920
Redis笔记
结合上篇redis持久化,本篇收收尾、唠唠嗑
1、上篇redis 持久化 url :不说全网最全面redis持久化,也敢说前10
八点半的Bruce、D
2021/08/05
3910
Redis 子进程开销监控和优化方式
Redis子进程负责AOF或者RDB文件的重写,它的运行过程主要涉及CPU、内存、硬盘三部分的消耗
码农架构
2020/12/14
8840
Redis原理—2.单机数据库的实现
Redis服务器的所有数据库都保存在redisServer.db数组中,而redisServer.dbnum保存数据库数量。客户端通过修改目标数据库指针,让它指向redisServer.db数组中不同元素来切换数据库。数据库主要由dict和expires两个字典构成:
东阳马生架构
2025/02/21
970
redis 学习(20)-- 常见的持久化开发与运维问题
Redis在执行 fsync 的时候,redis 为了保证 AOF 文件安全性,会校验上次 fsync 的时间是否大于2秒。若超过2秒,会发生阻塞。
希希里之海
2019/06/11
1K0
redis 学习(20)-- 常见的持久化开发与运维问题
Redis持久化的原理及优化
Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。
全菜工程师小辉
2019/08/16
9790
Redis高可用之持久化
redis将数据保存在内存中,一旦Redis服务器被关闭,或者运行Redis服务的主机本身被关闭的话,储存在内存里面的数据就会丢失
良月柒
2019/03/20
8620
Redis高可用之持久化
redis笔记
-单机下部署多个实例时,为了防止出现多个子进程执行重写操作,建议做隔离控制,避免CPU和IO资源竞争,要保证每个实例的AOF串行化执行。
槽痞
2020/06/23
3020
Redis居然还有比RDB和AOF更强大的持久化方式?
Redis中的数据存在内存中,如果突然宕机,那么内存中的数据将全部丢失。如果数据能从后端数据库恢复还好,如果数据只存在Redis中,那数据就全丢失了。并且如果请求量很多,MySQL服务器的压力会很大。
Java识堂
2021/02/05
6340
Redis居然还有比RDB和AOF更强大的持久化方式?
字节二面:Redis 的大 Key 对持久化有什么影响?
当应用程序向文件写入数据时,内核通常先将数据复制到内核缓冲区中,然后排入队列,然后由内核决定何时写入硬盘。
小林coding
2022/10/27
3660
字节二面:Redis 的大 Key 对持久化有什么影响?
Redis 关键知识
Redis 作为一个网络存储服务,需要独立部署,业务侧通过网络访问,这样业务服务和数据存储可以解耦。Redis是一个单线程的网络IO模型,如何做到高性能呢? 后面会详细解释。
Check King
2021/08/09
4140
Redis持久化问题定位与优化技巧
今天主要分享继Redis持久化方式RDB、AOF之后的一些常用的Redis问题定位于优化方式。
码农架构
2020/12/14
6150
Redis持久化问题定位与优化技巧
Redis持久化机制
在默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。
ma布
2024/10/30
1110
深度好文:保姆级教程彻底搞懂Redis 持久化
Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘中,那么一旦服务器进程退出,服务器中的数据库状态也会丢失,数据丢失是一种很严重的生产及故障,所以需要对 Redis 数据进行持久化。Redis 提供了如下几种不同级别的持久化方式
一个程序猿的异常
2023/07/24
1K0
深度好文:保姆级教程彻底搞懂Redis 持久化
【9k字+】第二篇:进阶:掌握 Redis 的一些进阶操作(Linux环境)
能够合理的查看,以及理解修改配置文件,能帮助我们更好的使用 Redis,下面按照 Redis 配置文件的顺序依次往下讲
BWH_Steven
2021/02/24
3370
【9k字+】第二篇:进阶:掌握 Redis 的一些进阶操作(Linux环境)
Redis数据库 专题
高性能:从内存读取数据比从硬盘读取要快很多。如果数据库中对应的数据改变之后,同步改变缓存中相应的数据即可。
Steve Wang
2022/05/10
7740
Redis数据库 专题
Redis 数据库
1.1 Redis简介 1.1.1 介绍 Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对(key-value)存储数据库。从2015年6月开始,Redis的开发由R
惨绿少年
2018/03/30
3.6K0
Redis原理篇
前面我们说通过队列的rpush和blpop可以实现消息队列(队尾进队列出),没有任何元素可以弹出的时候,连接会被阻塞。 但是基于list实现的消息队列,不支持一对多的消息分发,相当于只有一个消费者。如果要实现一对多的消息分发,怎么办?
编程之心
2021/07/14
8030
Redis原理篇
缓存数据库Redis
  1)、客户端向后端发送请求的时候,会先去缓存层查询,查询看看是否有符合的数据。   2)、如果有的话,直接返回。   3)、如果在缓存层没有查询到,才回去存储层去查询。   4)、去存储层查询叫做穿透查询,就是穿透缓存去存储层进行查询。   5)、从存储层查询出的数据回写到缓存层,方便下次查询的时候进行查询,回写的过程就是会种了。   6)、此时,返回给客户端,完成一次查询操作。   7)、缓存层还有一个熔断机制,如果存储层挂掉了,可以让客户端的请求直接打到缓存层上。   8)、不管是否获取到数据,直接进行返回,这样可以在有损的情况了,提供服务。
别先生
2020/04/01
1.6K0
缓存数据库Redis
相关推荐
面试中经常被问到的 Redis 持久化与恢复
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验