序言

网上看到的面试题:Redis有1亿个key,其中10w个key是以某个固定的前缀开头,如何将它们全部找出来?一般有两种命令可以实现:

  • Keys命令
  • Scan命令

下面具体分析一下两种命令

Keys命令

Keys pattern

如下图所示,建了一些不同数据结构(String、Hash、List、Set、ZSet)的Key,使用命令找出前缀为prefix的Key(key区分大小写),
在这里插入图片描述

  • 时间复杂度O(n);
  • 笔记本电脑40毫秒内可以查100w个键值对;
  • 生产环境慎用,大型数据库上执行会影响性能;

那么在大型数据库场景下为什么不能使用该命令呢?

Keys命令是一个阻塞式操作。

  • 单线程模型:Redis的命令处理是基于单线程的。一个命令在执行时,其他所有客户端的请求都必须等待;
  • 全量遍历:Keys为了找出所有匹配的key,会遍历数据库(NoSQL)中所有的key,遍历完成之前,Redis无法处理任何其他命令。
  • 生产环境灾难:如果正在有1亿个key的实例上执行Keys命令,会导致Redis服务卡顿数十秒甚至数分钟,所有依赖Redis的业务都会出现超时和雪崩,会导致严重的生产事故。

Scan命令

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

在这里插入图片描述

  • 单次调用时间复杂度O(1),完整迭代时间复杂度O(n);所以单次调用不会长时间阻塞线上服务;
  • 非阻塞式(渐进式)迭代:该命令允许增量迭代,每次调用返回少量数据,然后返回一个游标(cursor),下次传入这个游标,Redis就会接着上次结束的地方继续扫描,如上图scan xxx match prefix* count 3每次返回的游标不一定按照顺序;
  • COUNT参数:COUNT是一个建议值,告诉Redis希望每次迭代返回大约多少个key。但不是精确的,有时多有时少,但是可以控制单次扫描的粒度。如上图scan xxx match prefix* count 3每次返回的数据量不一定都是3;

参看官网,相关的还有其他的一些扫描指令:

  • SSCAN:iterates elements of Sets types.(针对Set数据结构)
  • HSCAN:iterates fields of Hash types and their associated values.(针对Hash数据结构)
  • ZSCAN:iterates elements of Sorted Set types and their associated scores.(针对ZSet数据结构)

在这里插入图片描述

实际操作

实际项目中可能会通过python脚本或者LUA脚本去执行查找,下面是使用python代码去执行的示例代码,

import redisr = redis.Redis(host='localhost', port=6379)
cursor = 0
prefix = 'your_prefix:*'
found_keys = []while True:cursor, keys = r.scan(cursor, match=prefix, count=10000)found_keys.extend(keys)if cursor == 0:break

可以使用Lua脚本在Redis服务器端直接处理,减少网络往返:

local keys = redis.call('SCAN', ARGV[1], 'MATCH', ARGV[2], 'COUNT', ARGV[3])
return keys

其他思路

空间换时间

在这里插入图片描述

另外维护一个“索引”:

  • 创建Key时,将key添加到前缀索引的Set集合中;
  • 查找Key时,直接读取索引Set的所有成员,这样时间复杂度即使是O(n),遍历的也是10w数据,而非NoSQL数据库中的1亿条数据;
  • 删除时,除了删除原始key,还需要从索引Set中移除对应的成员;

从节点(Replica)执行

假设这是一个低频且用于离线分析的需求,并且不想修改现有的数据结构,可以考虑在Redis集群(主从、哨兵、集群模式)的从节点去执行SCAN命令操作(甚至Keys命令),避免长时间耗时影响主节点(Master)的正常读写。
在这里插入图片描述

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

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

相关文章

【小沐学GIS】基于Godot绘制三维数字地球Earth(Godot)

🍺三维数字地球GIS系列相关文章(C)如下🍺:1【小沐学GIS】基于C绘制三维数字地球Earth(OpenGL、glfw、glut)第一期2【小沐学GIS】基于C绘制三维数字地球Earth(OpenGL、glfw、glut&…

day62 Floyd 算法 A * 算法

Floyd 算法本题是经典的多源最短路问题.Floyd 算法对边的权值正负没有要求,都可以处理。Floyd算法核心思想是动态规划。例如我们再求节点1 到 节点9 的最短距离,用二维数组来表示即:grid[1][9],如果最短距离是10 ,那就…

【软考论文】论可观测性架构技术的应用

🎁 考高级架构师的小伙伴注意了!📢 软考架构论文示例 2025年11月软考架构论文预测👍 一、历年论文题目 无!!! 二、考情分析 “可观测性技术”这一论题,目前在高级架构师与高级系统分…

软件测试:测试分类(一)

常用测试分类1.功能测试(人对功能的确定,保证某个功能可以正常进行)如验证你输入正确的手机号码和密码是否登录成功。手机号码不存在是否有提示,密码不正确是否有提示等2.自动化测试(如jmeter,属于黑盒测试…

BigFoot (Method Raid Tools)[MRT] (Event Alert Mod)[EAM]

检查法术技能ID,需要EAM命令,所以要先安装EAM BigFoot EventAlertMod lua-CSDN博客 /eam lookup 冰封之韧 同时我们发现一个糟糕的问题,为什么会有这么多ID呢,默认第一个 还有一种法子就是让别人开了技能告诉你ID,最…

【Scrapy-Redis】分布式爬虫实战(非常详细)

一、概要 1.分布式爬虫概念 分布式爬虫是一种利用多台机器协同工作的网络爬虫系统,通过任务分解、并行处理和资源共享,高效抓取并处理海量网页数据。其核心在于将爬取任务分配到不同节点,避免单点性能瓶颈,同时支持动态扩展和容错…

基于51单片机智能化交通红绿灯堵车流量红外设计

1 系统功能介绍 本设计题目为 基于51单片机智能化交通红绿灯堵车流量红外设计,主要用于十字路口交通信号智能控制,通过红外避障检测车流量,自动调节红绿灯时间,缓解拥堵。该系统由单片机、LED灯、红外避障传感器、LCD1602液晶显示…

VsCode 上的Opencv(C++)环境配置(Linux)

1.下载Opencv1.新建文件demo_cpp,在demo_cpp中新建third_parties文件2.OPENCV官网下载OpenCV-4.12.03.将下载好的opencv-4.12.0.zip压缩包在third_parties中解压,//以下均无特殊说明,均在vscode里的TERMINAL中输入 sudo apt-get install unzip//用于解压.zip文件 cd third_part…

sql xml模板

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace"com.example.mapper.UserMapper&quo…

docker在自定义网络中安装ElasticSearch和Kibana

创建自定义网络 创建一个名为 es-net 的桥接网络。这将作为 Elasticsearch 和 Kibana 的私有通信通道。 # 创建网络 docker network create es-net # 查看网络是否创建成功 docker network ls启动 Elasticsearch 容器 安装命令 docker run -d \--name elasticsearch \--net…

基于51单片机射频RFID停车刷卡计时收费系统设计

1 系统功能介绍 本设计题目为 基于51单片机射频RFID停车刷卡计时收费系统设计&#xff0c;旨在实现停车场车辆的刷卡计时和收费管理。系统通过单片机控制&#xff0c;结合 RFID 射频识别技术、LCD1602 显示以及蜂鸣器报警&#xff0c;实现停车时间的智能计时、累加及超时提醒功…

Netty源码—性能优化和设计模式

1.Netty的两大性能优化工具 (1)FastThreadLocal FastThreadLocal的作用与ThreadLocal相当&#xff0c;但比ThreadLocal更快。ThreadLocal的作用是多线程访问同一变量时能够通过线程本地化的方式避免多线程竞争、实现线程隔离。 Netty的FastThreadLocal重新实现了JDK的ThreadLoc…

Linux网络设备分析

🐧 Linux 网络设备驱动深入分析 本文将详细分析 Linux 网络设备驱动的工作原理、实现机制和代码框架,并通过一个虚拟网卡实例展示其实现,最后介绍常用的工具和调试手段。 1️⃣ Linux 网络设备驱动概述 Linux 网络设备驱动是内核中负责管理网络硬件(如以太网卡、Wi-Fi …

计算机视觉:从 “看见” 到 “理解”,解锁机器感知世界的密码

早上醒来&#xff0c;你拿起手机&#xff0c;人脸识别瞬间解锁屏幕&#xff1b;开车上班时&#xff0c;车载系统通过摄像头实时识别车道线&#xff0c;提醒你不要偏离&#xff1b;去医院做检查&#xff0c;医生用 AI 辅助的医学影像系统快速定位肺部微小结节&#xff1b;逛超市…

深入了解linux系统—— 线程封装

C11线程库 C11也提供了对应的线程库&#xff0c;在头文件<thread>中&#xff1b;C11将其封装成thread类&#xff0c;通过类实例化出对象&#xff0c;调用类内成员方法进行线程控制。 #include <iostream> #include <thread> #include <unistd.h> using…

安全防御-SCDN如何保护网站安全

随着互联网的快速发展&#xff0c;越来越多的企业依赖在线服务来运行其核心业务。与此同时&#xff0c;网络攻击的频率和复杂性也在不断增加&#xff0c;恶意流量成为许多企业头疼的问题。为了有效地提高网站的安全性和稳定性&#xff0c;德迅云安全加速SCDN被许多用户关注。今…

运筹优化(OR)-在机器学习(ML)浪潮中何去何从?

在如今机器学习的浪潮中&#xff0c;机器学习相关的岗位日益增多&#xff0c;而运筹优化的岗位却相对较少。这是今年我秋招过程中看到的现象。企业越来越希望候选人不仅能建模求解&#xff0c;还能理解如何用数据驱动优化。需要我们有一个完整的技术栈。那么我们就来看看OR与ML…

GitHub Copilot 在 VS Code 上的终极中文指南:从安装到高阶玩法

GitHub Copilot 在 VS Code 上的终极中文指南&#xff1a;从安装到高阶玩法 前言 GitHub Copilot 作为 AI 编程助手&#xff0c;正在彻底改变开发者的编码体验。本文将针对中文开发者&#xff0c;深度解析如何在 VS Code 中高效使用 Copilot&#xff0c;涵盖基础设置、中文优化…

安全测试、web探测、httpx

&#x1f4a2; 简介 httpx 是一个快速且多用途的HTTP工具包&#xff0c;允许使用retryablehttp库运行多个探测器。它旨在通过增加线程数量来保持结果的可靠性。 功能 &#x1f92a; 发送 GET、POST、PUT、DELETE 等 HTTP 请求支持流式传输支持重定向支持身份验证支持代理支持 …

CNN 中 3×3 卷积核等设计背后的底层逻辑

为什么卷积核爱用 33&#xff1f;CNN 设计 “约定俗成” 的底层逻辑 做深度学习的同学&#xff0c;对 CNN 里 33 卷积核、最大池化、BN 层这些设计肯定不陌生&#xff0c;但你有没有想过&#xff1a;为啥卷积核总选 33&#xff1f;池化层为啥默认最大池化&#xff1f;BN 层又是…