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

政府门户网站建设合同刺激广告

政府门户网站建设合同,刺激广告,松岗做网站费用,wordpress的登录页目录 前言: 分布式系统买票示例 引入redis做分布式锁 引入过期时间 引入校验id 引入lua脚本 过期时间续约问题 redlock算法 小结: 前言: 在分布式系统中,涉及多个主机访问同一块资源,此时就需要锁来做互斥控制…

目录

前言:

分布式系统买票示例

引入redis做分布式锁

引入过期时间

引入校验id

引入lua脚本

过期时间续约问题

redlock算法

小结:


前言:

    在分布式系统中,涉及多个主机访问同一块资源,此时就需要锁来做互斥控制,避免出现类似线程安全问题。而Java中的synchronized只是对当前进程中的线程有效,多个主机实际上是多个进程,那么它就无能为力了,此时就需要分布式锁。

分布式系统买票示例

    客户端访问买票服务器进行买票操作,当买到票之后数据库余票执行减1操作。

    客户端1先执行查询余票操作,发现余票还有一张,买票成功后服务器操作数据库执行减1操作。如果此时客户端1还没有执行数据库减1操作,客户端2执行了查询余票操作,发现余票也是一张,那么也进行数据库减1操作,那么此时客户端1和客户端2都会买到票。把一张票卖给了两个人,显然这是不合理的。

引入redis做分布式锁

    引入分布式锁,所谓分布式锁实际上就是一个/一组单独的服务器程序,给其他服务提供 “加锁” 服务。redis是一种典型的实现分布式锁的方案,但不是唯一一种。

    为了解决上述超卖问题,买票服务器在进行买票的时候,就需要先加锁。

    加锁实际上就是在redis上设置一个特殊的键值对,完成上述买票操作再删除这个键值对。(此时认为这个键值对就是分布式锁)

    其他服务器在买票的时候,也去redis尝试设置这样的键值对,如果发现键值对已经存在,就认为“加锁失败”,此时该进程是放弃还是阻塞就看具体的实现策略了。

    这样就可以保证第一个服务器执行查询-更新的过程中,第二个服务器不会执行查询操作,也就解决了上述超卖问题。

注意:

    上述买票的场景也可以使用MySQL的事务解决,批量执行查询-更新操作。但是分布式系统中数据库不一定是MySQL,也可能是其他数据库没有事务,因此使用redis作为分布式锁是比较好的解决方案。

引入过期时间

    redis中使用 set nx 命令可以实现加锁效果,解锁使用 del 命令来完成。

    如果某个服务器 set nx 成功了,还没有执行 del 命令就挂了,此时redis上的锁就无法删除,其他服务器就无法获取到锁。

解决方案:

    可以在set key 的时候设置过期时间,一旦时间到锁自动就释放了。redis中可以使用 set ex nx命令完成。此时这个过期时间范围设置就显得尤为重要了,后面会有解释(过期时间续约问题)。

注意:

    务必使用 set ex nx 命令一次性执行加锁和设置过期时间操作。如果使用set nx 设置锁,然后使用 expire 设置过期时间,就可能出现这两个命令一个成功一个失败,就算使用redis事务只能保证两条命令一块执行,但不能保证其正确性。相比之下一条命令直接操作就比较稳妥。

引入校验id

    是否会出现服务器1执行了加锁操作,被其他服务器删除的情况呢?

    这种情况有可能出现,代码总会有bug,需要提前去防止。

解决方案:

    给服务器编号,每个服务器都有自己的唯一标识。进行加锁的时候,设置键值对.key对应要对哪个资源加锁(比如车次),value就可以存储服务器编号,标识出这个锁是哪个服务器加的。

    解锁的时候就可以进行校验,先查询这个锁的服务器编号,和自己服务器编号进行对比。如果一致则执行解锁操作,否则就失败。服务器这边需要执行校验逻辑,此时就可以有效避免误解锁。

引入lua脚本

    一个服务器内部也可能是多线程的,就有可能存在两个线程执行上述判断然后解锁操作。由于不是原子的,就有可能出现问题。

    服务器1的线程A和线程B都执行解锁操作,如果线程A拿到锁判断完后,还没有执行DEL操作,此时线程B也拿到锁判断也会成功,那么就会执行两次DEL操作。

    如果在线程A执行DEL之后,线程B执行DEL之前,服务器2的线程C在redis中进行加锁操作(此时由于线程A已经执行了DEL操作,因此可以加锁成功)。由于线程B已经校验完成,那么执行DEL就会删除掉服务器2加的锁。该问题就是因为GET和DEL操作不是原子的,就会出现问题。

    解决上述问题,可以使用redis事务,保证GET和DEL的原子性,在执行期间不会有插队情况出现。但是一般不会这样做,引入lua脚本是更加有效的解决方案。

    lua是一门编程语言,作为redis内嵌脚本,lua语言特别轻量,实现一个lua的解释器消耗系统资源非常小。

    可以使用lua编写一些逻辑,把这个脚本上传到服务器上,然后客户端就可以控制redis执行这些脚本了。redis执行lua脚本的时候,是原子的,相当于执行一条命令一样。(redis官方文档中提出lua属于是redis事务的替代方案)。

过期时间续约问题

    在加锁的时候key需要设置过期时间,那么这个时间设置多少合适呢?

    如果设置短,那么有可能在业务逻辑还没执行完,锁就被释放了。

    如果设置长,那么锁释放就会不及时。

动态续约:

    初始情况下设置一个时间比较短的过期时间(灵活进行调整),如果发现时间快到的时候,业务逻辑还没执行完,那就在续上一些过期时间(无限续约)。直到业务逻辑执行完成,锁也可以在较短时间内被释放。

    如果服务器中途挂了,那也没有负责续约的线程了,此时锁也可以在较短时间内被释放。

    动态续约往往需要服务器这边一个专门的线程负责,把这个线程就叫做看门狗(watch dog)。

redlock算法

    使用redis作为分布式锁,那么就需要保证redis的高可用。

    使用redis哨兵机制,当主节点挂了可以投票选举从节点作为主节点。但是如果在主节点加锁后还没来得及同步给从节点,主节点就宕机了。此时哨兵选举的从节点也就不存在该锁了。

    作为分布式系统,就需要随时考虑某个节点挂了,不会影响大局。

    redlock算法核心思想就是:冗余

    此处加锁会按照一定顺序,对这些redis主节点都进行加锁。如果某个节点宕机了,没关系继续给下一个redis主节点加锁。如果加锁成功节点个数超过总个数一半,就视为加锁成功。同理,解锁需要把上述节点都执行解锁操作。这里就不会因为某个节点挂了,而导致加不上锁的情况。

小结:

    这里实际上实现了互斥锁,还可以使用redis做读写锁,可重入锁,公平锁等等。 

http://www.rdtb.cn/news/15260.html

相关文章:

  • 如何学好网站开发推广软文平台
  • 微信上做网站编辑网页版登录入口
  • 邵阳哪里做网站网络营销师证书
  • 免费网站建设视频百度百科创建
  • 个人或主题网站建设实验体会google下载官方版
  • 做58类网站需要多少钱福清市百度seo
  • 时时彩 网站开发电商代运营公司
  • 装修品牌焦作seo推广
  • 临沂做商城网站外贸推广有哪些好的方式
  • 关键词自然排名优化网站seo的主要优化内容
  • 从零开始网页制作教程seo高级优化方法
  • 一级 做爰免费网站神马网站快速排名案例
  • 丰台周边网站建设上海谷歌推广
  • 企业网站开发软件营业推广策略
  • 住建网是个什么网站开网店怎么开 新手无货源
  • 网站建设和维护释义全网热搜榜第一名
  • 投票网站如何做资讯门户类网站有哪些
  • 广州h5网站制作新媒体运营怎么自学
  • 如何做网站引流山东今日头条新闻
  • 企业网站策划案全球搜
  • 域名服务器ip查询杭州seo优化
  • 公司交易平台网上海网站优化公司
  • 医疗机构网站以患者做宣传线上广告投放方式
  • 做网站外包工作怎么样最成功的网络营销案例
  • 东莞网站搭建哪家强渠道推广有哪些方式
  • 定西市建设网站费用抖音seo搜索优化
  • 有哪些可以免费做高数题的网站深圳将进一步优化防控措施
  • wordpress 中文数据手机优化大师官方版
  • 做网站推广的难点、黄金网站软件免费
  • 北京企业查询湖南企业seo优化