分布式锁选型+缓存db一致性

news/发布时间2024/9/20 7:55:30

基于Redis Cluster模式

setnx就可以实现加锁,del实现解锁,但是这样不具备原子性,存在无法释放的可能。

因此可以使用在加锁时增加过期时间命令,做到原子性的加锁并且可以自动释放。

一些问题:

  • key的过期时间不能设置太长,避免其他线程阻塞
  • 可能出现误解锁,比如当前线程在锁期间没有完成,解锁时锁已经被别人占据,导致解掉别人的锁
  • 获取锁是非阻塞的,直接返回结果
  • 存在锁公平问题,需要自己实现

解决:

  • 守护线程对当前任务进度进行监控,及时续过期时间,知道锁释放或任务完成
  • 释放验证,释放时比对线程id和锁的value,防止释放不属于自己的锁
  • 阻塞机制,只能通过代码比如死循环去实现
  • 公平机制需要依赖等待队列来实现

可重入性需要自己开发,安全性方面可能丢失锁(redis主从复制)

可以了解一下基于多节点的高可用分布式锁的算法 RedLock。

缓存一致性问题解决讨论(增加思考能力)

加入缓存就不可避免的引入数据一致性的问题,所以在这里讨论,先说结论,我在项目上使用的是旁路缓存模式——

读策略:

从缓存中读取数据;如果缓存命中,则直接返回数据;如果缓存不命中,则从数据库中查询数据;查询到数据后,将数据写入到缓存中,并且返回给用户。

写策略:

更新数据库中(HBASE,Redis)的记录;删除缓存记录。

然后探讨一下各种模式的优缺点以及相应的解决方案。

再来对比一下几种策略:

一共分为四种

先更新数据库,再更新缓存
先更新数据库,再删除缓存
先更新缓存,再更新数据库
先删除缓存,再更新数据库

先更新数据库,再更新缓存

第一个问题是这个过程不具备原子性,可能存在

a改库
b改库
b更新缓存
a更新换粗

导致出现了更改丢失的情况,同时每次更新db都去更新缓存,如果是写多读少的情况下,无疑是浪费感情。

先更新数据库,再删除缓存

问题:

缓存失效
a去查数据库
b改库
b删缓存
a放置旧数据缓存

但是细想就会发现这个事情的概率比较低,因为并发的情况下,写库要比读库的耗时更长,正常情况下应该是b执行删缓存放到最后。

另外更新可以看做先删后加,删除就只有一步,相当于一个惰性处理,即懒加载的思想,只有用到的时候才去加在,因为缓存的成本是较高的,尽量需要保证会被访问到才缓存。

遗留问题,如果删缓存失败也会导致存在数据不一致问题,这种情况下可以依赖过期时间(缓存尽量不要设置为永久,如果能永久的我相信本地缓存或数据库更合适一些),允许一段时间的脏数据来达到最终一致性。

或者再引入一个中间件,删除缓存失败的时候入mq,随机时间后进行重试(不推荐,搞这么复杂还是别用缓存了)

先更新缓存,再更新数据库

同样属于双更模式,双更模式带来的不确定性比较大,并非原子操作,不推荐。

先删除缓存,再更新数据库

可能删完马上又有读请求过来查库读到了脏数据放入缓存中,毕竟读快于写,不推荐

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

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

相关文章

今年国内石油需求稳中有升,巡检机器人助力石油行业可持续发展

前言:全球能源市场出现普遍回落趋势,其中石油价格下降近20%,而天然气和煤炭价格更是下跌超过50%。此外,碳酸锂和光伏组件价格也纷纷下降超过50%。这种价格下滑对于全球经济的持续增长,尤其是控制通货膨胀方面&#xff…

golang学习6,glang的web的restful接口传参

1.get传参 //get请求 返回json 接口传参r.GET("/getJson/:id", controller.GetUserInfo) 1.2.接收处理 package controllerimport "github.com/gin-gonic/gin"func GetUserInfo(c *gin.Context) {_ c.Param("id")ReturnSucess(c, 200, &quo…

如何在 VM 虚拟机中安装 Windows Server 2012 操作系统保姆级教程(附链接)

一、 VMware Workstation 虚拟机 若没有安装 VM 虚拟机可以参考下篇文章进行安装: VM 虚拟机安装教程https://eclecticism.blog.csdn.net/article/details/135713915 二、Windows Server 2012 镜像 点击链接下载镜像 下载链接https://pan.baidu.com/s/16nRHgyE…

Flask入门二(Flask的CBV、模版语法、请求和响应)

文章目录 一、Flask的CBV1.CBV的写法2.as_view的执行流程3.Login.as_view(name‘index’) name到底有什么用?4.CBV中得methods作用 二、模版语法1.渲染变量2.变量的循环3.逻辑判断 三、请求和响应 一、Flask的CBV 1.CBV的写法 from flask import Flask app Flask…

Stable Diffusion 解析:探寻 AI 绘画背后的科技神秘

AI 绘画发展史 在谈论 Stable Diffusion 之前,有必要先了解 AI 绘画的发展历程。 早在 2012 年,华人科学家吴恩达领导的团队训练出了当时世界上最大的深度学习网络。这个网络能够自主学习识别猫等物体,并在短短三天时间内绘制出了一张模糊但…

微信小程序 ---- 慕尚花坊 收货地址

收货地址 收货地址列表新增收货地址编辑收货地址删除收货地址 01. 定义新增参数以及封装接口 API 思路分析: 点击新建地址按钮,需要跳转到新增地址页面 因为新增和编辑收货地址页面是同一个页面,我们需要在这个页面处理新增和编辑功能&a…

应用存储与持久化数据卷

1、PV 引入场景: ① Deployment 管理的 pod,在做镜像升级的过程中,会产生新的 pod并且删除旧的 pod ,新旧 pod 之间如何复用数据? ② 宿主机宕机的时候,如何实现带卷迁移? ③ 多个 pod 之间&…

亚信安慧AntDB-M的扩展功能(三)

销毁函数: void My_SUM_deinit(UDF_INIT *initid) { //清理工作 } 假设编译生成的动态库名字是:my_sum_udf.so。 使用CREATE FUNCTION命令创建函数: CREATE FUNCTION My_SUM RETURNS INTEGER SONAME my_sum_udf.so; 使用UDF: SELECT My…

模型优化_如何提高网络/模型的泛化能力?(全面)

目录 1. 以数据为中心的泛化方法 1.1 使用更多数据 1.2 做好数据预处理 特征工程 1.3 数据增强 1.4 调整数据分布 2. 以模型为中心的泛化方法 2.1 使用更大批次 超参数调优 2.2 调整目标函数 2.3 调整网络结构 2.4 屏蔽网络节点 2.5 权值正则化 2.6 偏差-方差权衡…

雾锁王国服务器官方配置要求说明

雾锁王国/Enshrouded服务器CPU内存配置如何选择?阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置,支持4人玩家畅玩,自带10M公网带宽,1个月90元,3个月271元,幻兽帕鲁服务器申请页面 https://t.aliyun.com…

【BUUCTF web】通关1.0

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …

微信为什么使用 SQLite 保存聊天记录?

SQLite 是一个被大家低估的数据库,但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上,SQLite 是一个非常可靠的数据库,它可以处理 TB 级的数据,但它没有网络层。接下来,本文将与大家共同探讨 SQLite 在过去…

房贷计算器微信小程序原生语言

微信小程序: 房贷计算器 效果: 输入 300万 结果 还款明细 一共有3个页面 1、输入页面 2、结果页面 3、详情页面 1 index页面 index.wxml文件 <view class="text-black"><!--房屋总价--><view class="cu-bar bg-white solid-bottom"&…

ZABBIX修改web界面的 “支持“,“帮助”,“Integrations“。等菜单按钮,百试百灵,删除修改Help,Support菜单

♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ **ZABBIX修改web界面的 “支持”&#xff0c;“帮助”,“Integrations”。等菜单按钮&#xff0c…

十三、Qt多线程与线程安全

一、多线程程序 QThread类提供了管理线程的方法&#xff1a;一个对象管理一个线程一般从QThread继承一个自定义类&#xff0c;重载run函数 1、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QDialog &#xff08;2&#xff09;添加类&#xff0c;修改基于QThr…

提升智能客服机器人的语义理解能力:理解用户的语义和意图

智能客服机器人的发展已经成为现代服务业的一大亮点。它们不仅能够提供724小时不间断的服务&#xff0c;而且能够处理大量的用户请求&#xff0c;大大提高了服务效率。然而&#xff0c;尽管智能客服机器人的技术已经取得了显著的进步&#xff0c;但其语义理解能力仍有待提高。为…

Crawler爬虫基础知识

本来其实不知道爬虫的意义的&#xff0c;但是发现爬虫在信息收集的那一方面好像挺重要&#xff01;&#xff01; 那么就来浅学一下吧&#xff01;&#xff01;&#xff01; 1.基本的储备 对于爬虫&#xff0c;我们一般都是用的python去编写脚本 &#xff0c;其中还要导入…

阿里云启动实例进入了急救模式解决办法

相关文档 问题描述 通过远程连接软件无法登录Linux实例&#xff0c;通过使用管理终端连接Linux实例远程连接时&#xff0c;发现系统进入到急救模式&#xff08;emergency mode&#xff09;&#xff0c;且出现报错。 CentOS实例报如下错误。 systemctl default to try again…

模拟算法题练习(一)

模拟算法介绍&#xff1a; 模拟算法通过模拟实际情况来解决问题&#xff0c;一般容易理解但是实现起来比较复杂&#xff0c;有很多需要注意的细节&#xff0c;或者是一些所谓很“麻模“的东西。 模拟题一般不涉及太难的算法&#xff0c;一般就是由较多的简单但是不好处理的部…

Java——建造者模式(Builder)

建造者模式&#xff08;Builder&#xff09; 1、建造者模式的定义 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许使用者在不知道内部建造细节的情况下&…
推荐文章