Redis分布式缓存面试题
为什么使用分布式缓存?
1. 提升性能
- 降低延迟:将数据缓存在离应用更近的地方,减少数据访问时间。
- 减轻数据库压力:缓存频繁访问的数据,减少对后端数据库的请求,提升系统响应速度。
2. 扩展性
- 水平扩展:通过增加节点,分布式缓存可以轻松扩展,处理更大规模的数据和请求。
- 负载均衡:数据分布在不同节点上,避免单点瓶颈,提升系统整体吞吐量。
3. 高可用性
- 容错能力:即使某个节点故障,其他节点仍能继续提供服务,确保系统稳定运行。
- 数据冗余:通过数据复制,防止单点故障导致的数据丢失。
4. 支持高并发
- 应对大量请求:分布式缓存能有效处理高并发场景,确保系统在高负载下仍能快速响应。
为什么使用Redis做分布式缓存?
1. 高性能
- 内存存储,读写速度快。
- 单线程模型,避免竞争问题,支持高并发。
2. 丰富的数据结构
- 支持字符串、哈希、列表、集合、有序集合等。
3. 持久化支持
- RDB 快照和 AOF 日志,确保数据不丢失。
4. 高可用性
- 主从复制、哨兵模式、集群模式。
5. 分布式支持
- Redis Cluster 支持数据分片和动态扩展。
6. 丰富的功能
- Lua 脚本、过期机制、发布/订阅、事务。
面对缓存穿透问题,有什么解决办法?
1. 缓存空值
- 将空结果缓存,设置较短过期时间。
2. 布隆过滤器
- 快速判断数据是否存在,过滤无效请求。
3. 缓存预热
- 提前加载热点数据到缓存。
4. 限流和降级
- 限制请求量或返回默认值。
数据库更新时布隆过滤器的同步方案
1. 定期重新建布隆过滤器
- 定期(每天或每小时)重新加载数据库中的有效键构建布隆过滤器。
2. 使用计数布隆过滤器
- 通过对每个key进行计数,支持动态删除和更新。
3. 结合缓存
- 通过缓存和布隆过滤器的组合实现实时更新。
4. 使用布隆过滤器的变种
- 如 Scalable Bloom Filter,适合动态数据量。
介绍一下分层布隆过滤器Scalable Bloom Filter
Scalable Bloom Filter 是布隆过滤器的一种变体,旨在解决传统布隆过滤器在数据量动态增长时的局限性。传统布隆过滤器需要预先设定容量,如果实际数据量超过预设容量,误判率会显著增加。而 Scalable Bloom Filter 可以动态扩展,适应数据量的增长。
Scalable Bloom Filter 的核心思想
-
分层设计:
- Scalable Bloom Filter 由多个布隆过滤器层(Layer)组成。
- 每一层都是一个独立的布隆过滤器,容量和误判率可以单独设置。
- 当某一层的容量接近饱和时,会自动创建新的层。
-
动态扩展:
- 当数据量增加时,新的数据会被添加到最新的层中。
- 查询时,会依次检查每一层,直到找到匹配的层或确认数据不存在。
-
误判率控制:
- 每一层的误判率可以单独设置,通常随着层数的增加,误判率逐渐降低。
- 整体误判率是所有层误判率的累积结果。
Scalable Bloom Filter 的优点
- 动态扩容:无需预先设定容量,适合数据量动态增长的场景。
- 误判率可控:通过分层设计,可以有效控制整体误判率。
- 灵活性高:可以根据需求调整每一层的容量和误判率。
Scalable Bloom Filter 的缺点
- 内存占用较高:由于分层设计,每一层都需要独立的内存空间。
- 查询性能稍低:查询时需要依次检查每一层,性能略低于单层布隆过滤器。
- 实现复杂度较高:需要管理多个布隆过滤器层。
Java 实现
以下是 Scalable Bloom Filter 的简单实现:
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.ArrayList;
import java.util.List;public class ScalableBloomFilter {private List<BloomFilter<String>> filters; // 布隆过滤器层private int layerCapacity; // 每一层的容量private double falsePositiveRate; // 每一层的误判率public ScalableBloomFilter(int layerCapacity, double falsePositiveRate) {this.filters = new ArrayList<>();this.layerCapacity = layerCapacity;this.falsePositiveRate = falsePositiveRate;addLayer(); // 初始化第一层}/*** 添加一个新层*/private void addLayer() {BloomFilter<String> newLayer = BloomFilter.create(Funnels.stringFunnel(), layerCapacity, falsePositiveRate);filters.add(newLayer);}/*** 添加一个元素*/public void add(String value) {// 如果当前层已满,添加新层if (filters.get(filters.size() - 1).approximateElementCount() >= layerCapacity) {addLayer();}// 将元素添加到最新的层filters.get(filters.size() - 1).put(value);}/*** 检查元素是否存在*/public boolean mightContain(String value) {// 依次检查每一层for (BloomFilter<String> filter : filters) {if (filter.mightContain(value)) {return true;}}return false;}/*** 获取当前层数*/public int getLayerCount() {return filters.size();}
}
使用示例
public class ScalableBloomFilterExample {public static void main(String[] args) {ScalableBloomFilter scalableBloomFilter = new ScalableBloomFilter(1000, 0.01);// 添加元素scalableBloomFilter.add("key1");scalableBloomFilter.add("key2");// 检查元素是否存在System.out.println("Contains key1: " + scalableBloomFilter.mightContain("key1")); // trueSystem.out.println("Contains key3: " + scalableBloomFilter.mightContain("key3")); // false// 获取当前层数System.out.println("Layer count: " + scalableBloomFilter.getLayerCount()); // 1}
}
Scalable Bloom Filter 的应用场景
- 动态数据量场景:如实时日志处理、用户行为分析等。
- 分布式系统:如分布式缓存、分布式数据库的去重。
- 大数据处理:如海量数据的快速过滤和查询。
总结
Scalable Bloom Filter 通过分层设计和动态扩展,解决了传统布隆过滤器在数据量动态增长时的局限性。它的核心优势在于:
- 动态扩容:无需预先设定容量。
- 误判率可控:通过分层设计控制整体误判率。
- 灵活性高:适合数据量动态变化的场景。
Redis分布式缓存如何判断热点数据?
1. 基于访问频率
- 原理:通过统计每个键的访问频率(如每秒访问次数),识别出访问频率最高的数据。
- 实现方法:
- 使用 Redis 的
INCR命令或监控工具(如 Redis Monitor)统计键的访问频率。 - 使用 Lua 脚本或客户端代码记录每个键的访问次数。
- 使用 Redis 的
Java 实现
import redis.clients.jedis.Jedis;public class HotKeyDetector {private Jedis jedis;public HotKeyDetector(Jedis jedis) {this.jedis = jedis;}public void trackAccess(String key) {// 使用 Redis 的计数器记录每个键的访问次数jedis.incr("access_count:" + key);}public String getMostFrequentKey() {// 获取所有键的访问计数Set<String> keys = jedis.keys("access_count:*");String hotKey = null;long maxCount = 0;for (String key : keys) {long count = Long.parseLong(jedis.get(key));if (count > maxCount) {maxCount = count;hotKey = key.replace("access_count:", "");}}return hotKey;}
}
2. 基于时间窗口
- 原理:在特定的时间窗口内(如最近 1 分钟)统计键的访问频率,识别出热点数据。
- 实现方法:
- 使用 Redis 的
ZSET(有序集合)记录每个键的访问时间戳。 - 定期清理过期的访问记录,并统计时间窗口内的访问次数。
- 使用 Redis 的
Java 实现
import redis.clients.jedis.Jedis;public class TimeWindowHotKeyDetector {private Jedis jedis;private static final long WINDOW_SIZE = 60000; // 时间窗口大小(1 分钟)public TimeWindowHotKeyDetector(Jedis jedis) {this.jedis = jedis;}public void trackAccess(String key) {long currentTime = System.currentTimeMillis();// 使用 ZSET 记录访问时间戳jedis.zadd("access_times:" + key, currentTime, String.valueOf(currentTime));// 清理时间窗口之外的数据jedis.zremrangeByScore("access_times:" + key, 0, currentTime - WINDOW_SIZE);}public String getMostFrequentKey() {Set<String> keys = jedis.keys("access_times:*");String hotKey = null;long maxCount = 0;for (String key : keys) {long count = jedis.zcard(key);if (count > maxCount) {maxCount = count;hotKey = key.replace("access_times:", "");}}return hotKey;}
}
3. 基于采样统计
- 原理:通过采样部分请求,统计键的访问频率,推断出热点数据。
- 实现方法:
- 使用 Redis 的
MONITOR命令或客户端代码采样请求。 - 对采样数据进行分析,识别出高频访问的键。
- 使用 Redis 的
4. 使用 Redis 模块(如 RedisGears)
- 原理:利用 RedisGears 这样的扩展模块,实时监控和分析键的访问模式。
- 实现方法:
- 编写 RedisGears 脚本,统计键的访问频率并输出热点数据。
5. 基于外部监控工具
- 原理:使用外部监控工具(如 Prometheus、Grafana)收集 Redis 的访问数据,并通过可视化或分析工具识别热点数据。
- 实现方法:
- 配置 Redis 的监控插件,将访问数据导出到监控工具。
- 在监控工具中设置告警规则或分析报告。
总结
判断 Redis 分布式缓存中的热点数据可以通过以下方法:
- 基于访问频率:统计每个键的访问次数。
- 基于时间窗口:统计特定时间窗口内的访问频率。
- 基于采样统计:通过采样请求推断热点数据。
- 使用 Redis 模块:如 RedisGears 实时监控。
- 基于外部监控工具:如 Prometheus、Grafana。
明日继续更新 😊
相关文章:
Redis分布式缓存面试题
为什么使用分布式缓存? 1. 提升性能 降低延迟:将数据缓存在离应用更近的地方,减少数据访问时间。减轻数据库压力:缓存频繁访问的数据,减少对后端数据库的请求,提升系统响应速度。 2. 扩展性 水平扩展&a…...
AI 编码 2.0 分析、思考与探索实践:从 Cursor Composer 到 AutoDev Sketch
在周末的公司【AI4SE 效能革命与实践:软件研发的未来已来】直播里,我分享了《AI编码工具 2.0 从 Cursor 到 AutoDev Composer》主题演讲,分享了 AI 编码工具 2.0 的核心、我们的思考、以及我们的 AI 编码工具 2.0 探索实践。 在这篇文章中&am…...
图扑 HT for Web 总线式拓扑图的可视化实现
在图形用户界面(GUI)设计中,自定义连线技术不仅提升了用户体验,还为复杂数据可视化开辟了新的可能性。该功能点允许用户灵活地在界面元素之间创建视觉连接,使流程图、思维导图和网络拓扑图等信息呈现更加直观和动态。 …...
domain 网络安全 网络安全域
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网…...
IDEA 2024.1 最新永久可用(亲测有效)
今年idea发布了2024.1版本,这个版本带来了一系列令人兴奋的新功能和改进。最引人注目的是集成了更先进的 AI 助手,它现在能够提供更复杂的代码辅助功能,如代码自动补全、智能代码审查等,极大地提升了开发效率。此外,用…...
android计算屏幕尺寸dpi
说明: 我计划用一个Android程序,打印出平板屏幕的尺寸,大小,dpi等参数信息 效果图: 分辨率: 1280x752DPI: 213物理尺寸(英寸): 对角线 9.4step1: package com.example.myapplication;import android.os.Bundle; impor…...
deepseek-r1-centos-本地服务器配置方法
参考: 纯小白 Centos 部署DeepSeek指南_centos部署deepseek-CSDN博客 https://blog.csdn.net/xingxin550/article/details/145574080 手把手教大家如何在Centos7系统中安装Deepseek,一文搞定_centos部署deepseek-CSDN博客 https://blog.csdn.net/soso67…...
nginx 配置https
参考文档:nginx 文档 -- nginx官网|nginx下载安装|nginx配置|nginx教程 配置 HTTPS 服务器 HTTPS 服务器优化 SSL 证书链 单个 HTTP/HTTPS 服务器 基于名称的 HTTPS 服务器 具有多个名称 的 SSL 证书 服务器名称指示 兼容性 要配置 HTTPS 服务器,ssl…...
mapbox添加自定义图片绑定点击事件,弹窗为自定义组件
一、首先构建根据后端返回的数据构建geojson格式的数据,点位的geojson数据格式: {"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "…...
【Python爬虫(84)】当强化学习邂逅Python爬虫:解锁高效抓取新姿势
【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发…...
车载DoIP诊断框架 --- 连接 DoIP ECU/车辆的故障排除
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…...
嵌入式开发:傅里叶变换(4):在 STM32上面实现FFT(基于STM32L071KZT6 HAL库+DSP库)
目录 步骤 1:准备工作 步骤 2:创建 Keil 项目,并配置工程 步骤 3:在MDK工程上添加 CMSIS-DSP 库 步骤 5:编写代码 步骤 6:配置时钟和优化 步骤 7:调试与验证 步骤 8:优化和调…...
Uniapp 小程序接口封装与使用
深入理解 Uniapp 小程序接口封装与使用 在 Uniapp 小程序开发中,接口请求是获取和交互数据的关键部分。合理地封装接口不仅能提高代码的可维护性,还能增强项目的健壮性。今天,我们就来详细探讨一下如何在 Uniapp 中进行接口封装、引入以及使…...
Python入门 — 类
面向对象编程中,编写表示现实世界中的事物和情景的类(class),并基于这些类来创建对象(object)。根据类来创建对象称为实例化,这样就可以使用类的实例(instance) 一、创建…...
vscode/cursor+godot C#中使用socketIO
在 Visual Studio Code(VS Code)中安装 NuGet 包(例如SocketIOClient),你可以通过以下几种方法: 方法 1:使用dotnet cli 打开终端:在 VS Code 中按下Ctrl 或者通过菜单View -> Terminal打开终端。 导…...
应用的负载均衡
概述 负载均衡(Load Balancing) 调度后方的多台机器,以统一的接口对外提供服务,承担此职责的技术组件被称为“负载均衡”。 负载均衡器将传入的请求分发到应用服务器和数据库等计算资源。负载均衡是计算机网络中一种用于优化资源利…...
Kubernetes与Docker:区别与优劣总结
在云原生技术栈中,Docker和Kubernetes是两大核心工具,但它们的功能定位和使用场景截然不同。本文将从技术原理、架构设计、功能特性及适用场景等角度,深入分析两者的区别与优劣,并结合实际应用场景说明如何协同使用。 一、核心技术…...
区块链仿真工具SimBlock使用
1. Environment requirements SimBlock 可以在 Windows、MacOS、Ubuntu Linux 或任何支持 Java 的 Unix 平台上运行。 它需要以下版本的 JDK 和 Gradle。 请注意,SimBlock 的仓库中包含 Gradle Wrapper,因此您也可以自动安装 Gradle(我们稍…...
面试八股文--数据库基础知识总结(2) MySQL
本文介绍关于MySQL的相关面试知识 一、关系型数据库 1、定义 关系型数据库(Relational Database)是一种基于关系模型的数据库管理系统(DBMS),它将数据存储在表格(表)中,并通过表格…...
LeetCode 1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1)
【LetMeFly】1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1) 力扣题目链接:https://leetcode.cn/problems/design-browser-history/ 你有一个只支持单个标签页的 浏览器 ,最开始你浏览的网页是 homepage ,…...
江协科技/江科大-51单片机入门教程——P[1-3] 单片机及开发板介绍
前言:本节主要的任务是了解一下 51 单片机和所用的普中51开发板。 目录 一、单片机介绍 二、单片机的应用领域 三、STC89C52单片机 四、命名规则 五、单片机内部拆解 六、单片机内部结构图 七、单片机管脚图 八、单片机最小系统 九、开发板介绍 十、开发…...
【Uniapp-Vue3】导入uni-id用户体系
在uniapp官网的uniCloud中下载uni-id用户体系 或者直接进入加载,下载地址:uni-id-pages - DCloud 插件市场 进入以后下载插件,打开HbuilderX 选中项目,点击确定 点击跳过 点击合并 右键uniCloud文件夹下的database文件夹&#x…...
如何免费使用稳定的deepseek
0、背景: 在AI辅助工作中,除了使用cursor做编程外,使用deepseek R1进行问题分析、数据分析、代码分析效果非常好。现在我经常会去拿行业信息、遇到的问题等去咨询R1,也给了自己不少启示。但是由于官网稳定性很差,很多…...
基于 MySQL 数据库对三级视图(用户视图、DBA视图、内部视图)的详细解释
基于 MySQL 数据库对三级视图(用户视图、DBA视图、内部视图)的详细解释,结合理论与实际操作说明: 一、三级视图核心概念 数据库的三级视图是 ANSI/SPARC 体系结构的核心思想,MySQL 的实现逻辑如下: …...
easyexcel和poi同时存在版本问题,使用easyexcel导出excel设置日期格式
这两天在使用easyexcel导出excel的时候日期格式全都是字符串导致导出的excel列无法筛选 后来调整了一下终于弄好了,看一下最终效果 这里涉及到easyexcel和poi版本冲突的问题,一直没搞定,最后狠下心来把所有的都升级到了最新版,然…...
git 国内源
git config --global url.“https://hub.fastgit.xyz/”.insteadOf “https://github.com/” git config --global url.“https://hub.fastgit.xyz/”.insteadOf “git://github.com/” 取消 FastGit 代理: git config --global --unset url.“https://hub.fastgit.xyz/”.in…...
Spring Boot @Async 注解深度指南
Spring Boot Async 注解深度指南 一、核心使用要点 启用异步支持 必须在启动类或配置类添加 EnableAsync,否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题:Spring 默认使用 SimpleAsyncTaskEx…...
Facebook Instant Game:即时游戏的新时代
一、Facebook Instant Game 简介 Facebook Instant Game(即时游戏)是一种基于 HTML5 技术的轻量级游戏平台,允许用户无需下载即可在Facebook Messenger 和 News Feed 中直接游玩。这种游戏模式降低了用户的进入门槛,使得游戏可以迅速传播,极…...
取topN不同算法的实现的性能差别
背景 最近在实现一个需求,需要对大量数据中排序出前N,最暴力的方法肯定是直接全量排序。这里很明显是可以不用全量排序的,取前N,我们自然而然可以想到一个算法——堆排序。 一开始自己先写好了一版,后来想起ÿ…...
【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.1.2典型应用场景:日志分析、实时搜索、推荐系统
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 为什么选择Elasticsearch?——典型应用场景深度解析1. 引言2. 日志分析:海量数据的实时洞察2.1 行业痛点2.2 ES解决方案关键技术实现: 2.…...
