# Redis 之缓存击穿的防范技巧

Redis 之缓存击穿的防范技巧

什么是缓存击穿

缓存击穿是指在高并发的访问下,当缓存中没有对应的数据,而请求需要频繁访问数据库,从而导致数据库性能下降,甚至瘫痪的现象。这是因为有大量的并发请求同时访问数据库,导致数据库负载过高,无法承受。

缓存击穿的原因

  • 热点数据:热点数据即指被大量访问的数据,如果热点数据没有被缓存,那么就没有发挥 Redis 的缓存优势,并且大量的数据访问可能导致缓存数据被秒杀。
  • 缓存穿透:缓存穿透是指查询缓存和数据库中都不存在的数据,导致每次都需要查询数据库,此时会发生大量的 "缓存穿透" 请求,而数据库无法承受这么多请求而导致宕机。
  • DNS攻击:恶意攻击者可能利用大量的虚假请求占用缓存服务器上的资源,使得正常请求无法得到处理,从而导致了缓存穿透。

解决方案

1. 互斥锁

在发起查询请求之前,首先会尝试获取互斥锁,如果获取失败,则等待,直至成功获取互斥锁,在获取成功之后再开始查询。为查询加上互斥锁相当于串行进行查询,从而避免了并发查询请求的发起,从而有效防止了缓存击穿问题。这种方式有一定的弊端,效率可能会降低,因为串行查询需要等待锁的释放。

示例代码:

------ ------ -------------- ---- -
    -- -----
    ------ ------- - ------ - ----
    ------ --------- - -----------------------------
    ------- --------- - ------------------------------------------------ ---------- --- ------------------
    -- ----------- -
        -- -----
        ------ ----- - -------------------------------------
        -- ------ -- ----- -
            ------ -------- ------
        -
        -- ------
        ------ ------ - --------------------
        -- ----
        ------------------------------------ ------- ---- ------------------
        -- ---
        ------ ------------ - -----------------------------------------
        -- ------------- -- ---- -- ------------------------------- -
            ------------------------------
        -
        ------ -------
    - ---- -
        --- -
            -- ----
            ------------------
        - ----- --------------------- -- -
            --------------------
        -
        ------ -------------
    -
-

2. 提前预热

提前预热其实就是在 Redis 中主动将热点数据预先加载。使用这种方式的前提是能够确定热点数据,在缓存中主动预加载这些数据,从而在后续访问中减少了对数据库的访问次数。这种方式能够有效地缓解缓存击穿的问题。

示例代码:

--------------
------ ---- ------ -
    -------- ---- - -------- ------- ------- -----
    --- ------- --- - ----- -
        -- -----
        ------ ------ - ----------------------------
        -- ----
        ------------------------------------ ------- ---- ------------------
    -
-

3. 布隆过滤器

布隆过滤器是一种数据结构,可以用于缓存穿透的问题。将所有可能的数据哈希到一个足够大的 bit 数组中,如果某些位都为 1,那么该数据就可能存在,这样即使查询请求中的 key 不存在,但是在经过哈希之后能够得到 bit 数组中的某几个标志位都是 1,这样就可以初步判断请求中的 key 不存在缓存中,直接返回 null,不再对数据库进行查询,从而避免大量的数据库查询请求。

示例代码:

------ ------ ----- ---------------- -
    ------- ------ ----- --- ------------ - - -- --- -- ----------
    ---
     - ------------------------------------
     --
    ------- ------ ----- ----- ----- - --- ----- - -- -- --- --- --- --- -- --
    ------- ------ ------ ------ - --- ---------------------

    ---
     - ----------------------
     --
    ------- ------ ----- --------------- ---- -
        ----- ------ - --- ------------------
        --- ---- - - -- - - ------------- ---- -
            --- -------- - ----------------------- - ----------
            --------- - -------- - -------------
        -
        ------ -------
    -

    ------ ------ ---- ---------- ---- -
        ----- ------ - --------------
        --- ---- ----- - ------- -
            ----------------- ------
        -
    -

    ------ ------ ------- --------------- ---- -
        ----- ------ - --------------
        --- ---- ----- - ------- -
            -- -------------------- -
                ------ ------
            -
        -
        ------ -----
    -
-

总结

缓存击穿是 Redis 中一个相对常见的问题,但是针对不同的业务场景,应有针对性地采取不同的解决方案。本文介绍了互斥锁、提前预热以及布隆过滤器几种解决方案,这些方案都能够有效地缓解缓存击穿的问题,使用时需要权衡方案的优点和弊端,选择适合自己业务场景的方案。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/6468355e968c7c53b08653eb


猜你喜欢

  • PWA 技术:如何增加用户互动性

    PWA 技术:如何增加用户互动性 近年来,前端技术发展的速度日新月异,各种新的技术层出不穷,其中 Progressive Web App(PWA)技术,正是最近备受关注的一种技术。

    1 年前
  • Promise 如何与 LocalStorage 配合使用?

    什么是 Promise? Promise 是 JavaScript 中处理异步操作的一种方法。一个 Promise 对象代表着一个异步操作的最终完成(或失败),并且可以在完成时使用返回的结果。

    1 年前
  • 前端 SEO 实践指南:使用 Next.js 构建优化便于爬虫索引的站点

    随着互联网的发展,搜索引擎成为人们获取信息的主要途径,因此,网站在搜索引擎上的排名变得越来越重要。搜索引擎优化(SEO)是一种技术,通过优化网站内容,使其更容易被搜索引擎爬虫索引,增加网站被收录的几率...

    1 年前
  • React 项目中如何实现数据的导出与导入

    在 React 项目开发中,数据的导出和导入是一项很重要的功能。使得用户可以选择性的导出数据,也可以通过导入数据实现批量操作。本文将介绍在 React 项目中如何实现数据的导出和导入,并提供示例代码和...

    1 年前
  • 怎样正确的使用CSS Reset?

    在Web开发过程中,CSS Reset是一种非常流行的技术。它的作用是通过消除浏览器默认样式,然后在样式表中使用自己的规则,确保网站在不同浏览器中表现统一。那么,怎样正确地使用CSS Reset呢?下...

    1 年前
  • 美化你的应用:Material Design 风格的颜色使用指南

    美化你的应用:Material Design 风格的颜色使用指南 随着现代移动应用和 Web 应用的流行,设计和用户界面变得越来越重要。而在设计中,颜色是非常重要的一部分。

    1 年前
  • Hapi.js 学习笔记

    Hapi.js 是一个现代化的 Node.js 后端框架,专注于提供高度可配置且易于扩展的应用程序服务器。本文将介绍一些 Hapi.js 的基础知识,并提供一些实用的示例代码。

    1 年前
  • Koa2 中的 WebSocket 实现实时通信

    在 Web 应用中,实时通信是一种非常重要的功能。在过去,我们通常使用 Ajax 或者长轮询技术来实现实时通信。然而,这些技术都有一定的局限性,比如长轮询会消耗更多的资源,导致响应时间延迟等等。

    1 年前
  • 为什么 Server-Sent Events 在 Web 应用中备受关注

    在 Web 应用中,实时数据的传输一直是难题。传统的方式是通过轮询实现,即客户端不断向服务器发送请求,服务器返回最新的数据。但是,这样会占用大量的网络资源,而且实时性也不够高。

    1 年前
  • SASS 中嵌套 CSS 选择器的最佳实践

    SASS 中嵌套 CSS 选择器的最佳实践 在前端开发中,CSS 是无法避免的一部分。然而,纯 CSS 编写样式表在处理大型项目时往往变得十分困难。一方面是代码逻辑难以维护,另一方面是无法高效地复用代...

    1 年前
  • Docker 魔术疑难杂症解决方法

    随着云计算和微服务的火热发展,Docker 已经成为了开发人员必须掌握的技能之一。然而,很多人在使用 Docker 时会遇到各种奇怪的问题,比如容器启动失败、网络配置出现问题、镜像无法构建等等。

    1 年前
  • ES6 中的字符串新增方法及其应用

    前言 随着 JavaScript 的深入发展,ES6(或称 ECMAScript 2015) 带来了许多新的特性,其中字符串的新增方法尤为重要。字符串作为前端开发中常见的数据类型之一,被广泛应用于业务...

    1 年前
  • LESS 中的运算符优化 CSS 样式表

    随着前端开发的快速发展,CSS 样式表的大小和复杂性也在逐渐增加。这导致了很多页面的加载速度变慢,用户体验下降。LESS 是一种 CSS 预处理器,通过在编写样式表之前对代码进行预处理,可以提高开发效...

    1 年前
  • 在 ES9 中使用 RegExp 的 lookbehind 属性解决贪婪问题

    正则表达式是前端开发人员必备技能之一。然而,在实际应用中,我们经常遇到贪婪问题(Greedy Problem),即匹配最长子串的行为。这就使得匹配的结果并不是我们所期望的。

    1 年前
  • Tailwind 框架如何实现导航栏组件

    Tailwind 是一款快速构建高效前端界面的 CSS 框架。它可以让我们快速实现页面样式,并且提供丰富的组件。其中,导航栏组件是常见的界面元素之一,不论是网站还是 Web 应用都有广泛的应用。

    1 年前
  • 如何在 Web Components 中优化图片加载

    如何在 Web Components 中优化图片加载 Web Components 是网页开发中一种新型的技术,它是一种自定义元素及其功能的模块化方法。图片是网页中很重要的一部分,为了改善用户的体验,...

    1 年前
  • Jest 测试框架如何支持 React Native 项目的测试

    在 React Native 项目中,测试是保证代码质量和可靠性的重要环节。而 Jest 是一个常用的 JavaScript 测试框架,它不仅支持 React 项目的测试,也支持 React Nati...

    1 年前
  • 使用 Socket.IO 实现实时位置共享的完整教程

    本文将使用 Socket.IO 技术实现实时位置共享功能。Socket.IO 是一个面向实时应用的 JavaScript 库,使得实时通信变得容易、可靠和快速。本教程将详细介绍如何使用 Socket....

    1 年前
  • Sequelize 中 Hooks 的使用

    Sequelize 是一个 Node.js 中的 ORM 框架,它提供了丰富的 API 用于快速、方便地操作数据库。在日常开发中,我们经常需要对数据库的数据进行自动填充或者一些简单的数据验证处理,Se...

    1 年前
  • 在 Cypress 中使用 Page Object 模式进行测试

    Cypress 是一个基于 JavaScript 的现代化 Web 自动化测试框架,它能够对 Web 应用程序进行端到端测试,覆盖 UI、集成与端到端测试。在 Cypress 中使用 Page Obj...

    1 年前

相关推荐

    暂无文章