租约锁机制

2023-10-28

背景和介绍

缓存是计算机里广泛使用的一种技术,对降低读取延迟、网络流量和服务器负载都非常有效,但也带来了一致性(Consistency)的问题。所谓一致就是客户端总能读到最新的数据,使用缓存后有可能服务器端的数据已经被修改,但客户端仍然从缓存中读取陈旧的数据。为了保证一致性,有两种常见的解决办法,第一种是轮询(Polling),即每次读取数据时都先询问服务器数据是不是最新的,如果不是就从服务器传输新数据,这种方法需要每次读取数据时都与服务器通信。另一种方法就是回调(Callback)或者无效化(Invalidation),就是由服务器记住有哪些客户端读取了数据,对数据做修改时首先通知所有这些客户端数据已经失效,这种方法的问题在于服务器需要记住所有读取过数据的客户端,这是很大的负担,更严重的是,一旦有客户端联系不上或者丢失了客户端的信息,修改操作就无法继续。

 

1989年斯坦福大学的Cary G. Gray和David R. Cheriton提出了利用租约来维护缓存一致性的方法。所谓租约,其实就是一个合同,即服务器给予客户端在一定期限内可以控制修改操作的 权力。如果服务器要修改数据,首先要征求拥有这块数据的租约的客户端的同意,之后才可以修改。客户端从服务器读取数据时往往就同时获取租约,在租约期限 内,如果没有收到服务器的修改请求,就可以保证当前缓存中的内容就是最新的。如果在租约期限内收到了修改数据的请求并且同意了,就需要清空缓存。在租约过 期以后,客户端如果还要从缓存读取数据,就必须重新获取租约,我们称这个操作为“续约”。

 

在租约期限内,客户端可以保证其缓存中的数据是最新的。同时,租约可以容忍各种非拜占庭式失效(机器崩溃、网络分割等)。如果客户端崩溃或者网络中断,服务器只需要等待其租约过期就可以进行修改操作。如果服务器出错丢失了所有客户端的信息,它只需要知道租约的最长期限,就可以在这个期限之后安全的修改数据。与回调方式相比,服务器只需记住还拥有租约的客户端即可。

 

租约与带期限的锁非常相似,但更加灵活,因为租约还提供了“寻求同意”的机制(我觉得可以称为“带期限可妥协的锁”)。服务器还可以实现多种租约,比如“写租约”和“读租约”,并保证一个时间段内只有一个写租约或者多个读租约,这就相当于是单写者多读者的锁协议。

 

因 为租约是基于时间的,因此其有效性需要系统时间来保证。如果服务器的时钟快而客户端时钟慢,那么有可能服务器认为一个租约已经过期而客户端仍然认为其有 效,就可能导致错误。对这种情况就必须通过时钟同步协议来解决了,不过这种情况很少见。一般情况下,我们可以认为一个分布式系统的时间是同步在一个很小的 时间差e之内,只需把这个e考虑到租约期限内即可。

 

 

租约属性和管理

租约的属性和管理有多种选择,首先要考虑的就是租约期限的长短。

一般情况下,应当选择较短的租约期限。与长租约相比,短租约有三个优点。首先,在失效情况下修改操作往往需要等待租约过期,因此短租约就意味着更短的失效延迟。其次,就算一个客户端已经不再需要读取数据,但在其租约过期前,任何的修改操作仍然需要征求它的同意,这种情况叫做“假共享”,显然租约期限越长,这个问题就越严重。最后,短租约也使得服务器要维护的客户端信息更少。然而短租约也意味着更大的续约开销, 因此对于要反复读取却很少修改的数据,长租约会更有效。因此,对租约期的选择要权衡失效延迟、假共享开销和续约开销等多个因素,服务器可以根据数据访问特 性和客户端的性质灵活设置期限。事实上,如果我们把租约期限设为零,就相当与轮询,此时修改操作随时可以进行,而读取数据总是要联系服务器。如果把租约期 限设为无限长,就相当于回调。

 

除了期限的选择,还有很多管理选项。对客户端来说,可以选择 是否续约、何时续约以及是否同意修改等。比如为了减少读取延迟,客户端可以在租约过期前就续约,不过这样可能加重服务器的负担。对服务器来说,可以选择是 否发放租约、租约覆盖粒度以及对如何进行修改操作。比如在收到修改请求后,服务器可以不征求客户端同意,而是简单的等待所有租约过期(等待时不再发放新租 约以避免无限期的延迟)。对于“安装文件”,也就是修改极少的文件(比如头文件、库文件),服务器可以用一个租约来覆盖一批文件,同时定期广播续约通知来节省开销,如果需要修改数据,就停止广播并等待租约过期即可。

 

 

互联网的一致性问题

在互联网环境下,一致性问题更加复杂,因为网络延迟比局域网要大的多,客户端失效和网络分割都很常见。因此很多情况下,我们都只保证缓存的弱一致性,也就是不保证客户端总能读到最新的数据,只是尽量保证其读到的数据还不是非常滞后。相应的,我们把前面使用的一致性称为强一致性。目前最常用的保证弱一致性的方法就是生存期(TTL), 即读取数据的时候会指定生存期,在生存期内客户端直接从缓存中读取数据,之后必须与服务器通信验证缓存有效性或者获取最新数据。很显然,我们可以给变化较 多的数据分配较短的生存期来尽量减少客户端读取过期数据的几率,而给变化较少的数据分配较长的生存期来减少读取延迟和服务器负载。


1992年CMU的Vincent Gate在Alex项目中实现了可变生存期(Adaptive TTL),这个技术基于这样的观察,就是新数据比旧数据更容易被修改。 在Alex中采用了更新阈值(update threshold)的概念,把生存期设定为其缓存时间的一个百分比。假设一个刚刚向服务器验证过的数据已经在缓存中存在了10个钟头,其更新阈值为 20%,那么其生存期就是2个钟头。采用可变生存期技术并不能减少网络流量,但是可以比普通的生存期技术减少服务器负荷。

 

虽然弱一致性模型已经满足我们日常浏览网页的需求,但还是有一些应用会要求强一致性。局域网情况下的方法很难直接扩展到互联网环境。轮询方法的读取延迟太 大。回调方法不但记录所有客户会使得服务器难以承受,经常出现的网络分割更使得修改操作无法继续。短租约导致的网络通信和服务器负荷都太大,而且如果租约 期限小于网络延迟的话,那么除了增加服务器负荷外没有任何作用。长租约又相应的使得失效延迟和假共享的问题更加严重,而且服务器要记录大量客户端数据。既 然有可变生存期,那自然的也有了可变租约(variable leases)的想法。1998年威斯康辛大学麦迪逊分校的Pei Cao和Chengjue Liu就提出了一种叫two-tier的方案,就是区分只是偶然读取数据的客户端和真正需要强一致性的客户端,只对后者才发放租约(由客户端显示的提出请求)。更进一步的,他们分析了如何根据不同情况调整租约属性,例如数据修改减少时增加租约期限,存储空间不够时则缩短租约期限甚至要求客户端放弃租约。

 

卷租约

在1999年的论文中,德克萨斯大学奥斯汀分校的Jian Yin等提出了互联网环境下保证强一致性的卷租约机制。

 

所谓卷租约(volume leases), 与上面提到的针对“安装文件”的租约有点类似,即由一个租约会覆盖多个相关文件,其期限较短,一般是数十秒,一般要在过期前续约。卷租约因为期限短,续约 操作就比较频繁,但用户往往会同时读取一个卷下的多个文件,因此这个开销分摊到了多个文件上,依然是可以接受的。如果光采用卷租约,会带来非常严重的假共 享问题,因为拥有卷租约的客户端各自关注的数据可能很不相同。因此服务器还另外提供了对象租约(object leases),就是只覆盖一个文件的普通租约,期限一般较长,可以是数小时甚至数天,以取得较小的续约开销。客户端要保证缓存有效,就必须同时拥有对象租约和卷租约。修改操作需要征求同时拥有卷租约和对象租约的客户端的同意,如果出现客户端机器失效或者网络分割的情况,最多只需等待卷租约过期,就可以安全的修改数据。

一旦卷租约过期,服务器就认为相应的对象租约也都过期,客户端重新获取卷租约时,会检查相应的对象租约的有效性,如果数据没有修改就续约,否则清空缓存。事实上,卷租约和对象租约类似于心跳和回调,前者主要用来确定客户端的状态,后者用来定位对数据有兴趣的客户端。通过两种租约的结合,可以较好的平衡失效延迟和通信开销。实验数据表明,要取得同样的失效延迟时间,卷租约机制可以比普通租约机制减少三成到四成的消息数。粗一想或许还会奇怪,加了一个租约怎么能够减少通信呢?这是因为要取得同样的失效延迟,普通租约就必须把租约期限设定在延迟期限内(比如20秒),而如果使用卷租约,只需把卷租约的期限设定在延迟期限内,而对象租约的时间可以设的很长。因为卷租约的通信开销有好几个对象分摊,而对象租约的开销因为期限很长事实上非常小,所以总的开销会小于只使用普通租约的情况。

 

 

租约的其他应用

以上我们只讨论了如何用租约来维护缓存一致性,其实租约的应用范围非常广泛。

 

在 Frangipani分布式文件系统中实现了一个分布式的锁,客户端在获取锁之前,首先要获取一个租约,并且必须在租约过期前续约。这个客户端获得的锁都 与这个租约相关联,如果租约过期了,锁服务器就会自动的释放这些锁。这里的租约就是对锁有效性的一个保证,通过维护客户端租约,避免了为每个锁维护期限的 开销。这里的租约就相当于心跳。


在gfs中,每个文件块都有多个副本分布在多个chunkserver上,在 并行追加时必须有一个全局统一的追加顺序。当然这个顺序可以由master来确定,但是这样会大大增加master的负荷。另一种方法可以由多个 chunkserver通过一致性协议(比如Paxos)来达成一个一致,但这样开销太大。gfs使用了租约机制,就是对每个文件块,由master向一 个chunkserver发放租约,在租约期限内就由它来负责并行追加操作的顺序。chunkserver正常运行时可以一直续约,如果出现了机器失效或 者网络分割的情况,master就在租约过期以后把租约交给另外一个chunkserver。在某些情况下,master也会联系拥有租约的 chunkserver,请它们提前释放租约。

很多情况下,系统中已经有一个保证一致性的中心服务,如某个单一服务器或者是实现了Paxos协议的一组服务器,但如果所有的功能都需要通过这个中心服务,很容易造成性能瓶颈。为了提高效率和扩展性,可以通过租约把一致性扩展到更多服务上。事实上用租约来维护缓存一致性也是相当于把服务器上的数据一致性扩展到了客户端。
 

 

到底租约是什么?

在很多时候,租约的定义似乎很模糊,有的时候租约类似心跳,有的时候又类似于锁。到底租约的本质是什么呢?
回到租约最原始的定义:租约就是在一定期限内给予持有者特定权力的 协议。我觉得这里的期限就是租约的根本特性,正是这一特性使得租约可以容忍机器失效和网络分割。在期限之内,租约其实就是服务器和客户端之间的协议,而这 个协议的内容可以五花八门。如果协议内容是服务器确认客户端还存活,那么这个租约的功能就相当于心跳;如果协议内容是服务器保证内容不会被修改,那么这个 租约就相当于读锁;如果协议内容是服务器保证内容只能被这个客户端修改,那么这个租约就相当于写锁。租约这种灵活性和容错性,使其成为了维护分布式系统一致性的有效工具。

 

 

https://blog.csdn.net/sunjinjuan/article/details/82774371

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

租约锁机制 的相关文章

  • 为什么我不能让单个 Redis 客户端在同一连接中充当 PUB 和 Sub ?

    我的思维模型是 聊天 我订阅了某个频道 并且可以向该频道发布消息 由于 pub sub 是异步的 因此发布的消息可能随时出现 包括当您期望命令响应时 尽管 Redis 是单线程的 通常会阻止此类事情 但网络延迟可能会导致一些有趣的影响 根据
  • 如何判断sidekiq是否连接到redis服务器?

    使用控制台 如何判断 sidekiq 是否连接到 Redis 服务器 我希望能够做这样的事情 if sidekiq is connected to redis psuedo code MrWorker perform async do wo
  • 在节点中使用redis获取hash key的所有字段和值

    红色是使用哈希 我需要存储具有多个字段和值的哈希键 我尝试如下 client hmset Table1 Id 9324324 ReqNo 23432 redis print client hmset Table1 Id 9324325 Re
  • 如何在实时添加对象时从 Redis 中弹出对象?

    我想让 Node js 进程运行 因为它正在检查 Redis 服务器是否有任何新的弹出内容 另一个进程将偶尔进行推送 而 Node 进程将尝试弹出任何进来的内容 Node 进程将保持运行 有人能给我指出一个好的方向吗 我正在尝试找出如何监听
  • 连接到 localhost:6379 时出现错误 99。无法分配请求的地址

    设置 我有一个虚拟机 并在虚拟机中运行三个容器 一个 nginx 代理 一个非常简约的 Flask 应用程序和 redis Flask 应在端口 5000 上提供服务 而 redis 应在 6379 上提供服务 这些容器中的每一个都可以作为
  • 找不到模块“socket.io/node_modules/redis”

    当尝试做的时候 var redis require socket io node modules redis 我收到错误 找不到模块 socket io node modules redis 我不明白为什么 我正在运行 Windows 并运
  • Redis部署配置-主从复制

    目前我有两台服务器 我已经部署了基于node js Express JS的Web服务API 我正在使用 Redis 来缓存 JSON 字符串 将此设置部署到生产中的最佳选择是什么 我懂了here https stackoverflow co
  • 使用 EVAL、SCAN 和 DEL 的 Redis 通配符删除脚本返回“非确定性命令后不允许写入命令”

    因此 我正在寻求构建一个 lua 脚本 该脚本使用 SCAN 根据模式查找键并删除它们 原子地 我首先准备了以下脚本 local keys local done false local cursor 0 repeat local resul
  • connect-redis - 如何保护会话对象免受竞争条件影响

    我使用 nodejs 和 connect redis 来存储会话数据 我将用户数据保存在会话中 并在会话生命周期中使用它 我注意到两个更改会话数据的请求之间可能存在竞争条件 我尝试过使用 redis lock 来锁定会话 但这对我来说有点问
  • 保护节点 Redis

    我正在尝试保护 Node Redis IPC 服务器以使用私钥 公钥 我已经关注了本教程 http bencane com 2014 02 18 sending redis traffic through an ssl tunnel wit
  • Redis键空间事件不触发

    我有两个 Redis 客户端 在一个文件中我有一个简单的脚本设置并删除了 Redis 键 var redis require redis var client redis createClient 6379 127 0 0 1 client
  • 为什么Redis中不建议使用KEYS?

    在Redis中 建议不要使用按键命令 https redis io commands KEYS 为什么会这样呢 是因为它的时间复杂度是 O N 吗 或者是别的什么原因 我做了下面的实验来证明KEYS命令有多么危险 当带有 KEYS 的一个命
  • 如何设置 Celery 以通过 ssl 与 Azure Redis 实例对话

    使用 的伟大答案 如何在microsoft azure上的django项目中配置celery redis https stackoverflow com questions 39616701 how to configure celery
  • 是否有可嵌入的 Java 替代 Redis?

    根据这个线程 https stackoverflow com questions 3047010 best redis library for java 如果我想从Java中使用Redis Jedis是最好的选择 然而 我想知道是否有任何库
  • 如何将node.js管道传输到redis?

    我有很多数据要插入 SET INCR 到redis DB 所以我正在寻找pipeline http redis io topics pipelining 质量插入 http redis io topics mass insert通过node
  • 使用Redis从有限范围内生成唯一ID

    我有一些数据库项目 除了主键之外 还需要项目所属组的唯一索引 我们来调用属性nbr 以及将项目分组在一起并定义唯一范围的属性nbr 我们会打电话group This nbr必须在 1 N 范围内 并且may从外部源导入项目时进行设置 由于所
  • socket.io 广播功能 & Redis pub/sub 架构

    如果有人能帮助我解决一个小疑问 我将不胜感激 使用socket io广播功能和在Redis上使用pub sub设计架构有什么区别 例如 在另一个示例中 node js 服务器正在侦听 socket io 针对 键 模型 todo 和值 数据
  • Node Js:Redis 作业在完成其任务后未完成

    希望你们做得很好 我在我的 Nodejs 项目中实现了 BullMQ Bull 的下一个主要版本 来安排发送电子邮件的作业 例如 发送忘记密码请求的电子邮件 所以 我编写了如下所示的代码 用户服务 await resetPasswordJo
  • 使用 Sentinels 升级 Redis 的最佳实践?

    我有 3 个 Redis 节点 由 3 个哨兵监视 我进行了搜索 文档似乎不清楚如何最好地升级此类配置 我目前使用的是 3 0 6 版本 我想升级到最新的 5 0 5 我对这方面的程序有几个疑问 升级两个大版本可以吗 我在我们的暂存环境中执
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O

随机推荐

  • 安卓(Android)的原生系统真的那么好用吗

    定制系统有定制系统的优点 它一定更适合中国的大众用户 毕竟中国的大众用户甚至连微信调整一个功能都可能不会使用了 学习成本 这种东西能不要就不要 在 Android 9 0 之前也一定更适合中国的 Android 软件环境 原生 Androi
  • tomcat如何增大并发_【高并发】高并发环境下如何优化Tomcat性能?看完我懂了!...

    写在前面 Tomcat作为最常用的Java Web服务器 随着并发量越来越高 Tomcat的性能会急剧下降 那有没有什么方法来优化Tomcat在高并发环境下的性能呢 Tomcat运行模式 Tomcat的运行模式有3种 1 bio模式 默认的
  • Doxygen和VS助手配置代码注释模板

    Title FileNote Shortcut filenote Description 文件注释 Copyright c YEAR xx科技有限公司 http blog csdn net stelalala All rights rese
  • android ios通用OTG,被忽视的iOS13福利:OTG随心读写移动SSD

    被忽视的iOS13福利 OTG随心读写移动SSD 2019 09 22 15 58 14 11点赞 59收藏 29评论 iOS13带来了深色模式 HapticTouch等众多新功能 但很少有人提到OTG读取优盘 移动固态硬盘的新增特性 所需
  • MySQL视图详解

    今天继续给大家介绍MySQL相关知识 本文主要内容是MySQL视图 一 MySQL视图详解 MySQL引入了视图的概念 所谓视图 其实就是一张虚拟的数据表 该数据表与其他普通数据表一样 有列和属性 视图和普通的数据表唯一不同的是 视图中本身
  • Java定义一个队列Queue及操作

    定义一个队列 定义一个队列 Queue
  • postMessage - 跨域消息传递

    window postMessage 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本 而不用管是否跨域 一个文档里的脚本还是不能调用在其他文档里方法和读取属性 但他们可以用这种消息传递技术来实现安全的通信 这项技术称为 跨文
  • grep 基本选项

    grep 命令基本格式 gt gt grep 选项 模式 文件 如果模式字符串中有空格必须用 括起来 1 c 选项 表示输出匹配字符串行的数量 默认情况下 grep命令打印出包含模式的所有行 2 n 选项 不但显示匹配的行号 而且会将该行打
  • forms组件

    转载于 https www cnblogs com cmd61 p 11582275 html
  • Bug记录——nn.Parameter()参数不更新、根据loss自学习权重变量不更新、pytorch 模型自定义参数不更新、网络梯度为None,参数不更新解、tensor参数有梯度,但不更新

    系列文章目录 PyTorch学习 关于tensor Variable nn Parameter 叶子节点 非叶子节点 detach 函数 查看网络层参数 pytorch优化器 add param group 介绍及示例 Yolov7 优化器
  • (附源码)基于SSM学生作业管理系统-计算机毕设 20912

    SSM学生作业管理系统 摘 要 随着科学技术的飞速发展 各行各业都在努力与现代先进技术接轨 通过科技手段提高自身的优势 对于学生作业管理系统当然也不能排除在外 随着网络技术的不断成熟 带动了学生作业管理系统 它彻底改变了过去传统的管理方式
  • Android开机启动shell脚本(Android 8.0测试OK)

    Android 下做开机启动shell脚本的大致流程如下 目录 写shell脚本 为脚本写te文件 在init rc中启动脚本 添加Selinux权限 写shell脚本 比如新建一个init test sh 内容如下 system bin
  • C语言/C++基础之奔跑的小人

    C语言 C 基础之奔跑的小人 程序之美 前言 主体 运行效果 代码示例一 运行结果 代码示例二 结束语 程序之美 前言 C语言实现的会动的小人 非常有意思 代码也比较简单 有兴趣的小伙伴 可以抽时间学习或者了解下 其实就是一些字符的拼接 最
  • 7-14 然后是几点 (15分)

    7 14 然后是几点 15分 题目描述如下 有时候人们用四位数字表示一个时间 比如 1106 表示 11 点零 6 分 现在 你的程序要根据起始时间和流逝的时间计算出终止时间 读入两个数字 第一个数字以这样的四位数字表示当前时间 第二个数字
  • shinyapps安装

    相信很多刚接触shiny的小白都和我一样 会遇到shinyapps配置失败的问题 因为网站上能找到的教程提供的方法已经out 现在更新之后和以前有所不同 这是以前的配置方法 准备工作 1 拥有R或像RStudio的集成开发环境 2 R包构建
  • How to print out more than 20 items (documents) in MongoDB's shell?

    How to print out more than 20 items documents in MongoDB s shell db foo find limit 300 won t do it It still prints out o
  • STlink下载和打断点Debug调试小结

    一 下载 1 检查设备是否选择正确 2 检查SWDIO有没有识别到 如果没有 检查硬件连线是否正确 3 检查Utilities选项 4 点击settings 添加FLASH 二 Debug调试 前 言 当之前在用STlink进行调试的时候
  • 关于spring的aop的xml和注解操作

    AOP 相关概念 1 横切关注点 一些具有横切多个不同软件模块的行为 通过传统的软件开发方法不能够有效地实现模块化的一类特殊关注点 横切关注点可以对某些方法进行拦截 拦截后对原方法进行增强处理 2 切面 Aspect 切面就是对横切关注点的
  • 耗时半月,终于把牛客网上的软件测试面试八股文整理成PDF合集!

    大家好 最近收到不少小伙伴的留言 反映现在的面试难度越来越高 要背的八股文越来越多了 考察的知识点也越来越细致 明摆着就是想让我们 徒手造航母 嘛 对程序员们来说确实是一大挑战 因此 我特地整理了今年上半年大厂软件测试面试题的合集 希望能够
  • 租约锁机制

    背景和介绍 缓存是计算机里广泛使用的一种技术 对降低读取延迟 网络流量和服务器负载都非常有效 但也带来了一致性 Consistency 的问题 所谓一致就是客户端总能读到最新的数据 使用缓存后有可能服务器端的数据已经被修改 但客户端仍然从缓