基于Redis可以做哪些事情(redis能做啥)
mhr18 2025-03-30 18:53 22 浏览 0 评论
作者 / 以码为梯
排版 / 以码为梯
文章字数 / 2600
阅读时长 / 10分钟
读了本文有所收获希望大家可以点赞转发
提及Redis我们的第一印象肯定是缓存,因为Redis是基于内存的数据库(速度快),所以适合用作缓存。但是除了被当做缓存使用,基于Reids提供的各种数据类型,我们还是可以实现很多功能。
分布式锁(SET)
我们设计分布式锁时需要考虑一下两个方面:
- 一次性只能有一个客户端获得锁。
- 避免死锁(获取锁的客户端在释放锁之前就崩溃后者网络不可到达的情况)。
以上两点都可以通过Redis中的SET命令来达到:
SET resource-name anystring NX EX max-lock-time
NX参数表示只有在键不存在时才能执行成功,这样多个客户端同时执行SET命令只有一个会成功,也就保证了只有一个客户端可以获得锁。
max-lock-time用来设置键的超时时间,这样在获取到锁的客户端崩溃或者网络不可达时依旧可以删除键,避免其他客户端一直不能获取到锁而造成死锁。
通常客户端获取锁并执行相关操作之后就会调用DEL命令来删除键,但是在网络延迟的情况下有可能会出现两个客户端同时获取到锁的情况:
- A、B两个客户端同时获取锁,A获得了锁,键的超时超时时间设置为60s。
- A执行相关的操作因为不明原因时间超过60s,键因为过期被删除。
- B获取到锁并执行相关操作。
- A执行操作完成调用DEL删除键。
- C执行SET命令也可以获得锁。
- 最后就出现了B、C两个客户端都获得锁的情况。
采用随机值的方式来解决上述问题,并在删除时不是通过键直接删除,而是通过判断值的方式来删除,这样就可以避免上述情况。
if redis.call(“get”,KEYS[1]) == ARGV[1]
then
return redis.call(“del”,KEYS[1])
else
return 0
end
除此之外,Redis还提供了RedLock algorithm来实现分布式锁,介于文章主题的原因,在这里就不详细介绍,大家可以去官网学习后者等后续文章。
会话管理
利用Redis的过期机制和消息通知机制可以实现在分布式架构对会话的统一管理,我们常用的spring-session就有基于redis的实现。
时间序列(APPEND)
在每次新增内容长度固定时,就可以使用APPEND命令来拼接新内容到字符串,然后通过GETRANGE来获取值,通过SETRANGE来设置值。
在使用时,可以以时间戳为键来存放这段时间内的值。例如每小时内的采集点存储,可以以小时为键。
APPEND ts2021082312 "0043"
计数器Counter(INCR)
可以通过INCR命令统计对网站的访问次数,每次用户访问就调用一次INCR。
结合EXPIRE命令也可以实现最近用户访问的页面。例如存在页面A、B、C、D,可以分别以vist:A、vist:B、vist:C、vist:D为键,每次用户访问对应的页面则调用INCR命令将访问次数加1同时设置新的过期时间60s。可以通过查询以vist开头的键列表查询最近60秒内被访问的页面列表。
速率限制器Rate limiter
在一些提供API的服务中,可能会存在需要限流的场景,例如每秒每个ip的请求数不超过10。通过Redis的INCR和EXPIRE可以实现该功能。
方案一
通过时间戳和IP地址组成键,收到请求时将IP和时间戳组成的键对应的值加1并对键设置过期时间。接着判断键对应的值加1之后的结果是否大于10,如果大于10则返回异常,否则请求可以正常通过。
方案二
以IP为键,并且将过期时长设置为1秒来实现。
方案三
通过Redis中的LIST来保存当前IP,通过LLEN来获取列表的长度并判断是否大于阈值。
可靠的消息队列
在使用Redis的RPUSH和RPOP来实现队列时,在消费者执行RPOP命令获取到消息后未执行对应业务之前就崩溃了,这样的场景就造成了消息丢失。
通过LMOVE命令,可以从列表获取元素的同时将元素插入额外的处理列表(processing)中,并在业务执行完成之后执行LREM命令去删除已经处理的消息。
上面提及的消息队列只是一种简单的实现模式,消息只能消费一次。在软件架构时其实还是要选用kafka这样的功能强大的中间件。
循环队列Circular list
LMOVE命令中如果source和destination是相同的键,那么就可以将头部元素移到尾部位置。
LMOVE circular circular LEFT RIGHT
对于一个需要持续执行的任务,例如判断系统中多个网址是否可用。可以将地址放入Redis列表中,并启动多个客户端执行调用上面的LMOVE命令来获取网址并完成检测工作,这样就确保了每个地址都会被检测到,并且新增的地址也会被检测到。
因为LMOVE命令是原子的而且是在同一个列表中移动元素,确保了成员不会丢失,最终确保了该方案的可靠性。
事件通知Event notification
因为Redis中的Set是没有提供的阻塞操作,我们可以将List的阻塞当做事件通知来完成Set的相关的阻塞操作。
标签系统
依赖Redis中Set的不存在重复成员的特性可以用来实现标签系统。
假设我们的业务场景是对TED的视频做标签管理。我们有资源S1、S2,S3,S1是关于健康(health)的、S2是关于数学(math)的、S3两者都有。我们就可以利用SET的命令完成以下需求:
// 给每个资源打上对应的标签
SADD S1 health
SADD S2 math
SADD S3 health math
// 标记拥有标签的资源
SADD tag:health S1 S3
SADD tag:math S3
获取标签列表
// 在标签过多的情况下通过迭代器的方式获取列表
SCAN 0 MATCH tag:*
获取同时拥有health和math两个标签的资源
SINTER tag: health tag: math
S1和S3拥有的相同的标签
SINTER S1 S3
排名相关
因为Sorted sets是带有排序功能,可以按照得分排序,因此利用此特性可以实现排行榜、获取排名前5的人等功能。
ZADD rank 10 a 9 b 8 d 7 f 6 h 5 k 4 l 3 p 2 i 1 z
// 获取排名前5
ZRANGE rank 0 4 rev
指标的统计
很多系统可能都会统计系统的日登录人数或一段时间的访问人数。通常我们有很多的方案来实现,比如可以通过审计系统将用户行为记录到一张表中,在查询时通过SQL语句去查询,这样虽然能达到效果,但是效率肯定不会太好。
我们可以使用Redis的bitmap来实现。
bitmap的最大特点就是效率快占用空间小,在对 1.28 亿用户的模拟中,“每日独立用户”等典型指标在 MacBook Pro 上耗时不到 50 毫秒,仅占用 16 MB 内存(128000000/8/1024/1024)。
对于日登录人数的指标我们可以做如下设计:
- 将用户的ID设置为增长的整数。
- 以当前日期为键在用户访问系统时获取到对应的用户ID,对应索引的位设置为1。
- 调用BITCOUNT来获取值为1的个数,即日登录人数。
- 对于某一段时间内系统的登录人数(不重复的)可以通过bitop命令来实现。
// 用户操作时设置对应索引的值为1,此操作的时间复杂度为O(1)
setbit yyyy-mm-dd user_id 1
bitcount yyyy-mm-dd
// 获取22号、23号、24号这三天的活跃用户人数
bitop or dest 2021-08-22 2021-08-23 2021-08-23
bitcount dest
感谢大家读到这里,大家如果还有关于Redis可以实现的功能希望各位可以在评论区交流
你的点赞评论是我最大的动力
相关推荐
- Docker集群管理之Docker Compose
-
前言:在上一篇《Docker集群管理之DockerMachine》中,我们通过源码分析了解了DockerMachine的工作原理,使用者可以通过DockerMachine的一条命令在任意支持的平...
- 使用Dockerfile build镜像
-
Docker映像可以看作是Docker容器的压缩包,包含了应用程序以及运行应用程序所需的依赖,容器是映像的运行时实例。一般构建镜像都是使用dockerfile进行构建而不是dockercommit,...
- 自建私有云相册:Docker一键部署Immich,照片视频备份利器
-
自建私有云相册:Docker一键部署Immich,照片视频备份利器前言随着人们手机、PC、平板等电子产品多样,我们拍摄和保存的照片和视频数量也在不断增加。如何高效地管理和备份这些珍贵的记忆成为了一个重...
- docker容器的使用以及部署mysql
-
首先什么是docker官方:翻译:Docker是一个用于开发、发布和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分离,以便您可以快速交付软件。使用Docker,您可以像管理应...
-
- 自建Docker镜像加速服务,免费且简单,服务器VPS、NAS皆可用
-
写在前面:流程十分简单,有手就行,还请耐心看完。本文的实例仅做演示用,不久后将会删除,有需要的各位请自行搭建。免费实例如果15分钟内未收到入站流量,Render会关闭实例的网络服务。Render会在下次收到处理请求时重新启动该服务。Ren...
-
2025-05-24 15:40 mhr18
- 用了8年的方式-用 Docker 瞬间搭建本地开发环境
-
有些时候我们需要在本地搭开发环境,比如平时学习新技术的时候。或者有时候公司的项目需要在本地建一套类似的,方便调试修改。开发环境可能包括MySQL、Redis、Nginx、MQ、Elasticsea...
- 使用dockerfile构建docker镜像
-
准备工作购买vps使用ssh工具连接上1、更新系统aptupdate-y2、一键安装Dockercurl-fsSLhttps://get.docker.com-oget-docker.sh...
- 快速搭建 SpringCloud 微服务开发环境的脚手架
-
本文适合有SpringBoot和SpringCloud基础知识的人群,跟着本文可使用和快速搭建SpringCloud项目。本文作者:HelloGitHub-秦人HelloGitHub推出...
- Docker Hub最全详解(图文全面总结)
-
DockerHubDockerHub是一个由Docker公司负责维护的公共注册中心,它包含了超过15000多个可用来下载和构建容器的Docker镜像。DockerHub作用Docker好比一个代...
- Docker 命令详解
-
dockerimages—查看本地镜像命令dockerimages说明列出本地已下载的所有镜像及其标签、ID、大小等信息。适用场景查看本地镜像资源、准备删除或管理镜像时。常见用法docker...
- Kylin安装Dify
-
cd/mntgitclonehttps://github.com/langgenius/dify.gitcp/mnt/dify/docker/.env.example/mnt/dif...
- kali下对Docker的详细安装
-
Docker是渗透测试中必学不可的一个容器工具,在其中,我们能够快速创建、运行、测试以及部署应用程序。如,我们对一些漏洞进行本地复现时,可以使用Docker快速搭建漏洞环境,完成复现学习。注:本教程仅...
- 银河麒麟V10使用Docker方式部署应用
-
现在越来越多的企业级应用需要运行在国产化环境中,而银河麒麟V10是目前我碰到的最常用的服务器,在银河麒麟上部署应用有两种方式:使用二进制文件编译部署和使用Docker。关于使用二进制文件的方式...
- Docker入门到精通超详细教程,Docker全家桶实战攻略
-
大家好,我是各位双生的武魂、随身老爷爷。从看到这篇内容开始,你就是被选定的天命骚年,将承担起学完docker教程的使命,本使命为单向契约,你可选择YES或者选择YES。正式学习之前,我先给大家做一下d...
- 【Docker 新手入门指南】第一章:前言
-
一、基本介绍Docker介绍Docker是基于Go语言开发的开源容器化平台,旨在实现“一次镜像,处处运行”。它通过将应用程序及其依赖环境(代码、运行时、系统工具、系统库等)打包成一个轻量级、可移...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)