C++ 全栈知识体系C++ 全栈知识体系
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
  • 架构基础

    • 发展历程
    • 服务演化
    • ORM框架
    • RPC框架
  • 分布式系统

    • 分布式系统 - 基础
    • 分布式系统 - 设计
    • 分布式系统 - 缓存
    • 分布式系统 - 通信方式
    • 分布式系统 - 一致性
    • 分布式系统 - 锁
    • 分布式系统 - 解决高并发、高性能、高可用
  • 微服务

    • 微服务 - 简介
    • 微服务 - 学习路线
    • 微服务 - 服务网关
    • 微服务 - 通信方式
    • 微服务 - 消息队列
    • 微服务 - 保护
    • 微服务 - 分布式搜索
    • 微服务 - 分布式事务
    • 微服务 - 多级缓存
    • 微服务 - 幂等性设计
  • 中间件

    • 消息队列 - ZeroMQ

      • ZeroMQ - 经典例子
      • ZeroMQ - 基础
      • ZeroMQ - 进阶
      • ZeroMQ - 高级请求-应答模式
    • RPC调用 - Dubbo

      • Dubbo - 框架学习
    • 配置中心 - Consul

      • Consul - 概述
      • Consul - 学习内容
      • Consul - 安装与使用
      • Consul - 服务健康检查
      • Consul - 常用的API
      • Consul - 存储个K/V
    • 配置中心 - Apollo

      • Apollo - 概述
      • Apollo - 设计
      • Apollo - Docker部署
      • Apollo - 使用配置中心
    • 监控平台 - Cat

      • Cat - 概述
      • Cat - Docker快速部署
      • Cat - C++客户端的docker镜像
    • 数据处理管道 - Logstash

      • Logstash - Elastic 总览
      • Logstash - 工作原理
      • Logstash - docker部署
      • Logstash - 实践
    • 服务网关 - Kong

      • Kong - 概述
      • Kong - Docker快速部署
      • Kong - C++客户端的docker镜像

分布式系统 - 锁

分布式锁的两种实现方式。

    Redis实现

    可使用setnx , expire指令简单实现,但是无法保证原子性,以及保证各个节点的时钟同步

    • lua脚本

      -- 删除锁的时候,找到 key 对应的 value,跟自己传过去的 value 做比较,如果是一样的才删除。

      if redis.call("get", KEYS[1]) == ARGV[1] then
          return redis.call("del",KEYS[1])
      else
          return 0
      end
    

    redis保证脚本会以原子性(atomic)的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。这和使用 MULTI / EXEC 包围的事务很类似。在其他别的客户端看来,脚本的效果(effect)要么是不可见的(not visible),要么就是已完成的(already completed)。

    另一方面,这也意味着,执行一个运行缓慢的脚本并不是一个好主意。写一个跑得很快很顺溜的脚本并不难,因为脚本的运行开销(overhead)非常少,但是当你不得不使用一些跑得比较慢的脚本时,请小心,因为当这些蜗牛脚本在慢吞吞地运行的时候,其他客户端会因为服务器正忙而无法执行命令。

    • redlock

      redisson 官网推荐

        1. 获取当期毫秒时间,轮流用相同的key和随机值在N个节点上请求锁,在这一步里客户端在每个master上请求锁时,会有一个比总释放时间小的多的超时时间,这样可以防止客户端在某个master 宕机时堵塞过长时间,如果这个master节点不可用我们应尽快尝试下一个master
        1. 客户端计算获取锁所花的时间,只有当客户端在大多数master节点上成功获取了锁(在这里是3个),而且总共消耗的时间不超过锁释放时间,这个锁就认为是获取成功了。
        1. 如果锁获取成功了,那现在锁自动释放时间就是最初的锁释放时间减去之前获取锁所消耗的时间。
        1. 如果锁获取失败了,不管是因为获取成功的锁不超过一半(N/2+1)还是因为总消耗时间超过了锁释放时间,客户端都会到每个master节点上释放锁,即便是那些他认为没有获取成功的锁。

    Zookeeper实现

    创建一个永久节点作为锁节点,试图加锁的客户端在锁节点下创建临时顺序节点。Zookeeper会保证子节点的有序性。若锁节点下id最小的节点是为当前客户端创建的节点,说明当前客户端成功加锁。否则加锁失败,订阅上一个顺序节点。当上一个节点被删除时,当前节点为最小,说明加锁成功。操作完成后,删除锁节点释放锁。

    1. zk的底层数据结构是树形结构,由一个一个的数据节点组成;

    2. zk的节点分为永久节点和临时节点,客户端可以创建临时节点,当客户端会话终止或超时后,zk会自动删除临时节点,该特性可以避免死锁;

    3. 当节点的状态发生变化时,zk的watch机制会通知监听相应事件的客户端,该特性可以用来实现阻塞等待加锁;

    4. 客户端可以在某个节点下创建子节点,Zookeeper会根据子节点数量自动生成整数序号,类似于数据库的自增主键;

    由于需要频繁的新增和删除节点,性能比较差,不推荐使用。

    Last Updated:
    Contributors: klc407073648
    Prev
    分布式系统 - 一致性
    Next
    分布式系统 - 解决高并发、高性能、高可用