【Redis】String字符串类型-内部编码使用场景

文章目录

  • 内部编码
  • 使用场景
    • 缓存功能
    • 计数功能
    • 共享会话
    • 手机验证码

内部编码

字符串类型的内部编码有3种:

  • int:8个字节(64位)的⻓整型,存储整数
  • embstr:压缩字符串,适用于表示较短的字符串
  • raw:普通字符串,适用于表示更长的字符串,内部是一个char类型的数组

image-20231025212919229

Redis会根据当前值的类型和⻓度动态决定使⽤哪种内部编码实现


使用场景

缓存功能

Redis作为缓冲层,MySQL作为存储层,绝⼤部分请求的数据都是从Redis中获取。由于Redis具有⽀撑⾼并发的特性,所以缓存通常能起到加速读写和降低后端压⼒的作⽤

image-20231021104656937

整体的思路:应用服务器访问数据的时候,先查询redis服务器,如果redis服务器上数据存在,那么就直接从redis当中取出数据交给应用服务器,不继续访问数据库

如果redis服务器上数据不存在,那么再读取MySQL,将读取到的结果范围给应用服务器,同时将这个查询到的数据写入到redis当中

伪代码模拟业务数据访问过程

1)假设业务是根据⽤⼾uid获取⽤⼾信息

UserInfo getUserInfo(long uid) {
	...
}

2)⾸先从Redis获取⽤⼾信息,我们假设⽤⼾信息保存在user:info:<uid>对应的键中

// 根据 uid 得到 Redis 的键
String key = "user:info:" + uid;
// 尝试从 Redis 中获取对应的值
String value = Redis 执⾏命令:get key;
// 如果缓存命中(hit)
if (value != null) {
    // 假设我们的⽤⼾信息按照 JSON 格式存储
    UserInfo userInfo = JSON 反序列化(value);
    return userInfo;
}

3)如果没有从Redis中得到⽤⼾信息,及缓存miss,则进⼀步从MySQL中获取对应的信息,随后写⼊缓存并返回

// 如果缓存未命中(miss)
if (value == null) {
    // 从数据库中,根据 uid 获取⽤⼾信息
    UserInfo userInfo = MySQL 执⾏ SQL:select * from user_info where uid = <uid>
        // 如果表中没有 uid 对应的⽤⼾信息
        if (userInfo == null) {
            响应 404
            return null;
        }
    // 将⽤⼾信息序列化成 JSON 格式
    String value = JSON 序列化(userInfo);
    // 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)
    Redis 执⾏命令:set key value ex 3600
    // 返回⽤⼾信息
    return userInfo;
}

通过增加缓存功能,极⼤地提升了查询效率,也降低了MySQL的访问数


注意:与MySQL等关系型数据库不同的是,Redis没有表、字段这种命名空间,⽽且也没有对键名有强制要求(除了不能使⽤⼀些特殊字符)。但设计合理的键名,有利于防⽌键冲突和项⽬的可维护性

  • 推荐的⽅式是使⽤业务名:对象名:唯⼀标识:属性作为键名
  • MySQL的数据库名为vs,⽤⼾表名为user_info,那么对应的键可以使⽤vs:user_info:6379vs:user_info:6379:name来表⽰

如果当前Redis只会被⼀个业务使⽤,可以省略业务名"vs:"。如果键名过长,则可以使⽤团队内部都认同的缩写替代,例如"user:6379:friends:messages:5217"可以被"u:6379:fr:m:5217"代替。毕竟键名过⻓,还是会导致Redis的性能明显下降的。


计数功能

许多应⽤都会使⽤Redis作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源,例如视频⽹站的视频播放次数可以使⽤Redis来完成:⽤⼾每播放⼀次视频,相应的视频播放数就会⾃增1

image-20231021110109878
  • 注意:写入统计数据仓库的步骤是异步的,并不是说来一个播放请求就必须马上写一个数据,二者并不需要同时完成,只需要最后保证数据正确即可

要开发⼀个成熟、稳定的真实计数系统,要⾯临的挑战远不⽌如此简单:防作弊(防止别人刷播放量),按照不同维度计数、避免单点问题、数据持久化到底层数据源等


共享会话

回顾

cookie:浏览器存储数据的机制 session:服务器这边存储数据的机制

会话:客户端和服务器在交互的过程当中产生的一些专属于该客户端的中间状态的数据


⼀个分布式Web服务将⽤⼾的Session信息(例如⽤⼾登录信息)保存在各⾃的服务器中,但这样会造成⼀个问题:出于负载均衡的考虑,分布式服务会将⽤⼾的访问请求均衡到不同的服务器上,并且通常⽆法保证⽤⼾每次请求都会被均衡到同⼀台服务器上,这样当⽤⼾刷新⼀次访问是可能会发现需要重新登录,这个问题是⽤⼾⽆法容忍的

session分散存储

image-20231021110151641

为了解决这个问题,可以使⽤Redis将⽤⼾的Session信息进⾏集中管理,如图2-13所⽰,在这种模式下,只要保证Redis是⾼可⽤和可扩展性的,⽆论⽤⼾被均衡到哪台Web服务器上,都集中从Redis中查询、更新Session信息

image-20231021110215469

手机验证码

很多应⽤出于安全考虑,会在每次进⾏登录时,让⽤⼾输⼊⼿机号并且配合给⼿机发送验证码,然后让⽤⼾再次输⼊收到的验证码并进⾏验证,从⽽确定是否是⽤⼾本⼈。为了短信接⼝不会频繁访问,会限制⽤⼾每分钟获取验证码的频率,例如⼀分钟不能超过?5?次

image-20231021110251669

伪代码实现上述功能

String 发送验证码(phoneNumber) {
    key = "shortMsg:limit:" + phoneNumber;
    // 设置过期时间为 1 分钟(60 秒)
    // 使⽤ NX,只在不存在 key 时才能设置成功
    bool r = Redis 执⾏命令:set key 1 ex 60 nx
        if (r == false) {
            // 说明之前设置过该⼿机的验证码了
            long c = Redis 执⾏命令:incr key
                if (c > 5) {
                    // 说明超过了⼀分钟 5 次的限制了
                    // 限制发送
                    return null;
                }
        }
    // 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次
    String validationCode = ⽣成随机的 6 位数的验证码();
    validationKey = "validation:" + phoneNumber;
    // 验证码 5 分钟(300 秒)内有效
    Redis 执⾏命令:set validationKey validationCode ex 300;
    // 返回验证码,随后通过⼿机短信发送给⽤⼾
    return validationCode ;
}

// 验证⽤⼾输⼊的验证码是否正确
bool 验证验证码(phoneNumber, validationCode) {
    validationKey = "validation:" + phoneNumber;
    String value = Redis 执⾏命令:get validationKey;
    if (value == null) {
        // 说明没有这个⼿机的验证码记录,验证失败
        return false;
    }
    if (value == validationCode) {
        return true;
    } else {
        return false;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言初学者周冲刺计划】2.4求一个3×3矩阵对角线元素之和

1解题思路&#xff1a; 首先学会怎么输入3*3矩阵的数值&#xff1b;然后细节处&#xff0c;比如最后求和应该加什么&#xff0c;怎么写问题&#xff1b; 2代码&#xff1a; #include<stdio.h> int main() {int str[3][3],i,j,sum0;for(i0;i<3;i){for(j0;j<3;j){…

农业中的机器学习

机器学习训练模型推荐&#xff1a; UnrealSynth虚幻合成数据生成器 - NSDT 机器学习是一个不断发展的领域&#xff0c;在农业中有许多潜在的应用。农民和农业科学家正在探索如何转向机器学习开发来提高作物产量、减少用水量和预测病虫害。未来&#xff0c;机器学习可以帮助农民…

Linux编辑器-vim使用

vi/vim的区别简单点来说&#xff0c;它们都是多模式编辑器&#xff0c;不同的是vim是vi的升级版本&#xff0c;它不仅兼容vi的所有指令&#xff0c;而且还有一些新的特性在里面。例如语法加亮&#xff0c;可视化操作不仅可以在终端运行&#xff0c;也可以运行于x window、 mac …

逆袭Flutter? Facebook 发布全新跨平台引擎 Hermes!

Facebook 于前日发布了新的 JavaScript 引擎&#xff1a;Hermes&#xff0c;专注于提高 React Native 应用的性能&#xff0c;并且在市面上那些内存较少、存储速度较慢且计算能力低下的移动设备上都有良好的表现。但是不是为了追赶Flutter&#xff1f;这块作者没有说明。 移动应…

java 数据结构 ArrayList源码底层 LinkedList 底层源码 迭代器底层

文章目录 数据结构总结ArrayList源码底层LinkedList底层源码 迭代器底层 数据结构 对于数据结构我这边只告诉你右边框框里的 栈的特点:后进先出,先进后出,入栈也成为压栈,出栈也成为弹栈 栈就像一个弹夹 队列先进先出后进后出 队列像排队 链表查询满 但是增删快(相对于数组而…

【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队

在云原生领域&#xff0c;无论使用哪种编排调度平台&#xff0c;Kubernetes&#xff0c;DockerSwarm&#xff0c;OpenShift等&#xff0c;业务都需要基于镜像进行交付&#xff0c;我们在内部实践“Source-to-image”和链式构建&#xff0c;总而总结出“OneBuild”模式。 其核心…

[JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、过滤器filter 概念介绍&#xff1a; 过滤器的使用&#xff1a; 过滤器的执行流程&#xff1a; 应用场景(登录校验)&#xff1a; 二、拦截器Interceptor 概念介绍&#xff1a; 拦截器的使用&#xff1…

ios原生分享

什么是 ios 系统的原生分享呢&#xff0c;如下图所示 具体使用系统UIActivityViewController&#xff0c;完整代码如下&#xff1a; -(void)shareAny:(NSString *)text url:(NSString *)_url imagePath:(NSString *)_imagePath {NSLog("shareAny, text:%, url:%, imagePa…

FRI及相关SNARKs的Fiat-Shamir安全

1. 引言 本文主要参考&#xff1a; Alexander R. Block 2023年论文 Fiat-Shamir Security of FRI and Related SNARKsAlbert Garreta 2023年9月在ZK Summit 10上分享 ZK10: Fiat-Shamir security of FRI and related SNARKs - Albert Garreta (Nethermind) 评估参数用的Sage…

甲方自建ERP这事靠不靠谱?来听听读过中欧商学院的老板怎么说

李总自建ERP开发团队的失败案例&#xff0c;投入三年&#xff0c;花了五六百万&#xff0c;做出来的东西&#xff0c;远不如免费开源的Odoo软件。Odoo有强大的技术平台&#xff0c;有无穷的功能插件。李总现身说法&#xff1a;“早知道有Odoo&#xff0c;何必瞎折腾&#xff0c…

SAP IDOC 开发入门

1, 基本概念 IDOC技术在早起版本的R/3系统就已经集成了&#xff0c;不过国内真正用起来还是05年以后了&#xff0c;其实IDOC是很强大的&#xff0c;在主数据和一些业务数据同步方面&#xff0c;几乎不需要做任何开发就可以配置完成&#xff0c;例如BD11&#xff0c;BD13这些事…

3 Spring底层概念介绍

BeanDefinition BeanDefinition表示Bean定义&#xff0c;BeanDefinition中存在很多属性用来描述一个Bean的特点。比如&#xff1a; class&#xff0c;表示Bean类型 scope&#xff0c;表示Bean作用域&#xff0c;单例或原型等 lazyInit&#xff1a;表示Bean是否是懒加载 initM…

2.Docker基本架构简介与安装实战

1.认识Docker的基本架构 下面这张图是docker官网上的&#xff0c;介绍了整个Docker的基础架构&#xff0c;我们根据这张图来学习一下docker的涉及到的一些相关概念。 1.1 Docker的架构组成 Docker架构是由Client(客户端)、Docker Host(服务端)、Registry(远程仓库)组成。 …

C语言实现 1.在一个二维数组中形成 n 阶矩阵,2.去掉靠边元素,生成新的 n-2 阶矩阵;3.求矩阵主对角线下元素之和:4.以方阵形式输出数组。

矩阵形式&#xff1a; 1 1 1 1 1 2 1 1 1 1 3 2 1 1 1 4 3 2 1 1 5 4 3 2 1 完整代码&#xff1a; /*编写以下函数 1&#xff0e;在一个二维数组中形成如以下形式的 n 阶矩阵&#xff1a; 1 1 1 1 1 2 1 1 1 1 3 2 1 1 1 4 3 2 1 1 5 4 3 2 1 2&#xff0e;去掉…

【Vue3+Vite+bwip-js库】 生成DataMatrix码

前提条件 已存在的vue3vite架构前端项目对二维码分类有一定的了解 生成的码的样式如下&#xff08;DataMatrix&#xff09; 该二维码容量如下 详情见&#xff1a;DataMatrix介绍 Vue3Vite 导入 bwip-js生成DataMatrix 1. 安装 npm install bwip-js --save2. 引入使用 <…

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用

基于STC12C5A60S2系列1T 8051单片机A/D转换器应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC12C5A60S2系列1T 8051单片机A/D转换器介绍STC12C5A60S2系列1T 805…

xlua源码分析(二)lua Call C#的无wrap实现

xlua源码分析&#xff08;二&#xff09;lua Call C#的无wrap实现 上一节我们主要分析了xlua中C# Call lua的实现思路&#xff0c;本节我们将根据Examples 03_UIEvent&#xff0c;分析lua Call C#的底层实现。例子场景里有一个简单的UI面板&#xff0c;面板中包含一个input fie…

3.线性神经网络-3GPT版

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.1 线性回归基础优化算法一、线性回归1、买房案例2、买房模型简化3、线性模型4、神经网络5、损失函数6、训练数据7、参数学习8、显示解9、总结 二、 基础优化算法1、梯度下降2、学习率3、小批量随机梯度下降4、批量大小5、…

Qt 中model/View 架构 详解,以及案例实现相薄功能

model/View 架构 导读 ​ 我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应用程序的界面中。早期的 Qt 要实现这个功能,需要定义一个组件,在这个组件中保存一个数据对象,比如一个列表。我们对这个列表进行查找、插入等的操作,或者把修改…

HNU程序设计 练习五-函数

1.小熊买糖果 【问题描述】 小熊去到商店&#xff0c;选择了一种它非常喜欢的糖果&#xff0c;其单价为 k 元&#xff0c;假定商店里有无穷多的这种糖果。 它的父亲允许它花费任意多的10元硬币和一个 r 元硬币去购买&#xff0c;但不能找零&#xff0c;请帮助小熊确定它能购买…