个人主页 : 个人主页
文章目录
前言
本文是作为 简单介绍 string的典型使用场景的学习笔记
string的典型使用场景
缓存功能
下图是比较典型的缓存使用场景,其中redis作为缓存层,mysql作为存储层,绝大部分请求数据从redis中获取。由于redis具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
- 用户(user):发起请求的主体
- get:HTTP请求方法,用户通过它向Web服务发起获取数据的请求
- return:返回操作,如Web服务返回给用户的响应,缓存层 或 存储层 返回给业务层的数据
- Web服务:接受用户请求,并将其转发给业务层进行处理 或 对业务层的响应进行格式化,返回给用户
- 业务层:处理具体的业务逻辑。接受Web服务的请求,并根据需要调用 存储层 或 缓存层 来获取数据
- hit:缓存命中,即缓存层中存在用户请求的数据,可以直接返回给业务层。
- miss:缓存未命中,即缓存层中不存在用户请求的数据,业务层需要去存储层查找数据
- 缓存层:存储热点数据的系统,用于加快数据访问速度,当缓存层命中时,则直接返回数据;如果缓存层未命中,则去存储层查找
- 存储层:用于持久化存储数据的系统,当缓存层未命中时,存储层负责提供用户请求的数据
- write cache:当缓存层未命中时,业务层从存储层获取数据后,将数据写入缓存层。
整体思路:应用服务器访问数据的时候,先查询redis,如果redis上数据存在,就直接从redis取数据交给应用服务器,不继续访问数据库;如果redis上的数据不存在,再读取mysql,把读取到的结果,返回给应用层服务器,同时,把这个数据也写入到redis中。
其中redis这样的缓存,经常用来存储 "热点"数据(二八原则),也就是高频被使用的数据,如我们可以把最近使用到的数据作为热点数据,存储在缓存层。
但随着时间的推移,一定会有很多的 请求数据 在redis访问不到,从而从mysql读取并写入redis中,此时redis的数据就会越来越多,怎么处理?
- 把数据写给redis的同时,给key设置一个过期时间
- redis在内存不足的时候,提供了淘汰策略
计数功能
许多应用都会使用redis作为计数的工具,他可以实现快速计数,查询存储的功能,同时数据可以异步处理。
下图是记录视频播放次数
- 用户点击播放视频,用户通过视频网站或应用界面点击播放某个视频
- 视频网站发送请求,视频网站接收到用户的播放请求后,会向redis数据库发送一个请求,以获取该视频在redis中的相关数据(如播放此时)
- redis数据库处理(一种内存数据结构存储),在redis中,每个视频都有唯一的ID(如"video":1111),redis执行 incr 命令来增加该视频ID对应的计数器值(视频播放的次数)
- 返回数据,redis处理完请求后,会将最新的播放次数等数据返回给视频网站,视频网站再将这些数据展示给用户。
- 异步方式处理,redis在更新播放次数的同时,系统会启动一个异步任务(消息队列,线程池等方式),该异步任务会将redis的播放次数同步到其它数据源
- 视频存储,视频本身数据会被存储在视频存储系统中
- 统计数据仓库,播放次数等统计数据则会被存储到统计数据仓库中,用于后续的数据分析,报表生成...
共享会话
使用redis将用户的session信息进行集中管理,这样只要保证redis是高可用和可扩展信的,无论用户均衡到哪个Web服务器上,都集中从redis中查询,更新session信息。
redis集中管理session
手机验证码
现在很多应用出于安全考虑,会在每次进行登录时,让用户输入手机号并配合给手机发送验证码,让用户再次输入收到的验证码进行验证。
为了短信接口不回频繁访问,会限制用户每分钟获取验证码的频率。列如发送验证码一分钟不能超过5次
cpp
// 发送验证码给指定电话号码
function sendCaptchaCode(phoneNumber) {
// 设置验证码的key,包含限制信息
key = "shortMsg:limit:" + phoneNumber;
// 设置key,过期时间为60秒,并且只在key不存在时设置成功(NX选项)
r = Redis.set(key, "someValue", "EX=60", "NX");
// 检查是否已经存在该key,即是否已发送过验证码
if (r == false) {
// 检查是否超过最大发送次数(例如5次)
if (C > 5) {
// 如果超过,说明一分钟 超过 5次限制了
return null;
}
}
// 增加验证码发送次数计数器
counterKey = "shortMsg:counter:" + phoneNumber;
C = Redis.incr(counterKey);
// 生成随机的6位数验证码
validationCode = generateRandom6DigitCode();
// 设置验证码的key和值,过期时间为300秒
validationKey = "validation:" + phoneNumber;
Redis.set(validationKey, validationCode, "EX=300");
// 返回验证码(实际中不会直接返回,而是通过短信发送给用户)
// 实际应调用短信发送接口
return validationCode;
}
// 验证用户输入的验证码是否正确
function verifyCaptchaCode(phoneNumber, inputCode) {
// 设置验证码的key
validationKey = "validation:" + phoneNumber;
// 从Redis中获取验证码
value = Redis.get(validationKey);
// 检查验证码是否存在
if (value == null) {
// 如果不存在,说明没有验证码记录,验证失败
return false;
}
// 比较输入的验证码和Redis中的验证码
if (value == inputCode) {
// 如果相同,验证成功
return true;
} else {
// 如果不同,验证失败
return false;
}
}
// 辅助函数:生成随机的6位数验证码
function generateRandom6DigitCode() {
// 此处为示例,实际应实现生成随机6位数验证码的逻辑
return Math.floor(100000 + Math.random() * 900000).toString();
}
总结
以上就是我是redis学习笔记