热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:rediskey分析

本文主要介绍关于redis,lua,数据库,java,后端的知识点,对Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本和rediskey分析有兴趣的朋友可以看下由

本文主要介绍关于redis,lua,数据库,java,后端的知识点,对Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本和redis key 分析有兴趣的朋友可以看下由【Minor王智】投稿的技术文章,希望该技术和经验能帮到你解决你所遇的Redis相关技术问题。

redis key 分析

笔记大纲 1.Redis的慢查询日志2.Pipeline流水线管道3.Redis的事务4.Lua脚本的支持5.Redis的发布订阅(鸡肋)6.Stream消息队列7.Redis的持久化7.1 RDB7.1.1 手动触发7.1.2 自动触发7.1.3 RDB文件的压缩7.1.4 RDB的优点7.1.5 RDB的缺点 7.2 AOF7.2.1 aof_buffer刷盘策略 8.键扫描和渐进式扫描8.1 keys8.2 scan

1.Redis的慢查询日志

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:redis key 分析

和MySQL一样,Redis也有相应的慢查询统计,Redis的慢查询统计的是步骤3的耗时。Redis提供了一个配置参数slowlog-log-slower-than来设置慢查询的阈值,默认是10毫秒。

2.Pipeline流水线管道

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:redis key 分析

其中1+4称为 Round Trip Time (RTT,往返时间),也就是数据在网络上传输的 时间。 Redis提供了批量操作命令(例如 mget、mset等),有效地节约 RTT。但大部分命令是不支持批量操作的,需要消耗n次RTT。
Pipeline(流水线)机制能改善上面这类问题,它能将一组Redis命令进行组装,通过一次RTT传输给Redis,再将这组Redis命令的执行结果按顺序返回给客户端,整个过程只需要1次RTT。 Pipeline并不是什么新的技术或机制,很多技术上都使用过。而且RTT在不同网络环境下会有不同,例如同机房和同机器会比较快,跨机房跨地区会比较慢。Redis 命令真正执行的时间通常在微秒级别,所以才会有Redis性能瓶颈是网络这样的说法。 Pipeline 虽然好用,但是每次Pipeline组装的命令个数不能没有节制,否则一 次组装 Pipeline数据量过大,一方面会增加客户端的等待时间,另一方面会造成 一定的网络阻塞,可以将一次包含大量命令的Pipeline拆分成多次较小的Pipeline 来完成,比如可以将Pipeline的总发送大小控制在内核输入输出缓冲区大小之内或者控制在TCP包的大小1460字节之内。 同时Pipeline只能操作一个Redis实例,但是即使在分布式Redis场景中,也可以作为批量操作的重要优化手段。

3.Redis的事务

Redis提供了简单的事务功能,将一组需要一起执行的命令放到multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务结束(开始提交),如果要停止事务的执行,可以使用discard命令代替exec命令即可。
MULTI :开启事务,redis将后续的客户端命令放入事务缓冲队列中
EXEC :真正执行事务缓冲队列中的命令
DISCARD :取消事务,丢弃缓冲队列中的命令
WATCH :监视N个key,如果在事务执行前,key的值被修改,则事务中断
UNWATCH :取消WATCH监视
但是Redis的事务是一个伪事务,它并不能保证一致性。因为他没有回滚的功能。如果事务中存在受检异常则能够保证事务性,但是如在事务执行过程中抛出运行时异常,Redis不会发生回滚。

4.Lua脚本的支持

Lua语言是在1993年由巴西一个大学研究小组发明,其设计目标是作为嵌入式程序移植到其他应用程序,它是由C语言实现的,虽然简单小巧但是功能强大,所以许多应用都选用它作为脚本语言,尤其是在游戏领域,暴雪公司的“魔兽世界”,“愤怒的小鸟”,Nginx将 Lua语言作为扩展。Redis将Lua作为脚本语言可帮助开发者定制自己的Redis命令。Redis2.6版本通过内嵌支持Lua环境。也就是说一般的运用,是不需要单独安装Lua的。
在Redis使用Lua脚本的好处包括:
1、减少网络开销,在Lua脚本中可以把多个命令放在同一个脚本中运行;
2、原子操作,Redis会将整个脚本作为一个整体执行,中间不会被其它 命令插入,编写脚本的过程中无 需担心会出现竞态条件;
3、复用性,客户端发送的脚本会存储在Redis中,这意味着其他客户端可以复用这一脚本来完成同样的 逻辑
但是eval命令要求你在每次执行脚本的时候都发送一次脚本,所以 Redis有一个内部的缓存机制,因此它不会每次都重新编译脚本,为了减少带宽的消耗,Redis提供了evalsha命令,它的作用和EVAL一样,都用于对脚本求值,但它接受的第一个参数不是脚本,而是脚本的SHA1摘要。

5.Redis的发布订阅(鸡肋) 6.Stream消息队列

Redis提供了基于“发布/订阅”模式的消息机制,此种模式下,消息发布者和订阅者不进行直接通信,发布者客户端向指定的频道(channel)发布消息,订阅该频道的每个客户端都可以收到该消息。对应命令publish cnannel msg和subscribe channel [channel …],但是Redis原生的发布订阅机制太过简陋,不适用于业务领域开发,随后诞生了Stream。 Redis5.0最大的新特性就是多出了一个数据结构Stream,它是一个新的强大的 支持多播的可持久化的消息队列,作者声明Stream借鉴了Kafka的设计。 Stream的消费模型借鉴了Kafka的消费分组的概念,它弥补了Redis的Pub/Sub不能持久化消息的缺陷。但是它又不同于kafka,Kafka的消息可以分partition,而 Stream不行。如果非要分parition的话,得在客户端做,提供不 同的Stream名称,对消息进行hash取模来选择往哪个Stream里放数据。

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:redis key 分析

7.Redis的持久化

Redis 虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。

7.1 RDB

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

7.1.1 手动触发

save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
bgsave命令:Redis进程执行fork()函数创建子进程,RDB持久化过程由子进程 负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。显然bgsave命令是针对save阻塞问题做的优化。因此Redis内部所有的涉及RDB 的操作都采用bgsave的方式。

7.1.2 自动触发

1、使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
2、如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。
3、执行debug reload命令重新加载Redis时,也会自动触发save操作。
4、默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行 bgsave。

7.1.3 RDB文件的压缩

Redis默认采用LZF算法对生成的RDB 文件做压缩处理,压缩后的文件远远小于内存大小,默认开启。虽然压缩RDB会消耗 CPU,但可大幅降低文件的体积,方便保存到硬盘或通过网络络发送给从节点,因此线上建议开启。如果 Redis 加载损坏的RDB文件时拒绝启动。

7.1.4 RDB的优点

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

7.1.5 RDB的缺点

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

7.2 AOF

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:redis key 分析

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。开启AOF功能需要设置配置:appendonly yes,默认不开启。
Redis使用单线程响应命令,如果每次写AOF文件命令都直接追加到硬盘,那么性能完全取决于当前硬盘负载。先写入缓冲区aof_buf中,还有另一个好处,Redis可以提供多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡。Redis提供了多种AOF缓冲区同步文件策略,由参数appendfsync控制。
AOF的覆写:通过对日志文件的整理和指令合并用来减少AOF文件的大小的一种策略。

7.2.1 aof_buffer刷盘策略

1、always:命令写人aof_buf后调用系统fsync()操作同步到AOF文件, fsync完成后线程返回命令fsync同步文件。
2、everysec:写人aof_buf后调用系统write()操作,write完成后线程返回。刷盘操作由专门线程每秒调用一次fsync命令。(建议配置)
3、no:写入aof_buf后调用系统write()操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责。write操作会触发延迟写(delayed write)机制。Linux在内核提供页缓冲区用来提高硬盘IO性能。write操作在写入系统缓冲区后直接返回。同步硬盘操作依赖 于系统调度机制,例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。fsync 针对单个文件操作,做强制刷盘,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化。

Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本:redis key 分析

8.键扫描和渐进式扫描 8.1 keys

用来全量遍历键,用法很简单keys pattern遍历所有的键, pattern直接使用星号即可,pattern 使用的是 glob 风格的通配符:代表匹配任意字符。
?代表匹配一个字符。
[]代表匹配部分字符,例如[1,3]代表匹配 1,3。
\用来做转义,例如要匹配星号、问号需要进行转义。
例如,查询key名称是uis开头的键集合:keys uis

但是如果考虑到Redis的单线程架构就不那么美妙了,如果Redis包含了大量的键,执行 keys命令很可能会造成Redis阻塞,所以一般建议不要在生产环境下使用keys命令。但有时候确实有遍历键的需求该怎么办,可以在以下三种情况使用: 1、在一个不对外提供服务的Redis从节点上执行,这样不会阻塞到客户端的请 求,但是会影响到主从复制。 2、如果确认键值总数确实比较少,可以执行该命令。 3、使用scan命令渐进式的遍历所有键,可以有效防止阻塞。

8.2 scan

Redis从2.8版本后,提供了一个新的命令scan,它能有效的解决keys命令存在的阻塞问题。和keys命令执行时会遍历所有键不同,scan采用渐进式遍历的方式来解决keys命令可能带来的阻塞问题,但是要真正实现keys的功能,需要执行多次scan。可以想象成只扫描一个字典中的一部分键,直到将字典中的所有键遍历完毕。
渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是 scan 并非 完美无瑕,如果在 scan 的过程中如果有键的变化(增加、删除、修改),那么遍 历效果可能会碰到如下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们在开发时需要考虑的。

本文《Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本》版权归Minor王智所有,引用Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本需遵循CC 4.0 BY-SA版权协议。


推荐阅读
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 深入理解Redis中的字典实现
    本文详细介绍了Redis中字典的实现机制,包括其底层数据结构、哈希表与哈希节点的关系、元素添加方法及rehash操作的具体流程。 ... [详细]
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Python错误重试让多少开发者头疼?高效解决方案出炉
    ### 优化后的摘要在处理 Python 开发中的错误重试问题时,许多开发者常常感到困扰。为了应对这一挑战,`tenacity` 库提供了一种高效的解决方案。首先,通过 `pip install tenacity` 安装该库。使用时,可以通过简单的规则配置重试策略。例如,可以设置多个重试条件,使用 `|`(或)和 `&`(与)操作符组合不同的参数,从而实现灵活的错误重试机制。此外,`tenacity` 还支持自定义等待时间、重试次数和异常处理,为开发者提供了强大的工具来提高代码的健壮性和可靠性。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • B站服务器故障影响豆瓣评分?别担心,阿里巴巴架构师分享预防策略与技术方案
    13日晚上,在视频观看高峰时段,B站出现了服务器故障,引发网友在各大平台上的广泛吐槽。这一事件导致了连锁反应,大量用户纷纷涌入A站、豆瓣和晋江等平台,给这些网站带来了突如其来的流量压力。为了防止类似问题的发生,阿里巴巴架构师分享了一系列预防策略和技术方案,包括负载均衡、弹性伸缩和容灾备份等措施,以确保系统的稳定性和可靠性。 ... [详细]
author-avatar
洪凤兴惠婷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有