Java学习指南
  • Java 编程的逻辑
  • Java进阶
  • Java FrameWorks
  • 了解 USB Type-A,B,C 三大标准接口
  • 深入浅出DDD
  • 重构:改善既有代码的设计
  • 面试大纲
  • 云原生
    • 什么是无服务器(what is serverless)?
  • 博客
    • 深入分析Log4j 漏洞
  • 博客
    • Serverless之快速搭建Spring Boot应用
  • 博客
    • 使用 Prometheus + Grafana + Spring Boot Actuator 监控应用
  • 博客
    • 使用 Prometheus + Grafana 监控 MySQL
  • 博客
    • 使用Github Actions + Docker 部署Spring Boot应用
  • 博客
    • Redis分布式锁之Redisson的原理和实践
  • 博客
    • 数据库中的树结构应该怎样去设计
  • 学习&成长
    • 如何成为技术大牛
  • 开发工具
    • Git Commit Message Guidelines
  • 开发工具
    • git命名大全
  • 开发工具
    • Gradle vs Maven Comparison
  • 开发工具
    • Swagger2常用注解及其说明
  • 开发工具
    • 简明 VIM 练级攻略
  • 微服务
    • 十大微服务设计模式和原则
  • 微服务
    • 微服务下的身份认证和令牌管理
  • 微服务
    • 微服务坏味道之循环依赖
  • 设计模式
    • 设计模式 - JDK中的设计模式
  • 设计模式
    • 设计模式 - Java三种代理模式
  • 设计模式
    • 设计模式 - 六大设计原则
  • 设计模式
    • 设计模式 - 单例模式
  • 设计模式
    • 设计模式 - 命名模式
  • 设计模式
    • 设计模式 - 备忘录模式
  • 设计模式
    • 设计模式 - 概览
  • 设计模式
    • 设计模式 - 没用的设计模式
  • 质量&效率
    • Homebrew 替换国内镜像源
  • 质量&效率
    • 工作中如何做好技术积累
  • Java FrameWorks
    • Logback
      • 自定义 logback 日志过滤器
  • Java FrameWorks
    • Mybatis
      • MyBatis(十三) - 整合Spring
  • Java FrameWorks
    • Mybatis
      • MyBatis(十二) - 一些API
  • Java FrameWorks
    • Mybatis
      • Mybatis(一) - 概述
  • Java FrameWorks
    • Mybatis
      • Mybatis(七) - 结果集的封装与映射
  • Java FrameWorks
    • Mybatis
      • Mybatis(三) - mapper.xml及其加载机制
  • Java FrameWorks
    • Mybatis
      • Mybatis(九) - 事务
  • Java FrameWorks
    • Mybatis
      • Mybatis(二) - 全局配置文件及其加载机制
  • Java FrameWorks
    • Mybatis
      • Mybatis(五) - SqlSession执行流程
  • Java FrameWorks
    • Mybatis
      • Mybatis(八) - 缓存
  • Java FrameWorks
    • Mybatis
      • Mybatis(六) - 动态SQL的参数绑定与执行
  • Java FrameWorks
    • Mybatis
      • Mybatis(十) - 插件
  • Java FrameWorks
    • Mybatis
      • Mybatis(十一) - 日志
  • Java FrameWorks
    • Mybatis
      • Mybatis(四) - Mapper接口解析
  • Java FrameWorks
    • Netty
      • Netty 可靠性分析
  • Java FrameWorks
    • Netty
      • Netty - Netty 线程模型
  • Java FrameWorks
    • Netty
      • Netty堆外内存泄露排查盛宴
  • Java FrameWorks
    • Netty
      • Netty高级 - 高性能之道
  • Java FrameWorks
    • Shiro
      • Shiro + JWT + Spring Boot Restful 简易教程
  • Java FrameWorks
    • Shiro
      • 非常详尽的 Shiro 架构解析!
  • Java FrameWorks
    • Spring
      • Spring AOP 使用介绍,从前世到今生
  • Java FrameWorks
    • Spring
      • Spring AOP 源码解析
  • Java FrameWorks
    • Spring
      • Spring Event 实现原理
  • Java FrameWorks
    • Spring
      • Spring Events
  • Java FrameWorks
    • Spring
      • Spring IOC容器源码分析
  • Java FrameWorks
    • Spring
      • Spring Integration简介
  • Java FrameWorks
    • Spring
      • Spring MVC 框架中拦截器 Interceptor 的使用方法
  • Java FrameWorks
    • Spring
      • Spring bean 解析、注册、实例化流程源码剖析
  • Java FrameWorks
    • Spring
      • Spring validation中@NotNull、@NotEmpty、@NotBlank的区别
  • Java FrameWorks
    • Spring
      • Spring 如何解决循环依赖?
  • Java FrameWorks
    • Spring
      • Spring 异步实现原理与实战分享
  • Java FrameWorks
    • Spring
      • Spring中的“for update”问题
  • Java FrameWorks
    • Spring
      • Spring中的设计模式
  • Java FrameWorks
    • Spring
      • Spring事务失效的 8 大原因
  • Java FrameWorks
    • Spring
      • Spring事务管理详解
  • Java FrameWorks
    • Spring
      • Spring计时器StopWatch使用
  • Java FrameWorks
    • Spring
      • 详述 Spring MVC 框架中拦截器 Interceptor 的使用方法
  • Java FrameWorks
    • Spring
      • 透彻的掌握 Spring 中@transactional 的使用
  • Java
    • Java IO&NIO&AIO
      • Java IO - BIO 详解
  • Java
    • Java IO&NIO&AIO
      • Java NIO - IO多路复用详解
  • Java
    • Java IO&NIO&AIO
      • Java N(A)IO - Netty
  • Java
    • Java IO&NIO&AIO
      • Java IO - Unix IO模型
  • Java
    • Java IO&NIO&AIO
      • Java IO - 分类
  • Java
    • Java IO&NIO&AIO
      • Java NIO - 基础详解
  • Java
    • Java IO&NIO&AIO
      • Java IO - 常见类使用
  • Java
    • Java IO&NIO&AIO
      • Java AIO - 异步IO详解
  • Java
    • Java IO&NIO&AIO
      • Java IO概述
  • Java
    • Java IO&NIO&AIO
      • Java IO - 设计模式
  • Java
    • Java IO&NIO&AIO
      • Java NIO - 零拷贝实现
  • Java
    • Java JVM
      • JVM 优化经验总结
  • Java
    • Java JVM
      • JVM 内存结构
  • Java
    • Java JVM
      • JVM参数设置
  • Java
    • Java JVM
      • Java 内存模型
  • Java
    • Java JVM
      • 从实际案例聊聊Java应用的GC优化
  • Java
    • Java JVM
      • Java 垃圾回收器G1详解
  • Java
    • Java JVM
      • 垃圾回收器Shenandoah GC详解
  • Java
    • Java JVM
      • 垃圾回收器ZGC详解
  • Java
    • Java JVM
      • 垃圾回收基础
  • Java
    • Java JVM
      • 如何优化Java GC
  • Java
    • Java JVM
      • 类加载机制
  • Java
    • Java JVM
      • 类字节码详解
  • Java
    • Java 基础
      • Java hashCode() 和 equals()
  • Java
    • Java 基础
      • Java 基础 - Java native方法以及JNI实践
  • Java
    • Java 基础
      • Java serialVersionUID 有什么作用?
  • Java
    • Java 基础
      • Java 泛型的类型擦除
  • Java
    • Java 基础
      • Java 基础 - Unsafe类解析
  • Java
    • Java 基础
      • Difference Between Statement and PreparedStatement
  • Java
    • Java 基础
      • Java 基础 - SPI机制详解
  • Java
    • Java 基础
      • Java 基础 - final
  • Java
    • Java 基础
      • Java中static关键字详解
  • Java
    • Java 基础
      • 为什么说Java中只有值传递?
  • Java
    • Java 基础
      • Java 基础 - 即时编译器原理解析及实践
  • Java
    • Java 基础
      • Java 基础 - 反射
  • Java
    • Java 基础
      • Java多态的面试题
  • Java
    • Java 基础
      • Java 基础 - 异常机制详解
  • Java
    • Java 基础
      • 为什么要有抽象类?
  • Java
    • Java 基础
      • 接口的本质
  • Java
    • Java 基础
      • Java 基础 - 枚举
  • Java
    • Java 基础
      • Java 基础 - 泛型机制详解
  • Java
    • Java 基础
      • Java 基础 - 注解机制详解
  • Java
    • Java 基础
      • 为什么 String hashCode 方法选择数字31作为乘子
  • Java
    • Java 并发
      • Java 并发 - 14个Java并发容器
  • Java
    • Java 并发
      • Java 并发 - AQS
  • Java
    • Java 并发
      • Java 并发 - BlockingQueue
  • Java
    • Java 并发
      • Java 并发 - CAS
  • Java
    • Java 并发
      • Java 并发 - Condition接口
  • Java
    • Java 并发
      • Java 并发 - CopyOnWriteArrayList
  • Java
    • Java 并发
      • Java 并发 - CountDownLatch、CyclicBarrier和Phaser对比
  • Java
    • Java 并发
      • Java 并发 - Fork&Join框架
  • Java
    • Java 并发
      • Java 并发 - Java CompletableFuture 详解
  • Java
    • Java 并发
      • Java 并发 - Java 线程池
  • Java
    • Java 并发
      • Java 并发 - Lock接口
  • Java
    • Java 并发
      • Java 并发 - ReentrantLock
  • Java
    • Java 并发
      • Java 并发 - ReentrantReadWriteLock
  • Java
    • Java 并发
      • Java 并发 - Synchronized
  • Java
    • Java 并发
      • Java 并发 - ThreadLocal 内存泄漏问题
  • Java
    • Java 并发
      • Java 并发 - ThreadLocal
  • Java
    • Java 并发
      • Java 并发 - Volatile
  • Java
    • Java 并发
      • Java 并发 - 从ReentrantLock的实现看AQS的原理及应用
  • Java
    • Java 并发
      • Java 并发 - 公平锁和非公平锁
  • Java
    • Java 并发
      • Java 并发 - 内存模型
  • Java
    • Java 并发
      • Java 并发 - 原子类
  • Java
    • Java 并发
      • Java 并发 - 如何确保三个线程顺序执行?
  • Java
    • Java 并发
      • Java 并发 - 锁
  • Java
    • Java 的新特性
      • Java 10 新特性概述
  • Java
    • Java 的新特性
      • Java 11 新特性概述
  • Java
    • Java 的新特性
      • Java 12 新特性概述
  • Java
    • Java 的新特性
      • Java 13 新特性概述
  • Java
    • Java 的新特性
      • Java 14 新特性概述
  • Java
    • Java 的新特性
      • Java 15 新特性概述
  • Java
    • Java 的新特性
      • Java 8的新特性
  • Java
    • Java 的新特性
      • Java 9 新特性概述
  • Java
    • Java 调试排错
      • 调试排错 - Java Debug Interface(JDI)详解
  • Java
    • Java 调试排错
      • 调试排错 - CPU 100% 排查优化实践
  • Java
    • Java 调试排错
      • 调试排错 - Java Heap Dump分析
  • Java
    • Java 调试排错
      • 调试排错 - Java Thread Dump分析
  • Java
    • Java 调试排错
      • 调试排错 - Java动态调试技术原理
  • Java
    • Java 调试排错
      • 调试排错 - Java应用在线调试Arthas
  • Java
    • Java 调试排错
      • 调试排错 - Java问题排查:工具单
  • Java
    • Java 调试排错
      • 调试排错 - 内存溢出与内存泄漏
  • Java
    • Java 调试排错
      • 调试排错 - 在线分析GC日志的网站GCeasy
  • Java
    • Java 调试排错
      • 调试排错 - 常见的GC问题分析与解决
  • Java
    • Java 集合
      • Java 集合 - ArrayList
  • Java
    • Java 集合
      • Java 集合 - HashMap 和 ConcurrentHashMap
  • Java
    • Java 集合
      • Java 集合 - HashMap的死循环问题
  • Java
    • Java 集合
      • Java 集合 - LinkedHashSet&Map
  • Java
    • Java 集合
      • Java 集合 - LinkedList
  • Java
    • Java 集合
      • Java 集合 - PriorityQueue
  • Java
    • Java 集合
      • Java 集合 - Stack & Queue
  • Java
    • Java 集合
      • Java 集合 - TreeSet & TreeMap
  • Java
    • Java 集合
      • Java 集合 - WeakHashMap
  • Java
    • Java 集合
      • Java 集合 - 为什么HashMap的容量是2的幂次方
  • Java
    • Java 集合
      • Java 集合 - 概览
  • Java
    • Java 集合
      • Java 集合 - 高性能队列Disruptor详解
  • 分布式
    • RPC
      • ⭐️RPC - Dubbo&hsf&Spring cloud的区别
  • 分布式
    • RPC
      • ⭐️RPC - Dubbo的架构原理
  • 分布式
    • RPC
      • ⭐️RPC - HSF的原理分析
  • 分布式
    • RPC
      • ⭐️RPC - 你应该知道的RPC原理
  • 分布式
    • RPC
      • ⭐️RPC - 动态代理
  • 分布式
    • RPC
      • 深入理解 RPC 之协议篇
  • 分布式
    • RPC
      • RPC - 序列化和反序列化
  • 分布式
    • RPC
      • ⭐️RPC - 服务注册与发现
  • 分布式
    • RPC
      • RPC - 核心原理
  • 分布式
    • RPC
      • ⭐️RPC - 框架对比
  • 分布式
    • RPC
      • ⭐️RPC - 网络通信
  • 分布式
    • 分布式事务
      • 分布式事务 Seata TCC 模式深度解析
  • 分布式
    • 分布式事务
      • 分布式事务的实现原理
  • 分布式
    • 分布式事务
      • 常用的分布式事务解决方案
  • 分布式
    • 分布式事务
      • 手写实现基于消息队列的分布式事务框架
  • 分布式
    • 分布式算法
      • CAP 定理的含义
  • 分布式
    • 分布式算法
      • Paxos和Raft比较
  • 分布式
    • 分布式算法
      • 分布式一致性与共识算法
  • 分布式
    • 分布式锁
      • ⭐️分布式锁的原理及实现方式
  • 分布式
    • 搜索引擎
      • ElasticSearch与SpringBoot的集成与JPA方法的使用
  • 分布式
    • 搜索引擎
      • 全文搜索引擎 Elasticsearch 入门教程
  • 分布式
    • 搜索引擎
      • 十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统
  • 分布式
    • 搜索引擎
      • 腾讯万亿级 Elasticsearch 技术解密
  • 分布式
    • 日志系统
      • Grafana Loki 简明教程
  • 分布式
    • 日志系统
      • 分布式系统中如何优雅地追踪日志
  • 分布式
    • 日志系统
      • 如何优雅地记录操作日志?
  • 分布式
    • 日志系统
      • 日志收集组件—Flume、Logstash、Filebeat对比
  • 分布式
    • 日志系统
      • 集中式日志系统 ELK 协议栈详解
  • 分布式
    • 消息队列
      • 消息队列 - Kafka
  • 分布式
    • 消息队列
      • 消息队列 - Kafka、RabbitMQ、RocketMQ等消息中间件的对比
  • 分布式
    • 消息队列
      • 消息队列之 RabbitMQ
  • 分布式
    • 消息队列
      • 消息队列 - 使用docker-compose构建kafka集群
  • 分布式
    • 消息队列
      • 消息队列 - 分布式系统与消息的投递
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息的可靠性传输
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息的顺序性
  • 分布式
    • 消息队列
      • 消息队列 - 如何保证消息队列的高可用
  • 分布式
    • 消息队列
      • 消息队列 - 消息队列设计精要
  • 分布式
    • 监控系统
      • 深度剖析开源分布式监控CAT
  • 大数据
    • Flink
      • Flink架构与核心组件
  • 微服务
    • Dubbo
      • 基于dubbo的分布式应用中的统一异常处理
  • 微服务
    • Dubbo
      • Vim快捷键
  • 微服务
    • Service Mesh
      • Istio 是什么?
  • 微服务
    • Service Mesh
      • OCTO 2.0:美团基于Service Mesh的服务治理系统详解
  • 微服务
    • Service Mesh
      • Service Mesh是什么?
  • 微服务
    • Service Mesh
      • Spring Cloud向Service Mesh迁移
  • 微服务
    • Service Mesh
      • 数据挖掘算法
  • 微服务
    • Service Mesh
      • Seata Saga 模式
  • 微服务
    • Spring Cloud
      • Seata TCC 模式
  • 微服务
    • Spring Cloud
      • Spring Cloud Config
  • 微服务
    • Spring Cloud
      • Seata AT 模式
  • 微服务
    • Spring Cloud
      • Spring Cloud Gateway
  • 微服务
    • Spring Cloud
      • Spring Cloud OpenFeign 的核心原理
  • 微服务
    • Spring Cloud
      • Seata XA 模式
  • 数据库
    • Database Version Control
      • Liquibase vs. Flyway
  • 数据库
    • Database Version Control
      • Six reasons to version control your database
  • 数据库
    • MySQL
      • How Sharding Works
  • 数据库
    • MySQL
      • MySQL InnoDB中各种SQL语句加锁分析
  • 数据库
    • MySQL
      • MySQL 事务隔离级别和锁
  • 数据库
    • MySQL
      • MySQL 索引性能分析概要
  • 数据库
    • MySQL
      • MySQL 索引设计概要
  • 数据库
    • MySQL
      • MySQL出现Waiting for table metadata lock的原因以及解决方法
  • 数据库
    • MySQL
      • MySQL的Limit性能问题
  • 数据库
    • MySQL
      • MySQL索引优化explain
  • 数据库
    • MySQL
      • MySQL索引背后的数据结构及算法原理
  • 数据库
    • MySQL
      • MySQL行转列、列转行问题
  • 数据库
    • MySQL
      • 一条SQL更新语句是如何执行的?
  • 数据库
    • MySQL
      • 一条SQL查询语句是如何执行的?
  • 数据库
    • MySQL
      • 为什么 MySQL 使用 B+ 树
  • 数据库
    • MySQL
      • 为什么 MySQL 的自增主键不单调也不连续
  • 数据库
    • MySQL
      • 为什么我的MySQL会“抖”一下?
  • 数据库
    • MySQL
      • 为什么数据库不应该使用外键
  • 数据库
    • MySQL
      • 为什么数据库会丢失数据
  • 数据库
    • MySQL
      • 事务的可重复读的能力是怎么实现的?
  • 数据库
    • MySQL
      • 大众点评订单系统分库分表实践
  • 数据库
    • MySQL
      • 如何保证缓存与数据库双写时的数据一致性?
  • 数据库
    • MySQL
      • 浅谈数据库并发控制 - 锁和 MVCC
  • 数据库
    • MySQL
      • 深入浅出MySQL 中事务的实现
  • 数据库
    • MySQL
      • 浅入浅出MySQL 和 InnoDB
  • 数据库
    • PostgreSQL
      • PostgreSQL upsert功能(insert on conflict do)的用法
  • 数据库
    • Redis
      • Redis GEO & 实现原理深度分析
  • 数据库
    • Redis
      • Redis 和 I/O 多路复用
  • 数据库
    • Redis
      • Redis分布式锁
  • 数据库
    • Redis
      • Redis实现分布式锁中的“坑”
  • 数据库
    • Redis
      • Redis总结
  • 数据库
    • Redis
      • 史上最全Redis高可用技术解决方案大全
  • 数据库
    • Redis
      • Redlock:Redis分布式锁最牛逼的实现
  • 数据库
    • Redis
      • 为什么 Redis 选择单线程模型
  • 数据库
    • TiDB
      • 新一代数据库TiDB在美团的实践
  • 数据库
    • 数据仓库
      • 实时数仓在有赞的实践
  • 数据库
    • 数据库原理
      • OLTP与OLAP的关系是什么?
  • 数据库
    • 数据库原理
      • 为什么 OLAP 需要列式存储
  • 系统设计
    • DDD
      • Domain Primitive
  • 系统设计
    • DDD
      • Repository模式
  • 系统设计
    • DDD
      • 应用架构
  • 系统设计
    • DDD
      • 聊聊如何避免写流水账代码
  • 系统设计
    • DDD
      • 领域层设计规范
  • 系统设计
    • DDD
      • 从三明治到六边形
  • 系统设计
    • DDD
      • 阿里盒马领域驱动设计实践
  • 系统设计
    • DDD
      • 领域驱动设计(DDD)编码实践
  • 系统设计
    • DDD
      • 领域驱动设计在互联网业务开发中的实践
  • 系统设计
    • 基础架构
      • 容错,高可用和灾备
  • 系统设计
    • 数据聚合
      • GraphQL及元数据驱动架构在后端BFF中的实践
  • 系统设计
    • 数据聚合
      • 高效研发-闲鱼在数据聚合上的探索与实践
  • 系统设计
    • 服务安全
      • JSON Web Token 入门教程
  • 系统设计
    • 服务安全
      • 你还在用JWT做身份认证嘛?
  • 系统设计
    • 服务安全
      • 凭证(Credentials)
  • 系统设计
    • 服务安全
      • 授权(Authorization)
  • 系统设计
    • 服务安全
      • 理解OAuth2.0
  • 系统设计
    • 服务安全
      • 认证(Authentication)
  • 系统设计
    • 架构案例
      • 微信 Android 客户端架构演进之路
  • 系统设计
    • 高可用架构
      • 业务高可用的保障:异地多活架构
  • 计算机基础
    • 字符编码
      • Base64原理解析
  • 计算机基础
    • 字符编码
      • 字符编码笔记:ASCII,Unicode 和 UTF-8
  • 计算机基础
    • 操作系统
      • 为什么 CPU 访问硬盘很慢
  • 计算机基础
    • 操作系统
      • 为什么 HTTPS 需要 7 次握手以及 9 倍时延
  • 计算机基础
    • 操作系统
      • 为什么 Linux 默认页大小是 4KB
  • 计算机基础
    • 操作系统
      • 磁盘IO那些事
  • 计算机基础
    • 操作系统
      • 虚拟机的3种网络模式
  • 计算机基础
    • 服务器
      • mac终端bash、zsh、oh-my-zsh最实用教程
  • 计算机基础
    • 服务器
      • Nginx强制跳转Https
  • 计算机基础
    • 服务器
      • curl 的用法指南
  • 计算机基础
    • 网络安全
      • 如何设计一个安全的对外接口?
  • 计算机基础
    • 网络安全
      • 浅谈常见的七种加密算法及实现
  • 计算机基础
    • 网络编程
      • MQTT - The Standard for IoT Messaging
  • 计算机基础
    • 网络编程
      • 两万字长文 50+ 张趣图带你领悟网络编程的内功心法
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有 TIME_WAIT 状态
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有性能问题
  • 计算机基础
    • 网络编程
      • 为什么 TCP 协议有粘包问题
  • 计算机基础
    • 网络编程
      • 为什么 TCP 建立连接需要三次握手
  • 计算机基础
    • 网络编程
      • 为什么 TCP/IP 协议会拆分数据
  • 计算机基础
    • 网络编程
      • 使用 OAuth 2 和 JWT 为微服务提供安全保障
  • 计算机基础
    • 网络编程
      • 四种常见的 POST 提交数据方式
  • 计算机基础
    • 网络编程
      • 有赞TCP网络编程最佳实践
  • 计算机基础
    • 网络编程
      • 看完这篇HTTP,跟面试官扯皮就没问题了
  • 计算机基础
    • 网络编程
      • 详细解析 HTTP 与 HTTPS 的区别
  • 质量&效率
    • 快捷键
      • Idea快捷键(Mac版)
  • 质量&效率
    • 快捷键
      • Shell快捷键
  • 质量&效率
    • 快捷键
      • conduit
  • 质量&效率
    • 敏捷开发
      • Scrum的3种角色
  • 质量&效率
    • 敏捷开发
      • Scrum的4种会议
  • 质量&效率
    • 敏捷开发
      • ThoughtWorks的敏捷开发
  • 质量&效率
    • 敏捷开发
      • 敏捷开发入门教程
  • 运维&测试
    • Docker
      • Docker (容器) 的原理
  • 运维&测试
    • Docker
      • Docker Compose:链接外部容器的几种方式
  • 运维&测试
    • Docker
      • Docker 入门教程
  • 运维&测试
    • Docker
      • Docker 核心技术与实现原理
  • 运维&测试
    • Docker
      • Dockerfile 最佳实践
  • 运维&测试
    • Docker
      • Docker开启Remote API 访问 2375端口
  • 运维&测试
    • Docker
      • Watchtower - 自动更新 Docker 镜像与容器
  • 运维&测试
    • Kubernetes
      • Kubernetes 介绍
  • 运维&测试
    • Kubernetes
      • Kubernetes 在有赞的实践
  • 运维&测试
    • Kubernetes
      • Kubernetes 学习路径
  • 运维&测试
    • Kubernetes
      • Kubernetes如何改变美团的云基础设施?
  • 运维&测试
    • Kubernetes
      • Kubernetes的三种外部访问方式:NodePort、LoadBalancer 和 Ingress
  • 运维&测试
    • Kubernetes
      • 谈 Kubernetes 的架构设计与实现原理
  • 运维&测试
    • 压测
      • 全链路压测平台(Quake)在美团中的实践
  • 运维&测试
    • 测试
      • Cpress - JavaScript End to End Testing Framework
  • 运维&测试
    • 测试
      • 代码覆盖率-JaCoCo
  • 运维&测试
    • 测试
      • 浅谈代码覆盖率
  • 运维&测试
    • 测试
      • 测试中 Fakes、Mocks 以及 Stubs 概念明晰
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP中的Bean是如何被AOP代理的
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP原生动态代理和Cglib动态代理
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP实现方式(xml&注解)
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP是如何收集切面类并封装的
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP概述
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP的底层核心后置处理器
  • Java FrameWorks
    • Spring
      • Spring AOP
        • Spring AOP的延伸知识
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(一)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(三)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(二)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(五)
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - IOC(四) - 循环依赖与解决方案
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot - 启动引导
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot JarLauncher
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot Web Mvc 自动装配
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 使用ApplicationListener监听器
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 声明式事务
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot 嵌入式容器
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot引起的“堆外内存泄漏”排查及经验总结
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot的启动流程
  • Java FrameWorks
    • Spring
      • Spring Boot
        • Spring Boot自动化配置源码分析
  • Java FrameWorks
    • Spring
      • Spring Boot
        • 如何自定义Spring Boot Starter?
  • Java FrameWorks
    • Spring
      • Spring IOC
        • IOC - 模块装配和条件装配
  • Java FrameWorks
    • Spring
      • Spring IOC
        • IOC - 配置源(xml,注解)
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Environment
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring ApplicationContext
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanDefinition
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanFactory
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanFactoryPostProcessor
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring BeanPostProcessor
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(一) - 概述
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(三) - 实例化阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(二) - BeanDefinition
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(五) - 销毁阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Bean的生命周期(四) - 初始化阶段
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring ComponentScan
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Events
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 基础篇
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 总结
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC 进阶篇
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring IOC容器的生命周期
  • Java FrameWorks
    • Spring
      • Spring IOC
        • Spring Resource
  • Java FrameWorks
    • Spring
      • Spring MVC
        • DispatcherServlet的初始化原理
  • Java FrameWorks
    • Spring
      • Spring MVC
        • DispatcherServlet的核心工作原理
  • Java FrameWorks
    • Spring
      • Spring MVC
        • WebMvc的架构设计与组件功能解析
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Boot 2 + Spring Security 5 + JWT 的单页应用 Restful 解决方案
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Security Oauth
  • Java FrameWorks
    • Spring
      • Spring Security
        • Spring Security
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • DispatcherHandler的工作原理(传统方式)
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • DispatcherHandler的工作原理(函数式端点)
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • WebFlux的自动装配
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • 快速了解响应式编程与Reactive
  • Java FrameWorks
    • Spring
      • Spring WebFlux
        • 快速使用WebFlux
  • 分布式
    • 协调服务
      • Zookeeper
        • Zookeeper - 客户端之 Curator
  • 分布式
    • 协调服务
      • Zookeeper
        • 详解分布式协调服务 ZooKeeper
  • 分布式
    • 协调服务
      • etcd
        • 高可用分布式存储 etcd 的实现原理
  • 数据库
    • Database Version Control
      • Flyway
        • Database Migrations with Flyway
  • 数据库
    • Database Version Control
      • Flyway
        • How Flyway works
  • 数据库
    • Database Version Control
      • Flyway
        • Rolling Back Migrations with Flyway
  • 数据库
    • Database Version Control
      • Flyway
        • The meaning of the concept of checksums
  • 数据库
    • Database Version Control
      • Liquibase
        • Introduction to Liquibase Rollback
  • 数据库
    • Database Version Control
      • Liquibase
        • LiquiBase中文学习指南
  • 数据库
    • Database Version Control
      • Liquibase
        • Use Liquibase to Safely Evolve Your Database Schema
  • 系统设计
    • 流量控制
      • RateLimiter
        • Guava Rate Limiter实现分析
  • 系统设计
    • 流量控制
      • Sentinel
        • Sentinel 与 Hystrix 的对比
  • 系统设计
    • 流量控制
      • Sentinel
        • Sentinel工作主流程
  • 系统设计
    • 流量控制
      • 算法
        • 分布式服务限流实战
  • 系统设计
    • 解决方案
      • 秒杀系统
        • 如何设计一个秒杀系统
  • 系统设计
    • 解决方案
      • 红包系统
        • 微信高并发资金交易系统设计方案--百亿红包背后的技术支撑
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 什么是预排序遍历树算法(MPTT,Modified Preorder Tree Traversal)
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 加密算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 推荐系统算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • linkerd
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 查找算法
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 缓存淘汰算法中的LRU和LFU
  • 计算机基础
    • 数据结构与算法
      • 其他相关
        • 负载均衡算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Paxos算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Raft算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - Snowflake算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - ZAB算法
  • 计算机基础
    • 数据结构与算法
      • 分布式算法
        • 分布式算法 - 一致性Hash算法
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Bitmap & Bloom Filter
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Map & Reduce
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - Trie树/数据库/倒排索引
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 分治/hash/排序
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 双层桶划分
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 外(磁盘文件)排序
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理 - 布隆过滤器
  • 计算机基础
    • 数据结构与算法
      • 大数据处理
        • 大数据处理算法
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 文本预处理:后缀树(Suffix Tree)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:BM 算法 (Boyer-Moore)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:KMP 算法(Knuth-Morris-Pratt)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配 - 模式预处理:朴素算法(Naive)(暴力破解)
  • 计算机基础
    • 数据结构与算法
      • 字符串匹配算法
        • 字符串匹配
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 分支限界算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 分治算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 动态规划算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 回溯算法
  • 计算机基础
    • 数据结构与算法
      • 常用算法
        • 贪心算法
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 十大排序算法
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(一)之3种简单排序(选择,冒泡,直接插入)
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(三)之堆排序
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(二)之希尔排序
  • 计算机基础
    • 数据结构与算法
      • 排序算法
        • 图解排序算法(四)之归并排序
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 树的高度和深度
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 红黑树深入剖析及Java实现
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 线性结构 - Hash
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 线性结构 - 数组、链表、栈、队列
  • 计算机基础
    • 数据结构与算法
      • 数据结构
        • 逻辑结构 - 树
  • 运维&测试
    • 测试
      • Spock
        • Groovy 简明教程
  • 运维&测试
    • 测试
      • Spock
        • Spock 官方文档
  • 运维&测试
    • 测试
      • Spock
        • Spock单元测试框架介绍以及在美团优选的实践
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(一)
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(三)
  • 运维&测试
    • 测试
      • TDD
        • TDD 实践 - FizzFuzzWhizz(二)
  • 运维&测试
    • 测试
      • TDD
        • 测试驱动开发(TDD)- 原理篇
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Nacos
          • Nacos 服务注册的原理
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Nacos
          • Nacos 配置中心原理分析
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • 服务调用过程
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Bus
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Consul
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Seata
          • Spring Cloud Stream
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Sentinel
          • Sentinel 与 Hystrix 的对比
  • 微服务
    • Spring Cloud
      • Spring Cloud Alibaba
        • Sentinel
          • Sentinel
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • How Hystrix Works
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Hystrix
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Hystrix原理与实战
  • 微服务
    • Spring Cloud
      • Spring Cloud Netflix
        • Hystrix
          • Spring Cloud Hystrix基本原理
由 GitBook 提供支持
在本页
  • 1. 分布式一致性
  • 1.1 CAP
  • 1.2 拜占庭将军问题
  • 1.3 FLP
  • 2. 共识算法
  • 2.1 Paxos 和 Raft
  • 2.2 POW(Proof-of-Work)
  • 2.3 POS(Proof-of-Stake)
  • 2.4 DPOS(Delegated Proof-of-Stake)
  • 3. 总结
  • 4. Reference

这有帮助吗?

  1. 分布式
  2. 分布式算法

分布式一致性与共识算法

上一页分布式算法下一页分布式

最后更新于2年前

这有帮助吗?

转载:分布式一致性与共识算法

  • 分布式一致性与共识算法

  • UTXO 与账户余额模型

区块链技术是近几年逐渐变得非常热门的技术,以比特币为首的密码货币其实已经被无数人所知晓,但是却很少有人会去研究它们的底层技术,也就是作为一个分布式网络比特币等加密货币是如何工作的。

2020-07-23-eUFXtQ

无论是 Bitcoin、Ethereum 还是 EOS,作为一个分布式网络,首先需要解决分布式一致性的问题,也就是所有的节点如何对同一个提案或者值达成共识,这一问题在一个所有节点都是可以被信任的分布式集群中都是一个比较难以解决的问题,更不用说在复杂的区块链网络中了。

1. 分布式一致性

在一个分布式系统中,如何保证集群中所有节点中的数据完全相同并且能够对某个提案(Proposal)达成一致是分布式系统正常工作的核心问题,而共识算法就是用来保证分布式系统一致性的方法。

然而分布式系统由于引入了多个节点,所以系统中会出现各种非常复杂的情况;随着节点数量的增加,节点失效、故障或者宕机就变成了一件非常常见的事情,解决分布式系统中的各种边界条件和意外情况也增加了解决分布式一致性问题的难度。

在一个分布式系统中,除了节点的失效是会导致一致性不容易达成的主要原因之外,节点之间的网络通信收到干扰甚至阻断以及分布式系统的运行速度的差异都是解决分布式系统一致性所面临的难题。

1.1 CAP

在 1998 年的秋天,加州伯克利大学的教授 Eric Brewer 第一次发布了 CAP 理论,在 1999 年论文 Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services 正式发布,其中总结了 Eric Brewer 提出的 CAP 理论。

这篇论文证明了两个非常有意思的理论,首先是在异步的网络模型中,所有的节点由于没有时钟仅仅能根据接收到的消息作出判断,这时完全不能同时保证一致性、可用性和分区容错性,每一个系统只能在这三种特性中选择两种。

不过这里讨论的一致性其实都是强一致性,也就是所有节点接收到同样的操作时会按照完全相同的顺序执行,被一个节点提交的更新操作会立刻反映在其他通过异步或部分同步网络连接的节点上,如果想要同时满足一致性和分区容错性,在异步的网络中,我们只能中心化存储所有数据,通过其他节点将请求路由给中心节点达到这两个目的。

但是在现实世界中其实并不存在绝对异步的网络环境,如果我们允许每一个节点拥有自己的时钟,这些时钟虽然有着完全不同的时间,但是它们的更新频率是完全相同的,所以我们可以通过时钟得知接收消息的间隔时间,在这种更宽松的前提下,我们能够得到更强大的服务。

然而在部分同步的网络环境中,我们仍然没有办法同时保证一致性、可用性和分区容错性,证明的过程其实非常简单,可以直接阅读 论文 的 4.2 节,然而时钟的出现能够让我们知道当前消息有多久没有得到回应,通过超时时间就能在一定程度上解决信息丢失的问题。

由于网络一定会存在延时,所以没有办法在分布式系统中做到强一致性的同时保证可用性,不过我们可以通过降低对一致性的要求,在一致性和可用性之间做出权衡,而这其实也是设计分布式系统首先需要考虑的问题,由于强一致性的系统会导致系统的可用性降低,仅仅将接受请求的工作交给其他节点对于高并发的服务并不能解决问题,所以在目前主流的分布式系统中都选择最终一致性。

最终一致性允许多个节点的状态出现冲突,但是所有能够沟通的节点都能够在有限的时间内解决冲突,从不一致的状态恢复到一致,这里列出的两个条件比较重要,一是节点直接可以正常通信,二是冲突需要在有限的时间内解决,只有在这两个条件成立时才能达到最终一致性。

1.2 拜占庭将军问题

拜占庭将军问题是 Leslie Lamport 在 The Byzantine Generals Problem 论文中提出的分布式领域的容错问题,它是分布式领域中最复杂、最严格的容错模型。

在该模型下,系统不会对集群中的节点做任何的限制,它们可以向其他节点发送随机数据、错误数据,也可以选择不响应其他节点的请求,这些无法预测的行为使得容错这一问题变得更加复杂。

拜占庭将军问题描述了一个如下的场景,有一组将军分别指挥一部分军队,每一个将军都不知道其它将军是否是可靠的,也不知道其他将军传递的信息是否可靠,但是它们需要通过投票选择是否要进攻或者撤退:

在这一节中,黄色代表状态未知,绿色代表进攻,蓝色代表撤退,最后红色代表当前将军的信息不可靠。

在这时,无论将军是否可靠,只要所有的将军达成了统一的方案,选择进攻或者撤退其实就是没有任何问题的:

上述的情况不会对当前的战局有太多的影响,也不会造成损失,但是如果其中的一个将军告诉其中一部分将军选择进攻、另一部分选择撤退,就会出现非常严重的问题了。

由于将军的队伍中出了一个叛徒或者信息在传递的过程中被拦截,会导致一部分将军会选择进攻,剩下的一部分会选择撤退,它们都认为自己的选择是大多数人的选择,这时就出现了严重的不一致问题。

拜占庭将军问题是对分布式系统容错的最高要求,然而这不是日常工作中使用的大多数分布式系统中会面对的问题,我们遇到更多的还是节点故障宕机或者不响应等情况,这就大大简化了系统对容错的要求;不过类似 Bitcoin、Ethereum 等分布式系统确实需要考虑拜占庭容错的问题,我们会在下面介绍它们是如何解决的。

1.3 FLP

FLP 不可能定理是分布式系统领域最重要的定理之一,它给出了一个非常重要的结论:在网络可靠并且存在节点失效的异步模型系统中,不存在一个可以解决一致性问题的确定性算法。

In this paper, we show the surprising result that no completely asynchronous consensus protocol can tolerate even a single unannounced process death. We do not consider Byzantine failures, and we assume that the message system is reliable it delivers all messages correctly and exactly once.

这个定理其实也就是告诉我们不要浪费时间去为异步分布式系统设计在任意场景上都能够实现共识的算法,异步系统完全没有办法保证能在有限时间内达成一致,在这里作者并不会尝试去证明 FLP 不可能定理,读者可以阅读相关论文 Impossibility of Distributed Consensuswith One Faulty Process 了解更多的内容。

2. 共识算法

在上一节中,我们已经简单了解了分布式系统中面对的问题与挑战,在这里我们会介绍不同共识算法的实现原理,包括传统分布式系统领域的 Paxos、Raft 以及密码货币中使用的工作量证明(POW)、权益证明(POS)和委托权益证明(DPOS),通过对这些共识算法原理的介绍和分析,我相信各位读者能对分布式一致性和共识算法有更深的理解。

2.1 Paxos 和 Raft

Paxos 和 Raft 是目前分布式系统领域中两种非常著名的解决一致性问题的共识算法,两者都能解决分布式系统中的一致性问题,但是前者的实现与证明非常难以理解,后者的实现比较简洁并且遵循人的直觉,它的出现就是为了解决 Paxos 难以理解并和难以实现的问题。

我们先来简单介绍一下 Paxos 究竟是什么,Paxos 其实是一类能够解决分布式一致性问题的协议,它能够让分布式网络中的节点在出现错误时仍然保持一致;Leslie Lamport 提出的 Paxos 可以在没有恶意节点的前提下保证系统中节点的一致性,也是第一个被证明完备的共识算法,目前的完备的共识算法包括 Raft 本质上都是 Paxos 的变种。

作为一类协议,Paxos 中包含 Basic Paxos、Multi-Paxos、Cheap Paxos 和其他的变种,在这一小节我们会简单介绍 Basic Paxos 和 Multi-Paxos 这两种协议。

2.1.1 Basic Paxos

Basic Paxos 是 Paxos 中最为基础的协议,每一个 Basic Paxos 的协议实例最终都会选择唯一一个结果;使用 Paxos 作为共识算法的分布式系统中,节点都会有三种身份,分别是 Proposer、Acceptor 和 Learner:

我们在这里会忽略最后一种身份 Learner 简化协议的运行过程,便于读者理解;Paxos 的运行过程分为两个阶段,分别是准备阶段(Prepare)和接受阶段(Accept),当 Proposer 接收到来自客户端的请求时,就会进入如下流程:

以上截图取自 Paxos lecture (Raft user study) 的第 12 页。

阶段1

  • 阶段1A:Prepare

    在Prepare阶段,一个Proposer会创建一个Prepare消息,每个Prepare消息都有唯一的提案编号n。n并不是将要提案的内容,而只是一个唯一的编号,用来标志这个Prepare的消息。 n必须比该Proposer之前用过的所有编号都大,一般来说我们可以以数字递增的方式来实现这个编号。 接下来Proposer会把该编号发送给Acceptors,只有大多数Acceptors接收到Proposer发来的消息,该消息才算是发送成功。

  • 阶段1B:Promise 所有的Acceptors都在等待从Proposers发过来的Prepare消息。当一个Acceptor收到从Proposer发过来的Prepare消息时候,会有两种情况:

    • 该消息中的n是Acceptor所有收到的Prepare消息中最大的一个,那么该Acceptor必须返回一个Promise消息给Proposer,告诉它后面所有小于n的消息我都会忽略掉。如果该Acceptor在过去的某个时间已经确认了某个消息,那么它必须返回那个消息的proposal number m 和 accepted value w (m,w)。如果该Acceptor在过去并没有确认过任何消息,那么会返回NULL。

    • 如果Prepare消息中的n小于该Acceptor之前接收到的消息,那么该消息会被Acceptor忽略(为了优化也可以返回一个拒绝消息给Proposer,告诉它不要再发小于n的消息给我了)。

阶段2

  • 阶段2A:Accept 如果一个Proposer从Acceptors接收到了足够多的Promises(>n/2),这表示该Proposer可以开始下一个Accept请求的阶段了,在Accept阶段,Proposer需要设置一个值,然后向Acceptors发送Accept请求。 在阶段1B我们讲到了,如果Acceptor之前确认过消息,那么会把该消息编号和消息的值(m,w)返回给Proposer, Proposer收到多个Acceptors返回过来的消息之后,会从中选择编号最大的一个消息所对应的值z,并把他作为Accept请求的值(n,z)发给Acceptor。如果所有的Acceptors都没有确认过消息,那么Proposer可以自主选择要确认的值z。

  • 阶段 2b: Accepted 当Acceptor接收到了Proposer的确认消息请求(n,z),如果该Acceptor在阶段1b的时候没有promise只接收>n的消息,那么该(n,z)消息就必须被Acceptor确认。 当(n,z)消息被Acceptor确认时,Acceptor会发送一个Accepted(n,z)消息给Proposer 和所有的Learner。当然在大部分情况下Proposer和Learner这两个角色可以合并。 如果该Acceptor在阶段1b的时候promise只接收>n的消息,那么该确认请求消息会被拒绝或者忽略。 按照以上的逻辑就会出现在一个轮次中,Acceptor 确认多次消息的情况。什么情况下才会出现这样的情况呢? 我们举个例子: Acceptor 收到Accept(n,z),然后返回了Accepted(n,z),接下来该Acceptor 又收到了Prepare(n+1)请求,按照阶段1B的原则,Acceptor会 Promise (n+1,z),然后Acceptor 收到Accept(n+1,z),最后返回Accepted(n+1,z)。大家可以看到尽管Acceptor 确认了多次请求,但是最终会确保确认的值是保持一致的。

这个过程在任何时候中断都可以保证正确性。例如如果一个proposer发现已经有其他proposers提出了编号更高的提案,则有必要中断这个过程。因此为了优化,在上述prepare过程中,如果一个acceptor发现存在一个更高编号的提案,则需要通知proposer,提醒其中断这次提案。

在整个共识算法运行的过程中,Proposer 负责提出提案并向 Acceptor 分别发出两次 RPC 请求,Prepare 和 Accept;Acceptor 会根据其持有的信息 minProposal、acceptedProposal 和 acceptedValue 选择接受或者拒绝当前的提案,当某一个提案被过半数的 Acceptor 接受之后,我们就认为当前提案被整个集群接受了。

我们简单举一个例子介绍 Paxos 是如何在多个提案下保证最终能够达到一致性的,上述图片中 S1 和 S5 分别收到了来自客户端的请求 X 和 Y,S1 首先向 S2 和 S3 发出 Prepare RPC 和 Accept RPC,三个服务器都接受了 S1 的提案 X;在这之后,S5 向 S3 和 S4 服务器发出 Prepare(2.5) 的请求,S3 由于已经接受了 X,所以它会返回接受的提案和值 (1.1, X),这时服务器使用接收到的提案代替自己的提案 Y,重新向其他服务器发送 Accept(2.5, X) 的 RPC,最终所有的服务器会达成一致并选择相同的值。

想要了解更多与 Paxos 协议在运行过程中的其他情况可以看一下 Paxos lecture (Raft user study) 视频和维基百科关于Paxos算法的介绍。

2.1.2 Multi-Paxos

由于大多数的分布式集群都需要接受一系列的值,如果使用 Basic Paxos 来处理数据流,那么就会导致非常明显的性能损失,而 Multi-Paxos 是前者的加强版,如果集群中的 Leader 是非常稳定的,那么我们往往不需要准备阶段的工作,这样就能够将 RPC 的数量减少一半。

上述图片中描述的就是稳定阶段 Multi-Paxos 的处理过程,S1 是整个集群的 Leader,当其他的服务器接收到来自客户端的请求时,都会将请求转发给 Leader 进行处理。

当然,Leader 角色的出现自然会带来另一个问题,也就是 Leader 究竟应该如何选举,在 Paxos Made Simple 一文中并没有给出 Multi-Paxos 的具体实现方法和细节,所以不同 Multi-Paxos 的实现上总有各种各样细微的差别。

2.1.3 Raft

Raft 其实就是 Multi-Paxos 的一个变种,Raft 通过简化 Multi-Paxos 的模型,实现了一种更容易让人理解的共识算法,它们两者都能够对一系列连续的问题达成一致。

Raft 在 Multi-Paxos 的基础之上做了两个限制,首先是 Raft 中追加日志的操作必须是连续的,而 Multi-Paxos 中追加日志的操作是并发的,但是对于节点内部的状态机来说两者都是有序的,第二就是 Raft 对 Leader 选举的条件做了限制,只有拥有最新、最全日志的节点才能够当选 Leader,但是 Multi-Paxos 由于任意节点都可以写日志,所以在选择 Leader 上也没有什么限制,只是在选择 Leader 之后需要将 Leader 中的日志补全。

在 Raft 中,所有 Follower 的日志都是 Leader 的子集,而 Multi-Paxos 中的日志并不会做这个保证,由于 Raft 对日志追加的方式和选举过程进行了限制,所以在实现上会更加容易和简单。

从理论上来讲,支持并发日志追加的 Paxos 会比 Raft 有更优秀的性能,不过其理解和实现上还是比较复杂的,很多人都会说 Paxos 是科学,而 Raft 是工程,当作者需要去实现一个共识算法,会选择使用 Raft 和更简洁的实现,避免因为一些边界条件而带来的复杂问题。

这篇文章并不会展开介绍 Raft 的实现过程和细节,如果对 Raft 有兴趣的读者可以在 The Raft Consensus Algorithm 找到非常多的资料。

2.2 POW(Proof-of-Work)

上一节介绍的共识算法,无论是 Paxos 还是 Raft 其实都只能解决非拜占庭将军容错的一致性问题,不能够应对分布式网络中出现的极端情况,但是这在传统的分布式系统都不是什么问题,无论是分布式数据库还是消息队列集群,它们内部的节点并不会故意的发送错误信息,在类似系统中,最常见的问题就是节点失去响应或者失效,所以它们在这种前提下是有效可行的,也是充分的。

这一节介绍的 工作量证明(POW,Proof-of-Work)是一个用于阻止拒绝服务攻击和类似垃圾邮件等服务错误问题的协议,它在 1993 年被 Cynthia Dwork 和 Moni Naor 提出,它能够帮助分布式系统达到拜占庭容错。

工作量证明的关键特点就是,分布式系统中的请求服务的节点必须解决一个一般难度但是可行(feasible)的问题,但是验证问题答案的过程对于服务提供者来说却非常容易,也就是一个不容易解答但是容易验证的问题。

这种问题通常需要消耗一定的 CPU 时间来计算某个问题的答案,目前最大的区块链网络 - 比特币(Bitcoin)就使用了工作量证明的分布式一致性算法,网络中的所有节点计算通过以下的谜题来获得当前区块的记账权:

SHA-256 作为一个哈希函数,想要通过 SHA-256 函数的输出推断出输入在目前来看可能性是可以忽略不计的,比特币网络就需要每一个节点不断改变 NONCE 来得到不同的结果 HASH,如果得到的 HASH 结果在小于某个范围,目前(2017.12.17)的难度是:

0x0000000000000000000000000000000000000000000000000000017268d8a21a

也就是如果只计算一次 SHA-256 的值能够小于上述结果的可能性是:

当前的全网算力也达到了 13,919 PH/s,这是一个非常恐怖的数字,随着网络算力的不断改变比特币也会不断改变当前问题的难度,保证每个区块被发现的时间在 10min 左右;在整个比特币网络中,谁先得到当前问题的答案就能够获得这个区块的记账权并将当前区块通过 Gossip 协议发送给尽可能多的比特币节点。

工作量证明的原理其实非常简单,比特币网络选择的谜题非常好的适应了工作量证明定义中的问题,比较难以寻找同时又易于证明,我们可以简单理解为工作量证明防止错误或者无效请求的原理就是增加客户端请求服务的工作量,而适合难度的谜题又能够保证合法的请求不会受到影响。

由于工作量证明需要消耗大量的算力,同时比特币大约 10min 才会产生一个区块,区块的大小也只有 1MB,仅仅能够包含 3、4000 笔交易,平均下来每秒只能够处理 5~7(个位数)笔交易,所以比特币网络的拥堵状况非常严重。

2.3 POS(Proof-of-Stake)

权益证明是区块链网络中的使用的另一种共识算法,在基于权益证明的密码货币中,下一个区块的选择是根据不同节点的股份和时间进行随机选择的。

由于创造新的区块并不会消耗大量的 CPU,如果它不诚实也不会失去什么,这也就给了很多节点作弊的理由,每一个节点为了最大化利益会在多条链上同时挖矿。

在早期的所有权证明算法中,整个网络只会奖励创建区块的节点,不存在任何惩罚,在这时每个节点在创造的多条链上同时投票才能够最大化利益,在这种情况下网络中的节点很难对一条链达成共识。

有两种办法能够解决缺乏利害关系(nothing-at-stake)造成的问题,一种是使用 Slasher 协议,惩罚同时在多条链上投票的节点,第二种方法时直接惩罚在错误的链上创建块的节点,总而言之就是通过算法之外的事情解决这个问题,引入激励和惩罚。

与工作量证明相比,权益证明不需要消耗大量的电力就能够保证区块链网络的安全性,同时也不需要在每个区块中创建新的货币来激励矿工参与当前网络的运行,这也就在一定程度上缩短了达成共识所需要的时间,基于权益证明的 Ethereum 每秒大概能处理 30 笔交易左右。

2.4 DPOS(Delegated Proof-of-Stake)

前面介绍的权益证明算法可以将整个区块链网络理解为一家公司,出资最多、占比最大的人有更多的机会得到话语权(记账权);对于小股东来说,千分之几甚至万分之几的股份很难有什么作为,只能得到股份带来的分红和收益。

但是在这里介绍的委托权益证明(DPOS,Delegated Proof-of-Stake)能够让每一个人选出可以代表自己利益的人参与到记账权的争夺中,这样多个小股东就能够通过投票选出自己的代理人,保障自己的利益。整个网络中选举出的多个节点能够在 1s 中之内对 99.9% 的交易进行确认,使用委托权益证明的 EOS 能够每秒处理几十万笔交易,同时也能够比较监管的干预。

在委托权益证明中,每一个参与者都能够选举任意数量的节点生成下一个区块,得票最多的前 N 个节点会被选择成为区块的创建者,下一个区块的创建者就会从这样一组当选者中随机选取,除此之外,N 的数量也是由整个网络投票决定的,所以可以尽可能地保证网络的去中心化。

3. 总结

在这篇文章中,我们首先介绍了分布式系统中面对的最重要问题,分布式一致性,随后又介绍了五种不同的共识算法,从解决非拜占庭问题下一致性的 Paxos 和 Raft 到解决拜占庭问题下的 POW、POS 和 DPOS,简单回忆一下,解决拜占庭问题的多个共识算法的实现反而更加简单,这是一件非常有意思的事情。

当整个网络需要实现拜占庭容错时,仅靠算法确实是比较难以实现的,往往都需要使用其他方面的激励或者惩罚,让诚实表现的节点利益最大化才是解决一致性的最佳方案;从工作量证明、权益证明再到委托权益证明,共识算法的不同导致性能也有着非常大的差异,我们可以看到随着网络中进行『投票』的节点越少,网络的处理能力就会越强和性能就会越快,委托权益证明选举了 N 个节点来保证性能和去中心化程度确实是一件非常聪明的事情。

中心化的网络确实能够带来性能的提升,但是在密码货币中,参与者往往更相信去中心化的机制,因为没有激励和惩罚我们并不能保证下一个负责记账的节点是否是诚实的,由此来看,如何在保证去中心化的同时提升网络的性能是每一个区块链网络都需要考虑的事情。

4. Reference

  • Consensus (computer science)

  • 区块链共识算法(POW,POS,DPOS,PBFT)介绍和心得

  • Paxos 与 Raft

  • Proof-of-work system

  • Proof-of-stake

  • Proof of Stake FAQ · Ethereum Wiki

  • Delegated Proof of Stake

  • Delegated Proof-of-Stake Consensus

  • DPOS共识算法 – 缺失的白皮书

  • 共识算法

  • CAP theorem

  • Paxos Made Simple

  • The Raft Consensus Algorithm

  • In Search of an Understandable Consensus Algorithm

  • 谈谈 paxos, multi-paxos, raft

  • Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services

  • “Eventual Consistency” vs “Strong Eventual Consistency” vs “Strong Consistency”?

  • Impossibility of Distributed Consensuswith One Faulty Process

  • The Byzantine Generals Problem

  • Byzantine fault tolerance

  • A Brief Tour of FLP Impossibility

  • Paxos Made Simple

  • Neat Algorithms - Paxos

  • FLP Impossibility 的证明

  • 白话区块链

  • Paxos

  • Paxos lecture (Raft user study)

  • Bitcoin: A Peer-to-Peer Electronic Cash System

  • Proof of Stake · Bitcoin Wiki

  • Slasher

  • Proof of Stake FAQ

2020-07-23-mv4yDc
2020-07-23-Leu3D3
2020-07-23-D0aKzP
2020-07-23-EMTdrZ
2020-07-23-HqYYkb
2020-07-23-KipG8u
2020-07-23-b9VL5N
2020-07-23-ijhHRa
2020-07-23-jXeVs5
2020-07-23-mEJ5vh
2020-07-23-pKNt3S
2020-07-23-sqvNGm
2020-07-23-apPqMX
2020-07-23-EMyzts
2020-07-23-jyQlpa
2020-07-23-1ZsFjD
2020-07-23-fJHvi2
2020-07-23-N35fhy
2020-07-23-LZ8iHe