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

自助建站网站seo公司网站工信部不备案吗

自助建站网站seo公司,网站工信部不备案吗,seo1新地址在哪里,企业网站管理系统视频教程在当今的互联网应用开发中,MySQL 作为可靠的关系型数据库,与 Redis 这一高性能的缓存系统常常协同工作。然而,如何确保它们之间的数据一致性,成为了开发者们面临的重要挑战。本文将深入探讨 MySQL 与 Redis 缓存一致性的相关问题&…

在当今的互联网应用开发中,MySQL 作为可靠的关系型数据库,与 Redis 这一高性能的缓存系统常常协同工作。然而,如何确保它们之间的数据一致性,成为了开发者们面临的重要挑战。本文将深入探讨 MySQL 与 Redis 缓存一致性的相关问题,从不同的方案分析到实际项目的代码实现,为你呈现全面的技术解析。

一、理论知识:探寻一致性方案的基石

(一)不佳的方案

  1. 先写 MySQL,再写 Redis
    在高并发场景下,当多个请求同时进行数据更新时,若请求 A 先写 MySQL,接着在写 Redis 过程中出现延迟,而请求 B 快速完成了 MySQL 和 Redis 的数据更新操作,就会导致数据不一致。
    在这里插入图片描述
    这是一幅描述在高并发场景下,“先写 MySQL,再写 Redis” 方案可能出现数据不一致问题的时序图 ,具体过程如下:
    1. 初始状态:假设数据在 MySQL 和 Redis 中的初始值未明确提及,但后续操作是将其从某个值更新为 10 再到 11 。
    2. 请求 A 操作:请求 A 先对 MySQL 进行写操作,将 MySQL 中的数据更新为 10 。之后请求 A 在向 Redis 写数据时出现卡顿(延迟) 。
    3. 请求 B 操作:请求 B 在请求 A 写 MySQL 之后开始操作。请求 B 先将 MySQL 中的数据更新为 11 ,接着顺利将 Redis 中的数据也更新为 11 。
    4. 请求 A 后续操作:请求 A 卡顿结束后,继续执行向 Redis 写数据的操作,将 Redis 中的数据更新为 10 。这就导致 Redis 中的数据与 MySQL 中的数据(此时 MySQL 中为 11 )不一致 。

这种情况产生的原因在于高并发环境下,请求执行顺序和延迟导致写 Redis 操作的先后出现差异,使得最终 MySQL 和 Redis 中的数据状态不一致。如果此时有读请求,按照先读 Redis 若没有再读 DB 且读请求不回写 Redis 的规则,就可能读到不一致的数据 。

  1. 先写 Redis,再写 MySQL
    此方案与先写 MySQL 再写 Redis 类似,在高并发情况下,由于操作顺序的原因,极易出现数据不一致的问题。例如,当 Redis 写入成功但 MySQL 写入失败时,后续的读操作可能会读取到 Redis 中已更新但 MySQL 中未更新的数据,从而产生不一致。
    在这里插入图片描述

  2. 先删除 Redis,再写 MySQL
    当存在更新请求 A 和读请求 B 时,请求 A 先删除 Redis 缓存,若此时更新 MySQL 的操作耗时较长,而请求 B 的读请求快速执行,并且读请求会回写 Redis,那么在请求 A 的 MySQL 更新尚未完成时,请求 B 可能会将旧数据回写到 Redis 中,导致数据不一致。
    在这里插入图片描述

(二)可靠的方案

  1. 先删除 Redis,再写 MySQL,再删除 Redis(缓存双删)
    为解决先删除 Redis 再写 MySQL 带来的不一致问题,缓存双删方案应运而生。即先删除 Redis 缓存,然后更新 MySQL 数据,最后再次删除 Redis 缓存。为确保最后一次删除操作在回写缓存之后执行,不建议采用简单的等待固定时间(如 500ms)的方式,推荐使用异步串行化删除,将删除请求放入队列中,这样既能保证异步操作不影响线上业务,又能通过串行化处理在并发情况下正确删除缓存。若双删失败,可借助消息队列的重试机制,或者自建表记录重试次数来实现重试。
    在这里插入图片描述

  2. 先写 MySQL,再删除 Redis
    对于一些对一致性要求不是极高的业务场景,此方案下存在的短暂不一致是可以接受的。比如在秒杀、库存服务等对一致性要求严格的业务中,这种方案可能不太适用。出现不一致的情况需要满足缓存刚好自动失效,且请求 B 从数据库查出旧数据回写缓存的耗时比请求 A 写数据库并删除缓存的时间更长,这种情况发生的概率相对较小。
    在这里插入图片描述

  3. 先写 MySQL,通过 Binlog,异步更新 Redis
    该方案通过监听 MySQL 的 Binlog 日志,以异步的方式将数据更新到 Redis 中。它能保证 MySQL 和 Redis 的最终一致性,但无法保证实时性。在查询过程中,若缓存中无数据,则直接查询 DB;若缓存中有数据,也可能存在数据不一致的情况。
    在这里插入图片描述

二、方案比较:抉择最优解

  1. 先写 Redis,再写 MySQL:若数据库出现故障,而数据仅存在于缓存中,会导致严重的数据不一致问题,且写数据库失败后对 Redis 的逆操作若失败,处理起来较为复杂,因此不建议使用。
  2. 先写 MySQL,再写 Redis:适用于并发量和一致性要求不高的项目。当 Redis 不可用时,需要及时报警并进行线下处理。
  3. 先删除 Redis,再写 MySQL:实际应用中使用较少,不推荐采用该方案。
  4. 先删除 Redis,再写 MySQL,再删除 Redis:虽然方案可行,但实现较为复杂,需要借助消息队列来实现异步删除 Redis 的操作。
  5. 先写 MySQL,再删除 Redis:此方案较为推荐,删除 Redis 失败时可进行多次重试,若重试无效则报警。在实时性方面表现较好,适用于高并发场景。
  6. 先写 MySQL,通过 Binlog,异步更新 Redis:适用于异地容灾、数据汇总等场景,结合 binlog 和 kafka 可使数据一致性达到秒级,但不适合纯粹的高并发场景,如抢购、秒杀等。
方案优点缺点适用场景
先写Redis,再写MySQL无明显优点数据库挂掉时,数据存在缓存但未写入数据库,会造成数据不一致;写数据库失败后对Redis的逆操作若失败,处理复杂不推荐用于任何场景
先写MySQL,再写Redis实现简单高并发时易出现数据不一致;Redis不可用时需线下处理并发量和一致性要求不高的项目
先删除Redis,再写MySQL无明显优点出现数据不一致的概率较大,实际应用中较少使用不推荐用于任何场景
先删除Redis,再写MySQL,再删除Redis能解决部分数据不一致问题实现复杂,需借助消息队列异步删除Redis对一致性要求极高,且能接受复杂实现的场景
先写MySQL,再删除Redis实时性较好,删除Redis失败可重试,适用于高并发场景存在短暂不一致的情况,对强一致性要求的业务不适用对一致性要求不是特别强的高并发场景,如一般的电商商品展示等
先写MySQL,通过Binlog,异步更新Redis能保证最终一致性,适用于异地容灾、数据汇总等场景无法保证实时性,不适合高并发场景异地容灾、数据汇总等对实时性要求不高的场景

三、项目实战:代码实现的精彩呈现

假设我们有一个简单的博客文章管理系统,需要保证文章标签数据在 MySQL 和 Redis 中的一致性。采取先写 MySQL,再删除 Redis方案,以下是相关的代码实现示例:

(一)数据更新

  1. 写操作
    优先操作MySQL:通过事务保证数据库更新原子性。
    同步删除Redis缓存:若删除失败触发事务回滚(需结合业务验证),防止脏数据。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import redis.clients.jedis.Jedis;public class DataUpdate {private static final String DB_URL = "jdbc:mysql://localhost:3306/blog";private static final String DB_USER = "root";private static final String DB_PASSWORD = "password";public static void updateArticleTags(String articleId, String newTags) {Connection conn = null;PreparedStatement pstmt = null;Jedis jedis = new Jedis("localhost", 6379);try {// 连接数据库conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);// 开启事务conn.setAutoCommit(false);// 更新 MySQL 数据String sql = "UPDATE articles SET tags =? WHERE id =?";pstmt = conn.prepareStatement(sql);pstmt.setString(1, newTags);pstmt.setString(2, articleId);pstmt.executeUpdate();// 删除 Redis 缓存jedis.del("article:" + articleId + ":tags");// 提交事务conn.commit();} catch (SQLException e) {try {// 回滚事务if (conn != null) {conn.rollback();}} catch (SQLException ex) {ex.printStackTrace();}e.printStackTrace();} finally {// 关闭资源if (pstmt != null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}jedis.close();}}
}

(二)数据获取

  1. 读操作
    先查缓存:命中则直接返回数据。
    未命中查DB:查询结果回写Redis并设置过期时间,避免缓存穿透。
import redis.clients.jedis.Jedis;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class DataRetrieval {private static final String DB_URL = "jdbc:mysql://localhost:3306/blog";private static final String DB_USER = "root";private static final String DB_PASSWORD = "password";public static String getArticleTags(String articleId) {Jedis jedis = new Jedis("localhost", 6379);String tags = jedis.get("article:" + articleId + ":tags");if (tags == null) {Connection conn = null;PreparedStatement pstmt = null;ResultSet rs = null;try {// 连接数据库conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);String sql = "SELECT tags FROM articles WHERE id =?";pstmt = conn.prepareStatement(sql);pstmt.setString(1, articleId);rs = pstmt.executeQuery();if (rs.next()) {tags = rs.getString("tags");// 将数据写入 Redis 缓存,并设置过期时间(例如 60 秒)jedis.setex("article:" + articleId + ":tags", 60, tags);}} catch (SQLException e) {e.printStackTrace();} finally {// 关闭资源if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (pstmt != null) {try {pstmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}return tags;}
}

四、总结

通过对 MySQL 与 Redis 缓存一致性的多种方案的分析和实际项目的代码实现,我们了解到不同方案的优缺点和适用场景。在实际开发中,应根据项目的具体需求,如并发量、一致性要求、业务场景等,选择合适的方案来保证数据的一致性。希望本文能为你在处理 MySQL 与 Redis 缓存一致性问题时提供有益的参考和帮助。

http://www.dtcms.com/wzjs/614347.html

相关文章:

  • 创业网站建设规划书房产网站内容建设部门规划
  • ps制作个人网站首页官网机票特价机票查询
  • 城市文明建设网站营销模式有哪些 新型
  • 泗洪网站建设本地wordpress密码忘记了
  • 天津做网站一般多少钱外贸网站价格
  • 网站建设如何排版网站友链查询源码
  • 网站开发前景知乎建立公司网站流程
  • 怎么在360网站做词条php网站添加验证码
  • 游戏公司官方网站建设方案在线天堂おっさんとわたし
  • 西安网站建设创意中国进出口商品交易网
  • 营销型网站建设eyouc个人开发的软件能卖吗
  • 优秀网站作品网站建设服务承诺包括什么
  • 可信赖的丹阳网站建设宣讲家网站做四讲四有模范
  • 广告图片网站源码唐山seo优化
  • 腾讯广告建站工具如何用本机电脑做网站服务器吗
  • 地方房产网站APP如何做更改wordpress主题
  • 中国农业建设中心网站小程序可以自己开发吗
  • 广东省城乡建设部网站企业网站建设不足
  • 静态网站教程网页编辑用户信息原理
  • 网站建设用什么开源程序好建立数据库连接时出错wordpress
  • 期货交易网站开发鲜花店网站源码
  • 哪里做网站做的好怎么做付费网站
  • 有没有网站是免费做店招图片的昆明网站排名优化价格
  • 网站建设公司需要具备做网站的论坛
  • php源码搭建网站流程合肥seo公司
  • 页面设计上下左右如何设置长沙网站seo分析
  • php 网站开发架构windows10优化大师
  • 大学生做企业网站怎样做网络推广效果好
  • 国外大型购物网站好单库网站是怎么做的
  • 网站建设的好处和目的湖南平台网站建设哪家好