【redis】string应用场景:缓存功能和计数功能

news2025/3/13 0:51:23

文章目录

  • 缓存功能
    • 实现思路
    • 存在的问题
    • 伪代码实现
  • 记数功能
    • 实现思路
    • 统计
    • 伪代码实现

缓存功能

实现思路

image.png

整体的思路:
应用服务器访问数据的时候,先查询 Redis

  • 如果 Redis 上数据存在了,就直接从 Redis 读取数据交给应用服务器,不继续访问数据库了
  • 如果 Redis 上数据不存在,再读取 MySQL,把读到的结果,返回给应用服务器。同时,把这个数据也写入到 Redis

Redis 这样的缓存,经常用来存储“热点”数据(高频被使用的数据)

刚才上述描述的过程,相当于是把最近使用到的数据作为热点数据

  • 暗含了一层假设:某个数据一旦被用到了,那么很可能在最近这段时间就会被反复用到

存在的问题

上述策略,存在一个明显的问题:
随着时间的推移,肯定是会有越来越多的 keyRedis 上访问不到,从而从 MySQL 读取并写入 Redis 中,此时 Redis 里面的数据不就越来越多了吗?

  1. 在把数据写给 Redis 的时候,给这个 key 设置一个过期时间
  2. Redis 也在内存不足的时候,提供了“淘汰策略

伪代码实现

  1. 假设业务是根据用户 uid 获取用户信息
UserInfo getUserInfo(long uid) {
	...
}

uid 还需要拼接一些前缀:user:info

  • 因为 Redis 里面存的信息有很多种,不仅仅只有用户信息
  • 所以为了后续进行区分,例如 grade:infoadmin:info… 需要拼接一个前缀
  1. 首先从 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;
}
  1. 如果没有从 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 小时(3600s)
	Redis 执行命令: set key value ex 3600
	
	// 返回用户信息
	return userInfo;
}

记数功能

许多应⽤都会使⽤ Redis 作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。

如图下图所⽰,例如视频⽹站的视频播放次数可以使⽤ Redis 来完成:⽤⼾每播放⼀次视频,相应的视频播放数就会⾃增 1

实现思路

image.png|435

企业为什么老乐意收集用户的数据?

  • 因为统计可以进一步明确用户拒的需求,然后根据需求改进和迭代产品

统计

Redis 可以计数,但是不擅长统计

比如,想在上述的 Redis 中,统计播放量前 100 的视频有哪些

  • 基于 Redis 搞,就很麻烦
  • 相比之下,如果是 MySQL 来存储上述数据,一个 SQL 就搞定了
    所以在 Redis 计数之后,还需要将播放量同步到“统计数据仓库”中

异步的方式:这里写入统计数据仓库(MySQL/HDFS…)的步骤是异步

  • 不是说,来一个播放请求,这里就必须立马写一个数据
  • 不要求两边是同时完成的,只要最后都完成了就行

伪代码实现

// 在 Redis 中统计某视频的播放次数
long incrVideoCounter(long vid) {
	key = "video: " + vid;
	long count = Redis 执行命令: incr key
	return counter;
}

实际中要开发一个成熟、稳定的真实技术系统,要面临的挑战远不止如此简单:防作弊、按照不同维度计数、避免单点击问题、数据持久到底层数据源等等

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue el-select 省市区三级联动 vue + element-ui使用第三方插件实现省市区三级联动

vue el-select 省市区三级联动 vue使用第三方插件实现省市区三级联动 网上找了好多教程,都是使用el-cascader级联选择器的省市区选择器,但是几乎没有三个单独的el-select的进行关联的三级省市联动组件效果 第一步:先安装省市区element-ui的插件 npm install element-china-a…

数学建模:MATLAB强化学习

一、强化学习简述 强化学习是一种通过与环境交互&#xff0c;学习状态到行为的映射关系&#xff0c;以获得最大积累期望回报的方法。包含环境&#xff0c;动作和奖励三部分&#xff0c;本质是智能体通过与环境的交互&#xff0c;使得其作出的动作所得到的决策得到的总的奖励达…

从0开始的操作系统手搓教程45——实现exec

目录 建立抽象 实现加载 实现sys_execv &#xff01;&#xff01;&#xff01;提示&#xff1a;因为实现问题没有测试。所以更像是笔记&#xff01; exec 函数的作用是用新的可执行文件替换当前进程的程序体。具体来说&#xff0c;exec 会将当前正在运行的用户进程的进程体&…

STM32之硬件SPI

SPI1和SPI2挂载的总线不一样&#xff0c;SPI1的时钟频率的比SPI2的大一倍。 核心部分是移位寄存器&#xff0c;数据一位一位的移到MOSI,同理&#xff0c;移位寄存器也一位一位的从MISO接收数据&#xff0c;LSBFIRST控制位控制高位先行还是低位先行。移位寄存器左边交叉箭头是ST…

【网络协议安全】任务10:三层交换机配置

CSDN 原创主页&#xff1a;不羁https://blog.csdn.net/2303_76492156?typeblog三层交换机是指在OSI&#xff08;开放系统互连&#xff09;模型中的第三层网络层提供路由功能的交换机。它不仅具备二层交换机的交换功能&#xff0c;还能实现路由功能&#xff0c;提供更为灵活的网…

依托大数据实验室建设,培育创新人才:数据科学与大数据技术专业人才培养实践

近年来&#xff0c;得益于全球大数据产业政策扶持与数字经济蓬勃发展&#xff0c;大数据市场呈现迅猛增长态势。国家层面相继出台《“数据要素”三年行动计划&#xff08;2024—2026年&#xff09;》《数字中国建设整体布局规划》等政策&#xff0c;旨在激发产业创新活力&#…

如何使用 CSS 实现黑色遮罩效果

最近在工作中遇见了一个需求&#xff0c;鼠标经过盒子出现黑色遮罩&#xff0c;遮罩中有相关的编辑按钮&#xff0c;点击以后&#xff0c;进行图片上传并且展示&#xff0c;由于当时没有思路&#xff0c;思考了好久&#xff0c;所以在完成开发后进行总结&#xff0c;使用的技术…

ChatGPT课件分享(37页PPT)

资料解读&#xff1a;ChatGPT课件分享 详细资料请看本解读文章的最后内容。 近年来&#xff0c;人工智能技术的迅猛发展引发了全球范围内的广泛关注&#xff0c;尤其是以OpenAI为代表的公司在自然语言处理领域的突破性进展&#xff0c;彻底改变了人机交互的方式。本文将详细解…

无人机扩频技术对比!

一、技术原理与核心差异 FHSS&#xff08;跳频扩频&#xff09; 核心原理&#xff1a;通过伪随机序列控制载波频率在多个频点上快速跳变&#xff0c;收发双方需同步跳频序列。信号在某一时刻仅占用窄带频谱&#xff0c;但整体覆盖宽频带。 技术特点&#xff1a; 抗干扰…

C语言_数据结构总结4:不带头结点的单链表

纯C语言代码&#xff0c;不涉及C 0. 结点结构 typedef int ElemType; typedef struct LNode { ElemType data; //数据域 struct LNode* next; //指针域 }LNode, * LinkList; 1. 初始化 不带头结点的初始化&#xff0c;即只需将头指针初始化为NULL即可 void Init…

几种常见的虚拟环境工具(Virtualenv、Conda、System Interpreter、Pipenv、Poetry)的区别和特点总结

在 PyCharm 中创建虚拟环境是一个非常直接的过程&#xff0c;可以帮助你管理项目依赖&#xff0c;确保不同项目之间的依赖不会冲突。 通过 PyCharm 创建虚拟环境 打开 PyCharm 并选择或创建一个项目。 打开项目设置&#xff1a; 在 Windows/Linux 上&#xff0c;可以通过点击…

Ubuntu安装问题汇总

参考文章&#xff1a; 【Ubuntu常用快捷键总结】 【王道Python常用软件安装指引】 1. 无法连接虚拟设备 sat0:0 【问题】&#xff1a;出现下图所示弹框。 【问题解决】&#xff1a; 点击 “否” 。 点击左上角的 “虚拟机” → “设置…” → “CD/DVD (SATA)” &#xff0c;…

Ceph(1):分布式存储技术简介

1 分布式存储技术简介 1.1 分布式存储系统的特性 &#xff08;1&#xff09;可扩展 分布式存储系统可以扩展到几百台甚至几千台的集群规模&#xff0c;而且随着集群规模的增长&#xff0c;系统整体性能表现为线性增长。分布式存储的水平扩展有以下几个特性&#xff1a; 节点…

从0开始的操作系统手搓教程43——实现一个简单的shell

目录 添加 read 系统调用&#xff0c;获取键盘输入 :sys_read putchar和clear 上班&#xff1a;实现一个简单的shell 测试上电 我们下面来实现一个简单的shell 添加 read 系统调用&#xff0c;获取键盘输入 :sys_read /* Read count bytes from the file pointed to by fi…

【Spring】基础/体系结构/核心模块

概述&#xff1a; Spring 是另一个主流的 Java Web 开发框架&#xff0c;该框架是一个轻量级的应用框架。 Spring 是分层的 Java SE/EE full-stack 轻量级开源框架&#xff0c;以 IoC&#xff08;Inverse of Control&#xff0c;控制反转&#xff09;和 AOP&#xff08;Aspect…

01 音视频知识学习(视频)

图像基础概念 ◼像素&#xff1a;像素是一个图片的基本单位&#xff0c;pix是英语单词picture的简写&#xff0c;加上英 语单词“元素element”&#xff0c;就得到了“pixel”&#xff0c;简称px&#xff0c;所以“像素”有“图像元素” 之意。 ◼ 分辨率&#xff1a;是指图像…

vue3自定义hooks遇到的问题

问题 写了一个输入查询参数和url返回加载中状态、请求方法、接口返回列表的hooks&#xff0c;出现的结果是只有请求方法有效&#xff0c;加载状态无效&#xff0c;接口返回了数据&#xff0c;页面却不显示数据。 代码如下 只展示部分关键代码 import { ref, toRefs, toRef, o…

liunx磁盘挂载和jar启动命令

一、磁盘挂载 查看历史磁盘挂载命令&#xff1a;history | grep mount 查看所有挂载硬盘命令&#xff1a;mount 磁盘挂载命令&#xff1a;mount -t cifs -o usernamesh**,passwordP!ss**** //192.168.1.2/attachmentfilesShare2.2/pdfCert /home/nybzg/cnfai1/pdfCert 二、j…

gbase8s rss集群通信流程

什么是rss RSS是一种将数据从主服务器复制到备服务器的方法 实例级别的复制 (所有启用日志记录功能的数据库) 基于逻辑日志的复制技术&#xff0c;需要传输大量的逻辑日志,数据库需启用日志模式 通过网络持续将数据复制到备节点 如果主服务器发生故障&#xff0c;那么备用服务…

如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统

我在业余时间开发了一款自己的独立产品&#xff1a;升讯威在线客服与营销系统。陆陆续续开发了几年&#xff0c;从一开始的偶有用户尝试&#xff0c;到如今线上环境和私有化部署均有了越来越多的稳定用户。 随时近来 AI 大模型的火热&#xff0c;越来越多的客户&#xff0c;问…