Redis 6.0的新特性:多线程、客户端缓存与安全

2020年5月份,6.0版本。

面向网络处理的多IO线程可以提高网络请求处理的速度,而客户端缓存可以让应用直接在客户端本地读取数据,这两个特性可以提升Redis的性能。

细粒度权限控制让Redis可以按照命令粒度控制不同用户的访问权限,加强了Redis的安全保护。

RESP 3协议则增强客户端的功能,可以让应用更加方便地使用Redis的不同数据类型。

1 从单线程处理网络请求到多线程处理

Redis单线程架构,虽有些命令操作可用后台线程或子进程执行(如数据删除、快照生成、AOF重写),但从网络IO处理到实际的读写命令处理,都是由单线程完成。

随着网络硬件的性能提升,Redis性能瓶颈有时会出现在网络I/O处理,即单个主线程处理网络请求的速度跟不上底层网络硬件的速度。
一般有两种方法:

  • 用用户态网络协议栈(例如DPDK)取代内核网络协议栈,让网络请求的处理不用在内核里执行,直接在用户态完成处理就行。
    让Redis避免频繁让内核进行网络请求处理,可很好地提升请求处理效率。但这个方法要求在Redis的整体架构中,添加对用户态网络协议栈的支持,需修改Redis源码中和网络相关的部分(例如修改所有的网络收发请求函数),这会带来很多开发工作量。而且新增代码还可能引入新Bug,导致系统不稳定。
  • 采用多个IO线程来处理网络请求,提高网络请求处理的并行度。Redis 6.0采用
    Redis的多I/O线程只是用来处理网络请求,对于读写命令,Redis仍使用单线程处理。因为,Redis处理请求时,网络处理经常是瓶颈,通过多个I/O线程并行处理网络操作,可提升实例的整体处理性能。而继续使用单线程执行命令操作,无需为了保证Lua脚本、事务的原子性,额外开发多线程互斥机制了。这样Redis线程模型实现就简单了。

6.0中,主线程和IO线程具体是怎么协作完成请求处理的?

可将主线程和多I/O线程的协作分成如下阶段:

服务端和客户端建立Socket连接,并分配处理线程

主线程负责接收建立连接请求。当有客户端请求和实例建立Socket连接时,主线程会创建和客户端的连接,并把 Socket 放入全局等待队列中。
紧接着,主线程通过轮询方法把Socket连接分配给IO线程。

IO线程读取并解析请求

主线程一旦把Socket分配给IO线程,就会进入阻塞状态,等待IO线程完成客户端请求读取和解析。因为有多个IO线程在并行处理,所以,这个过程很快就可以完成。

主线程执行请求操作

等到IO线程解析完请求,主线程还是会以单线程的方式执行这些命令操作

IO线程回写Socket和主线程清空全局队列

当主线程执行完请求操作后,会把需要返回的结果写入缓冲区,然后,主线程会阻塞等待IO线程把这些结果回写到Socket中,并返回给客户端。

和IO线程读取和解析请求一样,IO线程回写Socket时,也是有多个线程在并发执行,所以回写Socket的速度也很快。等到IO线程回写Socket完毕,主线程会清空全局队列,等待客户端的后续请求。
该阶段主线程和IO线程的操作:

2 启用多线程

6.0多线程机制默认关闭,要启用,需在redis.conf中完成两个设置:

1.设置io-threads-do-reads=yes,表示启用多线程。

io-threads-do-reads yes

2.设置线程个数。线程个数一般小于Redis实例所在机器的CPU核数。如8核机器,Redis官方建议6个IO线程。

io-threads  6

若你在实际应用中,发现Redis实例CPU开销不大,吞吐量却没提升,可考虑使用Redis 6.0的多线程机制,加速网络处理,提升实例吞吐量。

3 实现服务端协助的客户端缓存

6.0实现了服务端协助的客户端缓存功能,也称跟踪(Tracking)功能。业务应用中的Redis客户端就能将读取的数据缓存在业务应用本地,应用就能直接在本地快速读取数据。

问题也来了,若数据被修改或失效,如何通知客户端对缓存的数据做失效处理?6.0实现的Tracking功能提供两种模式解决这问题。

3.1 普通模式

实例会在服务端记录客户端读取过的key,并监测key是否有修改。一旦key值变化,服务端会给客户端发送invalidate消息,通知客户端缓存失效

服务端对记录的key只会报告一次invalidate消息,也就是说,服务端在给客户端发送过一次invalidate消息后,如果key再被修改,此时,服务端就不会再次给客户端发送invalidate消息。

只有当客户端再次执行读命令时,服务端才会再次监测被读取的key,并在key修改时发送invalidate消息。这样设计的考虑是节省有限的内存空间。毕竟,如果客户端不再访问这个key了,而服务端仍然记录key的修改情况,就会浪费内存资源。

我们可以通过执行下面的命令,打开或关闭普通模式下的Tracking功能。

CLIENT TRACKING ON|OFF

3.2 广播模式

服务端会给客户端广播所有key的失效情况,但这样做后,若K被频繁修改,服务端会发送大量失效广播消息,消耗大量网络带宽资源。

实际应用时,会让客户端注册希望跟踪的key的前缀,当带有注册前缀的K被修改时,服务端会把失效消息广播给所有注册的客户端。和普通模式不同,在广播模式下,即使客户端还没读取过K,但只要它注册了要跟踪的K,服务端都会把K失效消息通知给这客户端。

案例 -客户端如何使用广播模式接收key失效消息

当我们在客户端执行下面的命令后,如果服务端更新了user🆔1003这个key,那么,客户端就会收到invalidate消息。

CLIENT TRACKING ON BCAST PREFIX user

这种监测带有前缀的key的广播模式,和我们对key的命名规范非常匹配。我们在实际应用时,会给同一业务下的key设置相同的业务名前缀,所以,我们就可以非常方便地使用广播模式。

普通模式和广播模式,需要客户端使用RESP 3协议,RESP 3协议是6.0新启用的通信协议。

对于使用RESP 2协议的客户端来说,就需要使用另一种模式:

重定向模式(redirect)

想获得失效消息通知的客户端,需执行订阅命令SUBSCRIBE,专门订阅用于发送失效消息的频道_redis_:invalidate。同时使用另外一个客户端,执行CLIENT TRACKING,设置服务端将失效消息转发给使用RESP 2协议的客户端。

案例

如何让使用RESP 2协议的客户端也能接受失效消息?

假设客户端B想获取失效消息,但客户端B只支持RESP 2协议,客户端A支持RESP 3协议。我们可以分别在客户端B和A上执行SUBSCRIBE和CLIENT TRACKING,如下所示:

//客户端B执行,客户端B的ID号是303
SUBSCRIBE _redis_:invalidate//客户端A执行
CLIENT TRACKING ON BCAST REDIRECT 303

这样设置以后,如果有键值对被修改了,客户端B就可以通过_redis_:invalidate频道,获得失效消息了。

4 从简单的基于密码访问到细粒度的权限控制

实例的访问权限控制列表功能(Access Control List,ACL),这个特性可以有效地提升Redis的使用安全性。

在Redis 6.0 版本之前,要想实现实例的安全访问,只能通过设置密码来控制,例如,客户端连接实例前需要输入密码。

此外,对于一些高风险的命令(例如KEYS、FLUSHDB、FLUSHALL等),在Redis 6.0 之前,我们也只能通过rename-command来重新命名这些命令,避免客户端直接调用。

Redis 6.0 提供了更加细粒度的访问权限控制,这主要有两方面的体现。

首先,6.0版本支持创建不同用户来使用Redis。在6.0版本前,所有客户端可以使用同一个密码进行登录使用,但是没有用户的概念,而在6.0中,我们可以使用ACL SETUSER命令创建用户。例如,我们可以执行下面的命令,创建并启用一个用户normaluser,把它的密码设置为“abc”:

ACL SETUSER normaluser on > abc

另外,6.0版本还支持以用户为粒度设置命令操作的访问权限。我把具体操作列在了下表中,你可以看下,其中,加号(+)和减号(-)就分别表示给用户赋予或撤销命令的调用权限。

为了便于你理解,我给你举个例子。假设我们要设置用户normaluser只能调用Hash类型的命令操作,而不能调用String类型的命令操作,我们可以执行如下命令:

ACL SETUSER normaluser +@hash -@string

除了设置某个命令或某类命令的访问控制权限,6.0版本还支持以key为粒度设置访问权限。

具体的做法是使用波浪号“~”和key的前缀来表示控制访问的key。例如,我们执行下面命令,就可以设置用户normaluser只能对以“user:”为前缀的key进行命令操作:

ACL SETUSER normaluser ~user:* +@all

好了,到这里,你了解了,Redis 6.0可以设置不同用户来访问实例,而且可以基于用户和key的粒度,设置某个用户对某些key允许或禁止执行的命令操作。

这样一来,我们在有多用户的Redis应用场景下,就可以非常方便和灵活地为不同用户设置不同级别的命令操作权限了,这对于提供安全的Redis访问非常有帮助。

5 启用RESP 3协议

Redis 6.0实现了RESP 3通信协议,而之前都是使用的RESP 2。在RESP 2中,客户端和服务器端的通信内容都是以字节数组形式进行编码的,客户端需要根据操作的命令或是数据类型自行对传输的数据进行解码,增加了客户端开发复杂度。

而RESP 3直接支持多种数据类型的区分编码,包括空值、浮点数、布尔值、有序的字典集合、无序的集合等。

所谓区分编码,就是指直接通过不同的开头字符,区分不同的数据类型,这样一来,客户端就可以直接通过判断传递消息的开头字符,来实现数据转换操作了,提升了客户端的效率。除此之外,RESP 3协议还可以支持客户端以普通模式和广播模式实现客户端缓存。

6 总结


Redis 6.0是刚刚推出的,新的功能特性还需要在实际应用中进行部署和验证,所以,如果你想试用Redis 6.0,可以尝试先在非核心业务上使用Redis 6.0:

  • 可以验证新特性带来的性能或功能优势
  • 避免因为新特性不稳定而导致核心业务受到影响

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/80110.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot如何整合mybatisplus

文章目录 1. 相关配置和代码2. 整合原理2.1 spring boot自动配置2.2 MybatisPlusAutoConfiguration2.3 debug流程2.3.1 MapperScannerRegistrar2.3.2MapperScannerConfigurer2.3.3 创建MybatisPlusAutoConfiguration2.3.4 创建sqlSessionFactory2.3.5 创建SqlSessionTemplate2.…

HTTP连接之出现400 Bad Request分析

1、400简介 400是一种HTTP状态码,告诉客户端它发送了一条异常请求。400页面是当用户在打开网页时,返回给用户界面带有400提示符的页面。其含义是你访问的页面域名不存在或者请求错误。主要分为两种。 1、语义有误,当前请求无法被服务器理解…

高抗干扰LCD液晶屏驱动芯片,低功耗的特性适用于水电气表以及工控仪表类产品

VK2C23是一个点阵式存储映射的LCD驱动器,可支持最大224点(56SEGx4COM)或者最大416点(52SEGx8COM)的LCD屏。单片机可通过I2C接口配置显示参数和读写显示数据,也可通过指令进入省电模式。其高抗干扰&#xff…

38.利用matlab解 有约束无约束的参数估计对比(matlab程序)

1.简述 1.离散型随机变量的极大似然估计法: (1) 似然函数 若X为离散型, 似然函数为 (2) 求似然函数L(θ)的最大值点 θ, 则θ就是未知参数的极大似然估计值. 2.连续型随机变量的极大似然估计法: (1) 似然函数 若 X 为连续型, 似然函数为 (2) 求似然函数L(θ)的最大值点θ, 则…

【java】【maven】【高级】MAVEN聚合继承属性等

目录 1、模块开发与设计 2、聚合 2、继承 3、属性 4、版本管理 5、资源配置 6、多环境配置 7、多环境开发配置 8、跳过测试 9、私服 前言:maven的高级使用包含分模块开发与设计、聚合、继承、属性、版本管理、资源配置、多环境配置、多环境开发配置、跳过…

MVC架构模式

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220(3)----定时器中断产生指定数量脉冲

基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220----3.定时器中断产生指定数量脉冲 概述样品申请视频教学STM32CUBEMX配置产生固定数量的PWM电机设置STSPIN220初始化主程序 概述 在步进电机控制过程中,为了实现精确的位置和速度控制,经常需要输出指定…

【Github】Uptime Kuma:自托管监控工具的完美选择

简介: Uptime Kuma 是一款强大的自托管监控工具,通过简单的部署和配置,可以帮助你监控服务器、VPS 和其他网络服务的在线状态。相比于其他类似工具,Uptime Kuma 提供更多的灵活性和自由度。本文将介绍 Uptime Kuma 的功能、如何使…

SpringBoot 依赖管理和自动配置---带你了解什么是版本仲裁

😀前言 本篇博文是关于SpringBoot 依赖管理和自动配置,希望能够帮助到您😊 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您…

Maven 打包生成Windows和Liunx启动文件

新建一个springboot项目。 1、项目结构 2、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocati…

Activiti7

文章目录 概述入门案例1.创建springboot项目pom.xml 2.获取ProcessEngine2.1 默认的方式2.2 编程方式获取2.3 表结构介绍 3.在线流程设计器 概述 官网地址&#xff1a;https://www.activiti.org/ Activiti由Alfresco软件开发&#xff0c;目前最高版本Activiti 7。是BPMN的一个…

CI/CD—Docker中深入学习

1 容器数据卷 什么是容器数据卷&#xff1a; 将应用和环境打包成一个镜像&#xff01;数据&#xff1f;如果数据都在容器中&#xff0c;那么我们容器删除&#xff0c;数据就会丢失&#xff01;需求&#xff1a;数据可以持久 化。MySQL容器删除了&#xff0c;删容器跑路&#…

从excel中提取嵌入式图片的解决方法

1 发现问题 我的excel中有浮动图片和嵌入式图片&#xff0c;但是openpyxl的_image对象只提取到了浮动图片&#xff0c;通过阅读其源码发现&#xff0c;这是因为openpyxl只解析了drawing文件导致的&#xff0c;所以确定需要自己解析 2 解决思路 1、解析出media资源 2、解析…

Ansible环境搭建,CentOS 系列操作系统搭建Ansible集群环境

Ansible是一种自动化工具&#xff0c;基于Python写的&#xff0c;原理什么的就不过多再说了&#xff0c;详情参考&#xff1a;https://www.itwk.cc/post/403.html https://blog.csdn.net/qq_34185638/article/details/131079320?spm1001.2014.3001.5502 环境准备 HOSTNAMEIP…

大后台,小前台——组合式创新加速推进产教融合

2023年8月1日&#xff0c;由成都知了汇智科技有限公司组织召开的“2023产教融合项目推进闭门研讨会”于成都市高新区软件园G8区7楼正式举行&#xff0c;本次会议基于“产业链的用人需求、资本链的回报诉求、服务链的价值要求、教育链的延伸需求”进行交流探讨&#xff0c;形成稳…

Java-认识String

目录 一、String概念及创建 1.1 String概念 1.2 String的创建 二、String常用方法 2.1 String对象的比较 2.2 字符串查找 2.3 转化 2.4 字符串替换 2.5 字符串拆分 2.6字符串的截取 2.7 其他操作方法 2.8 字符串修改 三、面试题 一、String概念及创建 1.1 String概念 Java中…

2023上半年手机及数码行业分析报告(京东销售数据分析)

2023年上半年&#xff0c;手机市场迎来复苏&#xff0c;同环比来看&#xff0c;销量销额纷纷上涨。 而数码市场中&#xff0c;各个热门品类表现不一。微单相机及智能手表同比去年呈现增长态势&#xff0c;而笔记本电脑市场则出现下滑。 基于此现状&#xff0c;鲸参谋发布了20…

Git Submodule 更新子库失败 fatal: Unable to fetch in submodule path

编辑本地目录 .git/config 文件 在 [submodule “Assets/CommonModule”] 项下 加入 fetch refs/heads/:refs/remotes/origin/

AWS Amplify 部署node版本18报错修复

Amplify env&#xff1a;Amazon Linux:2 Build Error : Specified Node 18 but GLIBC_2.27 or GLIBC_2.28 not found on build 一、原因 报错原因是因为默认情况下&#xff0c;AWS Amplify 使用 Amazon Linux:2 作为其构建镜像&#xff0c;并自带 GLIBC 2.26。不过&#xff0c;…

每天一道leetcode:剑指 Offer 04. 二维数组中的查找(中等二分查找)

今日份题目&#xff1a; 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 示…