当前位置: 首页 > article >正文

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 的核心思想

  1. 分层设计

    • Scalable Bloom Filter 由多个布隆过滤器层(Layer)组成。
    • 每一层都是一个独立的布隆过滤器,容量和误判率可以单独设置。
    • 当某一层的容量接近饱和时,会自动创建新的层。
  2. 动态扩展

    • 当数据量增加时,新的数据会被添加到最新的层中。
    • 查询时,会依次检查每一层,直到找到匹配的层或确认数据不存在。
  3. 误判率控制

    • 每一层的误判率可以单独设置,通常随着层数的增加,误判率逐渐降低。
    • 整体误判率是所有层误判率的累积结果。

Scalable Bloom Filter 的优点

  1. 动态扩容:无需预先设定容量,适合数据量动态增长的场景。
  2. 误判率可控:通过分层设计,可以有效控制整体误判率。
  3. 灵活性高:可以根据需求调整每一层的容量和误判率。

Scalable Bloom Filter 的缺点

  1. 内存占用较高:由于分层设计,每一层都需要独立的内存空间。
  2. 查询性能稍低:查询时需要依次检查每一层,性能略低于单层布隆过滤器。
  3. 实现复杂度较高:需要管理多个布隆过滤器层。

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 的应用场景

  1. 动态数据量场景:如实时日志处理、用户行为分析等。
  2. 分布式系统:如分布式缓存、分布式数据库的去重。
  3. 大数据处理:如海量数据的快速过滤和查询。

总结

Scalable Bloom Filter 通过分层设计和动态扩展,解决了传统布隆过滤器在数据量动态增长时的局限性。它的核心优势在于:

  1. 动态扩容:无需预先设定容量。
  2. 误判率可控:通过分层设计控制整体误判率。
  3. 灵活性高:适合数据量动态变化的场景。

Redis分布式缓存如何判断热点数据?

1. 基于访问频率

  • 原理:通过统计每个键的访问频率(如每秒访问次数),识别出访问频率最高的数据。
  • 实现方法
    • 使用 Redis 的 INCR 命令或监控工具(如 Redis Monitor)统计键的访问频率。
    • 使用 Lua 脚本或客户端代码记录每个键的访问次数。

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(有序集合)记录每个键的访问时间戳。
    • 定期清理过期的访问记录,并统计时间窗口内的访问次数。

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 命令或客户端代码采样请求。
    • 对采样数据进行分析,识别出高频访问的键。

4. 使用 Redis 模块(如 RedisGears)

  • 原理:利用 RedisGears 这样的扩展模块,实时监控和分析键的访问模式。
  • 实现方法
    • 编写 RedisGears 脚本,统计键的访问频率并输出热点数据。

5. 基于外部监控工具

  • 原理:使用外部监控工具(如 Prometheus、Grafana)收集 Redis 的访问数据,并通过可视化或分析工具识别热点数据。
  • 实现方法
    • 配置 Redis 的监控插件,将访问数据导出到监控工具。
    • 在监控工具中设置告警规则或分析报告。

总结

判断 Redis 分布式缓存中的热点数据可以通过以下方法:

  1. 基于访问频率:统计每个键的访问次数。
  2. 基于时间窗口:统计特定时间窗口内的访问频率。
  3. 基于采样统计:通过采样请求推断热点数据。
  4. 使用 Redis 模块:如 RedisGears 实时监控。
  5. 基于外部监控工具:如 Prometheus、Grafana。

明日继续更新 😊

相关文章:

Redis分布式缓存面试题

为什么使用分布式缓存&#xff1f; 1. 提升性能 降低延迟&#xff1a;将数据缓存在离应用更近的地方&#xff0c;减少数据访问时间。减轻数据库压力&#xff1a;缓存频繁访问的数据&#xff0c;减少对后端数据库的请求&#xff0c;提升系统响应速度。 2. 扩展性 水平扩展&a…...

AI 编码 2.0 分析、思考与探索实践:从 Cursor Composer 到 AutoDev Sketch

在周末的公司【AI4SE 效能革命与实践&#xff1a;软件研发的未来已来】直播里&#xff0c;我分享了《AI编码工具 2.0 从 Cursor 到 AutoDev Composer》主题演讲&#xff0c;分享了 AI 编码工具 2.0 的核心、我们的思考、以及我们的 AI 编码工具 2.0 探索实践。 在这篇文章中&am…...

图扑 HT for Web 总线式拓扑图的可视化实现

在图形用户界面&#xff08;GUI&#xff09;设计中&#xff0c;自定义连线技术不仅提升了用户体验&#xff0c;还为复杂数据可视化开辟了新的可能性。该功能点允许用户灵活地在界面元素之间创建视觉连接&#xff0c;使流程图、思维导图和网络拓扑图等信息呈现更加直观和动态。 …...

domain 网络安全 网络安全域

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网&#xf…...

IDEA 2024.1 最新永久可用(亲测有效)

今年idea发布了2024.1版本&#xff0c;这个版本带来了一系列令人兴奋的新功能和改进。最引人注目的是集成了更先进的 AI 助手&#xff0c;它现在能够提供更复杂的代码辅助功能&#xff0c;如代码自动补全、智能代码审查等&#xff0c;极大地提升了开发效率。此外&#xff0c;用…...

android计算屏幕尺寸dpi

说明&#xff1a; 我计划用一个Android程序&#xff0c;打印出平板屏幕的尺寸&#xff0c;大小&#xff0c;dpi等参数信息 效果图&#xff1a; 分辨率: 1280x752DPI: 213物理尺寸(英寸): 对角线 9.4step1: package com.example.myapplication;import android.os.Bundle; impor…...

deepseek-r1-centos-本地服务器配置方法

参考&#xff1a; 纯小白 Centos 部署DeepSeek指南_centos部署deepseek-CSDN博客 https://blog.csdn.net/xingxin550/article/details/145574080 手把手教大家如何在Centos7系统中安装Deepseek&#xff0c;一文搞定_centos部署deepseek-CSDN博客 https://blog.csdn.net/soso67…...

nginx 配置https

参考文档&#xff1a;nginx 文档 -- nginx官网|nginx下载安装|nginx配置|nginx教程 配置 HTTPS 服务器 HTTPS 服务器优化 SSL 证书链 单个 HTTP/HTTPS 服务器 基于名称的 HTTPS 服务器 具有多个名称 的 SSL 证书 服务器名称指示 兼容性 要配置 HTTPS 服务器&#xff0c;ssl…...

mapbox添加自定义图片绑定点击事件,弹窗为自定义组件

一、首先构建根据后端返回的数据构建geojson格式的数据&#xff0c;点位的geojson数据格式&#xff1a; {"type": "FeatureCollection","features": [{"type": "Feature","geometry": {"type": "…...

【Python爬虫(84)】当强化学习邂逅Python爬虫:解锁高效抓取新姿势

【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发…...

车载DoIP诊断框架 --- 连接 DoIP ECU/车辆的故障排除

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…...

嵌入式开发:傅里叶变换(4):在 STM32上面实现FFT(基于STM32L071KZT6 HAL库+DSP库)

目录 步骤 1&#xff1a;准备工作 步骤 2&#xff1a;创建 Keil 项目&#xff0c;并配置工程 步骤 3&#xff1a;在MDK工程上添加 CMSIS-DSP 库 步骤 5&#xff1a;编写代码 步骤 6&#xff1a;配置时钟和优化 步骤 7&#xff1a;调试与验证 步骤 8&#xff1a;优化和调…...

Uniapp 小程序接口封装与使用

深入理解 Uniapp 小程序接口封装与使用 在 Uniapp 小程序开发中&#xff0c;接口请求是获取和交互数据的关键部分。合理地封装接口不仅能提高代码的可维护性&#xff0c;还能增强项目的健壮性。今天&#xff0c;我们就来详细探讨一下如何在 Uniapp 中进行接口封装、引入以及使…...

Python入门 — 类

面向对象编程中&#xff0c;编写表示现实世界中的事物和情景的类&#xff08;class&#xff09;&#xff0c;并基于这些类来创建对象&#xff08;object&#xff09;。根据类来创建对象称为实例化&#xff0c;这样就可以使用类的实例&#xff08;instance&#xff09; 一、创建…...

vscode/cursor+godot C#中使用socketIO

在 Visual Studio Code(VS Code)中安装 NuGet 包&#xff08;例如SocketIOClient&#xff09;&#xff0c;你可以通过以下几种方法&#xff1a; 方法 1&#xff1a;使用dotnet cli 打开终端&#xff1a;在 VS Code 中按下Ctrl 或者通过菜单View -> Terminal打开终端。 导…...

应用的负载均衡

概述 负载均衡&#xff08;Load Balancing&#xff09; 调度后方的多台机器&#xff0c;以统一的接口对外提供服务&#xff0c;承担此职责的技术组件被称为“负载均衡”。 负载均衡器将传入的请求分发到应用服务器和数据库等计算资源。负载均衡是计算机网络中一种用于优化资源利…...

Kubernetes与Docker:区别与优劣总结

在云原生技术栈中&#xff0c;Docker和Kubernetes是两大核心工具&#xff0c;但它们的功能定位和使用场景截然不同。本文将从技术原理、架构设计、功能特性及适用场景等角度&#xff0c;深入分析两者的区别与优劣&#xff0c;并结合实际应用场景说明如何协同使用。 一、核心技术…...

区块链仿真工具SimBlock使用

1. Environment requirements SimBlock 可以在 Windows、MacOS、Ubuntu Linux 或任何支持 Java 的 Unix 平台上运行。 它需要以下版本的 JDK 和 Gradle。 请注意&#xff0c;SimBlock 的仓库中包含 Gradle Wrapper&#xff0c;因此您也可以自动安装 Gradle&#xff08;我们稍…...

面试八股文--数据库基础知识总结(2) MySQL

本文介绍关于MySQL的相关面试知识 一、关系型数据库 1、定义 关系型数据库&#xff08;Relational Database&#xff09;是一种基于关系模型的数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;它将数据存储在表格&#xff08;表&#xff09;中&#xff0c;并通过表格…...

LeetCode 1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1)

【LetMeFly】1472.设计浏览器历史记录&#xff1a;一个数组完成模拟&#xff0c;单次操作均O(1) 力扣题目链接&#xff1a;https://leetcode.cn/problems/design-browser-history/ 你有一个只支持单个标签页的 浏览器 &#xff0c;最开始你浏览的网页是 homepage &#xff0c…...

江协科技/江科大-51单片机入门教程——P[1-3] 单片机及开发板介绍

前言&#xff1a;本节主要的任务是了解一下 51 单片机和所用的普中51开发板。 目录 一、单片机介绍 二、单片机的应用领域 三、STC89C52单片机 四、命名规则 五、单片机内部拆解 六、单片机内部结构图 七、单片机管脚图 八、单片机最小系统 九、开发板介绍 十、开发…...

【Uniapp-Vue3】导入uni-id用户体系

在uniapp官网的uniCloud中下载uni-id用户体系 或者直接进入加载&#xff0c;下载地址&#xff1a;uni-id-pages - DCloud 插件市场 进入以后下载插件&#xff0c;打开HbuilderX 选中项目&#xff0c;点击确定 点击跳过 点击合并 右键uniCloud文件夹下的database文件夹&#x…...

如何免费使用稳定的deepseek

0、背景&#xff1a; 在AI辅助工作中&#xff0c;除了使用cursor做编程外&#xff0c;使用deepseek R1进行问题分析、数据分析、代码分析效果非常好。现在我经常会去拿行业信息、遇到的问题等去咨询R1&#xff0c;也给了自己不少启示。但是由于官网稳定性很差&#xff0c;很多…...

基于 ‌MySQL 数据库‌对三级视图(用户视图、DBA视图、内部视图)的详细解释

基于 ‌MySQL 数据库‌对三级视图&#xff08;用户视图、DBA视图、内部视图&#xff09;的详细解释&#xff0c;结合理论与实际操作说明&#xff1a; 一、三级视图核心概念 数据库的三级视图是 ANSI/SPARC 体系结构的核心思想&#xff0c;MySQL 的实现逻辑如下&#xff1a; …...

easyexcel和poi同时存在版本问题,使用easyexcel导出excel设置日期格式

这两天在使用easyexcel导出excel的时候日期格式全都是字符串导致导出的excel列无法筛选 后来调整了一下终于弄好了&#xff0c;看一下最终效果 这里涉及到easyexcel和poi版本冲突的问题&#xff0c;一直没搞定&#xff0c;最后狠下心来把所有的都升级到了最新版&#xff0c;然…...

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&#xff0c;否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题&#xff1a;Spring 默认使用 SimpleAsyncTaskEx…...

Facebook Instant Game:即时游戏的新时代

一、Facebook Instant Game 简介 Facebook Instant Game(即时游戏)是一种基于 HTML5 技术的轻量级游戏平台&#xff0c;允许用户无需下载即可在Facebook Messenger 和 News Feed 中直接游玩。这种游戏模式降低了用户的进入门槛&#xff0c;使得游戏可以迅速传播&#xff0c;极…...

取topN不同算法的实现的性能差别

背景 最近在实现一个需求&#xff0c;需要对大量数据中排序出前N&#xff0c;最暴力的方法肯定是直接全量排序。这里很明显是可以不用全量排序的&#xff0c;取前N&#xff0c;我们自然而然可以想到一个算法——堆排序。 一开始自己先写好了一版&#xff0c;后来想起&#xff…...

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.1.2典型应用场景:日志分析、实时搜索、推荐系统

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 为什么选择Elasticsearch&#xff1f;——典型应用场景深度解析1. 引言2. 日志分析&#xff1a;海量数据的实时洞察2.1 行业痛点2.2 ES解决方案关键技术实现&#xff1a; 2.…...