当前位置: 首页 > 编程日记 > 正文

分布式一致性(共识)算法(Paxos,raft,ZAB)的一些总结

文章目录

  • 前言
  • CAP理论
    • C consistency 一致性
    • A availability 可用性
    • P partition tolerance 分区容错性
  • 一致性模型
    • 弱一致性
    • 强一致性
  • 强一致性算法
    • 需要明确的问题
    • 强一致算法: 主从同步
    • 强一致性算法:多数派
    • 强一致算法:Paxos
      • Basic Paxos
      • Multi Paxos
        • 第一个版本:使用Proposer表示唯一的一个Leader
        • 第二个版本:将算法角色进一步简化
    • 强一致算法: Raft(基于log replicated的共识算法)
    • 强一致算法:ZAB
  • 总结

前言

分布式系统是当前互联网领域的一个重要且大势所趋的一种解决计算,存储,网络相关问题的方向,利用数量庞大的服务器节点作为底层,在其之上搭建一个可以跨省甚至跨国的庞大系统。

它能够保证用户数据的一致性,对用户提供服务的高可用性,以及跨地域的分区容错性,而分布式一致性算法就是为了保证分布式系统能够满足其特性。

分布式一致性算法,我将其划分到了分布式存储技能树中的分布式理论中:

在这里插入图片描述
本文的总结,将按照以下导图进行知识点的总结和梳理
在这里插入图片描述

CAP理论

提到分布式系统,那么CAP理论便无法绕过了。自从2000年,Eric Brewer教授提出了分布式系统设计一定会遵循:一致性,可用性,分区容错性的三个原则之后,互联网界的分布式系统便都将其作为自己的衡量标准。后续的分布式系统设计也都按照CAP理论进行设计,但是任何一个系统都只能在三个原则中满足两个,无法三个都满足,即使像最近的亚马逊S3和google spanner等全球分布式系统也只能满足CP两种,对于A则也只能提供多个9的可用性。

后续该理论上升为定理之后也有相关的证明论文,本节只是将其作为一个基本理论扫盲的介绍。

在这里插入图片描述

C consistency 一致性

在分布式系统中有多个节点,整个系统对外提供的服务应该是一致的。即用户在不同的系统节点访问数据的时候应该是同样的结果,不能出现1号节点是结果1, 2号节点是结果2这种不一致的情况。

A availability 可用性

分布式系统为用户提供服务,需要保证能够在一些节点异常的情况下仍然支持为用户提供服务。

P partition tolerance 分区容错性

分布式系统的部署可能跨省,甚至跨国。不同省份或者国家之间的服务器节点是通过网络进行连接,此时如果两个地域之间的网络连接断开,整个分布式系统的体现就是分区容错性了。

在这种系统出现网络分区的情况下系统的服务就需要在一致性 和 可用性之间进行取舍。
在这里插入图片描述
如果为了在出现网络分区之后提供仍然能够提供可用性,那么一致性必然无法满足。因为可用性的要求是系统仍然能够提供服务,但是这个时候分布式系统在两个地域之间无法通信,那么America的请求无法同步到China的服务节点上,整个系统的一致性显然不能满足。

同理 为了保证一致性,那么可用性也必然不能满足,因为一致性的要求是请求A写入America之后从China中读,一定要能够读到这个请求(强一致性)或者 经过一段时间之后也能够读到(弱一致性)。但是两地域已经出现了网络分区,那么请求会阻塞从而降低可用性。

所以CAP理论一定是无法全部满足三者,只能满足其中的两者。

一致性模型

弱一致性

弱一致性体现的是最终一致性,即如上CAP理论中 ,两个地域的请求分别通过两地的节点写入,可以不用立即进行同步,而是经过一段时间之后两地的用户数据变为一致。这种一致性成为弱一致性,即最终一致性。
也就是用户一地写入之后从另外一个节点读取,无法立即读到刚才写入的数据。

比如DNS域名系统,Cassandra的 Gossip协议等都是最终一致性的体现。

全球目前的域名系统可以看作一个域名树,由一个根域名节点.cn下辖多个.edu,.org,.com等子域名节点,而这一些子域名之下🈶️更多的子域名(以企业为例www.kuaishou.com,之下有多个数据中心,不同的数据中心又数百上千的存储节点),当我们向某一个节点更新域名信息的时候,在其他节点立即访问该记录则不一定立即访问到最终的更新,而是经过一段时间之后我们能够看到更新。

强一致性

强一致性是非常有必要的,比如业界的银行系统,支付系统等对一致性要求非常高。
当下比较流行的强一致性算法 像 Paxos,以及基于paxos衍生的raft,ZAB都能提供强一致性的能力。

强一致性描述的是一个请求在一个节点写入之后在其他节点读取,则该数据的更新能够被读到。
接下来主要描述的是一些强一致性算法的原理。

强一致性算法

需要明确的问题

  • 数据不能存放在单个节点上,当然这个是分布式系统的基础形态,不满足这个分布式系统也不能称为分布式系统了
  • 分布式系统对分区容错的方案是 state machine replication (复制状态机),而强一致算法也被称为共识算法(consensus)
    state状态机 简单来说就是一个函数,根据输入的不同值来执行对应的请求处理逻辑。
    为了保证系统的最终一致性,不仅需要系统内部达成共识,也需要一些client的行为。

强一致算法: 主从同步

主从同步复制:

  1. master接受写请求
  2. master复制日志到slave
  3. master等待直到所有从节点返回

在这里插入图片描述

这是一个强一致性算法的基础,但是这样的模型会出现如下问题:
比如一个slave节点异常宕机,那么master迟迟等不到该节点的返回,此时client请求便会阻塞。这样的模型就是强一致模型,但是系统的可用性就会非常差,一个节点挂掉会导致整个系统不可用。

强一致性算法:多数派

为了避免主从同步那样一个节点异常,整个集群不可用的情况,推出了多数派。即每次写入只需要保证写入节点数大于N/2 个,读节点数保证大于N/2个节点,此时即可认为能够向客户端返回了。

这样既能够保证一致性,又提高了可用性。但是这个情况也只是针对单个请求写入的情况下,而我们实际生产环境中会存在大量的并发场景。
比如:
在这里插入图片描述
并发这个分布式系统的不同节点执行不同的操作,在满足多数派的情况下可能会出现顺序的问题,不同的节点因为请求同步的时间问题可能出现请求的顺序不一致。

强一致算法:Paxos

基础的Paxos算法包括如下三种:

  • Basic Paxos
  • Multi Paxos
  • Fast Paxos

paxos算法是Lasile Lamport的发明,这个算法已经有很多论文对其基本原理进行描述,因为本身角色很多又要在不同的异常场景下描述清楚,很难真正让读者对该算法融会贯通的。

Lamport为了更加形象的描述,提出了虚拟出来一个叫做Paxos的希腊城邦,这个城邦的管理者为了方便对民众的管理,提出了一系列法案用来对民众进行约束,当民众有民事请求时,会提交民事诉讼给国会,有一个组织者将该诉讼整理成法案交给一个个议员进行处理,议员之间又分为投票者和接受者用来实际进行该法案最终是否要处理的决定,最终将结果反馈给组织者,由组织者将最终的结果再返还给民众。

具体的角色如下:

  • Client :系统外部角色,请求的发起者。就像是故事中的民众
  • Proposer: 接受Client请求,想集群提出提议(propose)。并在投票的国会发生冲突的时候进行调节,经结果反馈给民众
  • Accpetor(Voter): 投票者,就是负责在集群内部对法案是否要写入进行投票。只有满足多数派(法定人数Quorum的由来)的情况下提议才会被接受,像是国会。
  • Learner:接受者,即进行backup,将民众的请求记录下来。这个角色对集群一致性本身并没有什么影响。

Basic Paxos

主要分为如下几个阶段(phases):

  1. Phase 1a: Prepare阶段
    这个阶段Proposer提出一个提案编号为N;此时N大于这个Proposer之前提出的议案,请求这个集群的Acceptor Quorum接受。
  2. Phase 1b: Promise阶段
    如果N大于此Acceptor之前接受的任何提案编号则接受,否则拒绝。
  3. Phase 2a: Accept阶段
    如果Acceptor内部投票通过的人数达到了多数派,则Proposer会发出accept的请求,该请求包括提案编号为N,以及提案的内容(用户请求的内容)
  4. Phase2b: Accepted阶段
    如果此acceptor在此期间没有收到任何编号大于N的提案,则接受此提案内容,否则忽略。接受之后会向Proposer返回成功,且将议案的内容交给Learner进行backup

正常的处理流程如下:
在这里插入图片描述

客户端发起request请求到Proposer,然后Proposer发出提案并携带提案的编号1,分别发给每一个Acceptor;每一个Acceptor根据天都编号是否满足大于1,将投票结果通过Propose阶段反馈给Proposer;Proposer收到Acceptor的结果判断是否达到了多数派,达到了多数派则向Acceptor发出Accept请求,并携带提案的具体内容V;Acceptor收到提案内容后向Proposer反馈Accepted表示收到,并将提案内容交给Learner进行备份。

Learner写入提案内容之后向Client发送完成请求的响应。

当Acceptor出现异常时流程如下:
在这里插入图片描述
虽然Accetor3 出现异常,没有向Proposer反馈,但是Proposer此时收到的接受提案的反馈有2个Acceptor,仍然满足多数派的情况,此时仍然能够将提案内容继续写入的,所以后续的Accept的发送只需要发送给剩下的两个Acceptor即可。

当Proposer出现异常时的情况如下:
在这里插入图片描述
Proposer失败的话表示收到Acceptor的Propose请求之后无法继续发送Accept请求,这个时候集群会重新选出另一个新的能够工作的Proposer,再从prepare阶段开始处理,同时Prepare的提案版本号会增加一个,但是提案的内容还是之前的内容。

当出现活锁的情况:
简化了如下处理流程,当然其中的 Proposers和Acceptors 不只一个,是由多个组成的。
在这里插入图片描述
基本情况就是集群中有多个Propser,当proposer1发送prepare版本为1并收到propose的时候节点发生了异常,集群切换到了新的proposer,并重新prepare 版本2,准备好和版本1相同的内容的提案。(因为acceptor处理的过程中发现更高版本的提案,会丢弃当前的版本,转向更高版本去处理)。

当proposer2等待acceptor的propose返回时,proposer1有上线了,发现自己prepare(1)提案被打断,此时又准备了一个更高版本的prepare(3)提案,打断了proposer2的2版本提案;当proposer2发现自己的2号版本被打断,又准备了更高的4号版本,从而打断了propose1的3号提案版本;依此下去,整个集群将会阻塞在相同的提案的不断提交之中,这种情况就是集群出现了活锁

当然也有较好的解决措施,比如:proposer1的上线之后 重新提交法案使用随机时间机制,即随机生成一个时间戳,在这段时间内不向Acceptor发送消息;这样proposer2的提案能够被处理完成,这个时候proposer1再次提交新的提案。

综上这一些基本异常情况来看,basic paxos还是能够保证系统的一致性和可用性,共识算法还是能够正常工作。
但是basic还是有一些缺点:

  • 难实现
    有太多的角色需要实现
  • 效率低(2轮 rpc)
    每一个请求需要proposer和acceptor 至少交互两次才能完成请求的处理
  • 活锁

这个时候推出了Multi Paxos,其中的特色就是Leader概念,Leader是由唯一的Proposer表示,所有的请求都需要经过这个Leader进行转发。

Multi Paxos

第一个版本:使用Proposer表示唯一的一个Leader

Proposer可以直接用来做提案是否被接受的决定,而不用所有的acceptor各自决定是否要接受提案。

正常处理流程如下:

在这里插入图片描述
在这里插入图片描述

  • 处理第一个请求的时候因为需要选择leader,所以还是会走2轮rpc,从prepare 到最后的Accepted。
  • 从第二个请求开始,所有的请求只需要交给Proposer,Proposer即可完成是否接受请求的决定,一次Accept即可达成将请求写入Learner的过程。

第二个版本:将算法角色进一步简化

这个简化之后便更加接近我们实际的分布式系统的情况
在这里插入图片描述

当然这个还是正常请求的处理流程,不过只会通过一轮Accept通信即可完成请求的处理。

ps:简化后的集群第一个请求还是会走2轮rpc,为了从servers中选举出一个leader,这个过程还是会从prepare开始到Accepted完成。

强一致算法: Raft(基于log replicated的共识算法)

raft是更为简化的multi paxos(其实也就是上一个图中的paxos)算法,相比于paxos的复杂实现来说角色更少,问题更加精简。
rafti整体来说可以拆分成三个子问题来达成共识:

  • Leader Election 如何选择出leader
  • Log Replication 如何将log复制到其他的节点
  • Safety 保证复制之后集群的数据是一致的

重新定义了新的角色:

  • Leader 一个集群只有一个leader
  • Follower 一个服从leader决定的角色
  • Cadidate follower发现集群没有leader,会重新选举leader,参与选举的节点会变成candidate

除了以上的精简之外,raft还提供了完善的社区 甚至 完整共识过程的可视化展示,这里可以通过原理动画展示 : http://thesecretlivesofdata.com/raft/ 浏览。

主体过程如下:

  1. 三个基本的节点角色介绍一下
    在这里插入图片描述

  2. Leader Election的选举过程
    初始所有节点都是follower状态,当开始选举的时候将待选举节node a点置为candidate状态
    canditdate会向其他的follower节点发送请求进行leader投票,其他节点投票通过,则将candidate节点的状态置为leader状态。

    在这里插入图片描述

接下来通过两种心跳时间来详细看一下选举过程的实现
在leader election选举的过程中会有两种timeout的设置来控制整个的选举过程:

  • Election timeout
    表示follower等待请求的超时时间,如果这个时间结束前还没有收到来自leader或者选举leader的请求,那么当前follower便会变为 candidate。 raft给的设定值一般在150ms-300ms之间的随机值。
    变成candidate之后,当前节点会立即发送leader的投票请求,其他的follower节点会重置选举的超时时间。

  • heartbeat timeout
    新选举出来的leader每隔一段时间会发送一个请求给follower,这个时间就是心跳时间。
    同样follower在相同的时间间隔内回复leader一个请求,表示自己已经收到。

    这样的心跳间隔将会一直持续,直到一个follower停止接受心跳,变成candidate。

    重新选举的过程就是candidate发送选举请求,follower接受到之后返回对应的心跳回应,candidate根据心跳回应的个数判断是否满足多数派,从而变成leader。变成leader之后,会持续发送心跳包来保证follower的存活。

  1. Log Replication过程
    主要过程如下:
    客户端发送请求到leader,leader接受之后将请求封装成log entry,并将log副本发送给其他的follower节点。
    等待其他的follower节点回复,发现达到了多数派之后leader便将该entry写入到自己的文件系统之中;
    写入之后再发送请求,表示follower节点也可以写入了。
    在这里插入图片描述
    接下来我们详细看看log Replicated的实现过程,我们的leader被选举出来之后用于请求的转发,将接受到的用户请求封装成log entry,并将log entry的副本转发给follower,这个log enry发送到follower之后也会用于重置follower的心跳时间。
    1. 客户端会发送一条请求到leader,这个请求会追加到leader的log上,但此时还没有写入leader所在节点的文件系统之上
    2. 这个条leader的log 会在leader发送下一条心跳包的时候携带该请求的信息 一起发送给follower
    3. 当entry提交到follower,且收到多数派的回复之后会给client一个回复,表示集群已经写入完成。同时将leader的log写入自己的文件系统,并且发送command让从节点也进行写入。这个过程就是multi paxos中的accepted阶段。

关于raft更加详细严谨的细节介绍和性能测试 可以参考论文raft paper

强一致算法:ZAB

基本和raft相同,只是在一些名词的叫法上有一些区别
比如ZAB 将某一个leader的周期称为epoch,而raft称为 term。

实现上的话 raft为了保证日志连续性,心跳方向是从leader到follower,ZAB则是相反的。

总结

本篇从理论和实现逻辑上描述了CAP理论、paxos相关的一致性算法变种以及基于multi paxos实现的简化版强一致算法协议raft和ZAB,后续会从源码层面一一观察以及自实现基础raft的通信来加深对分布式系统设计的理解。

可以看到分布式系统的核心算法还是围绕CAP理论来进行取舍,从系统前期的角色设计,到每个角色承担的任务,到最后异常情况下的各个角色做出的反应都能看到CAP的影子。这一些设计原则最终还是会反馈到用户体验之上,双十一的巨量流量,国外的APP群体和国内实时通信交互,看似简单的一个用户功能背后的每一个RPC都是一段跨省,跨国的异地恋,即使异国之路被封锁,合理的系统设计也能够让这段恋情持续。

各自安好,静待他音。

想猪!!!

相关文章:

dedecms 财付通接口

用织梦做了个旅游网站&#xff0c;网址&#xff1a;http://www.redtourism.cn/ 客户要求财付通支付&#xff0c;上网找了下 不是要买就是要钱&#xff0c;只有自己写了。 代码&#xff1a; <?phpif(!defined(DEDEINC)) exit(Request Error!);/** *财付通接口类 */class ten…

r语言手动算两个C指数p值,如何用R语言进行Pvalue显著性标记?

作者&#xff1a;一只想飞的喵审稿&#xff1a;童蒙编辑&#xff1a;angelica箱线图是统计学中较常见的图形之一。这篇文章将讲述如何简单比较两组或多组的平均值&#xff0c;且添加显著性标记。通常情况根据显著性p值的数值大小&#xff0c;分为四类&#xff1a;(1)0.01≤p<…

linux yum命令详解

yum&#xff08;全称为 Yellow dog Updater, Modified&#xff09;是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器。基於RPM包管理&#xff0c;能够从指定的服务器自动下载RPM包并且安装&#xff0c;可以自动处理依赖性关系&#xff0c;并且一次安装所有依赖的软体包…

OpenCV编译viz模块

首先需要编译vtk。注意不要使用最新的master版本&#xff0c;而是使用tag分支下的最新版本。当前最新版本是https://gitlab.kitware.com/vtk/vtk/tree/v8.2.0版本。直接点击下载源码即可。 Cmake选项设置&#xff1a; 如果需要编译成静态库&#xff0c;需要在CXX_FLAGS、C_FLAG…

vim 成“神“之路 (一)

文章目录1. 安装1.1 linux1.2 MacOs的安装1.3 Windows的安装1.4 vim中文帮助文档安装2. vim基本概念和基础命令2.1 基本的键位映射如下:2.2 vim模式2.3 vim的选项和基本配置2.3.1 备份和跨会话撤销文件2.3.2 vim中支持鼠标3. vim 常用命令 -- 应对稍复杂任务3.1 光标移动3.2 文…

android 添加头参数,Retrofit添加header参数的几种方法

(1)使用注解的方式添加一个Header参数publicinterfaceUserService {Headers("Cache-Control: max-age640000")GET("/tasks")Call> getTasks();}添加多个Header参数publicinterfaceUserService {Headers({"Accept: application/vnd.yourapi.v1.full…

redis下载地址

http://www.newasp.net/soft/67186.html转载于:https://www.cnblogs.com/phpxuetang/p/4190999.html

Ubuntu 13.10 安装软件失败后出现的问题——已安装 post-installation 脚本 返回了错误号 1...

安装Oracle-java7-installer失败后&#xff0c;再次重新安装后出现错误&#xff5e;&#xff5e; dpkg: error processing oracle-java7-installer (--configure): 子进程 已安装 post-installation 脚本 返回了错误号 1 索性执行 sudo apt-get install -f&#xff0c;我勒个…

C. Edgy Trees Codeforces Round #548 (Div. 2) 【连通块】

一、题面 here 二、分析 这题刚开始没读懂题意&#xff0c;后来明白了&#xff0c;原来就是一个数连通块里点数的问题。首先在建图的时候&#xff0c;只考虑红色路径上的点。为什么呢&#xff0c;因为为了不走红色的快&#xff0c;那么我们可以反着想只走红色的路径&#xff0c…

设计模式 之美 -- 策略模式

策略模式作为行为型设计模式中的一种&#xff0c;主要封装相同功能的不同实现算法&#xff0c;用于在用户程序内部灵活切换。对用户来说能够快速替换对应的算法&#xff0c;能够让算法的实现独立于使用的用户。 基本的UML类图如下&#xff1a; 用户使用Stratey的实例能够快速…

Good Bye 2014 B. New Year Permutation(floyd )

题目链接 题意:给n个数&#xff0c;要求这n个数字小的尽量放到前面&#xff0c;求一个最小的。 给一个矩阵s[i][j]1&#xff0c;表示位置 i 的数字可以和 位置 j 的数字交换。 分析&#xff1a; 刚开始用的是3个循环&#xff0c;每次都找一个能直接连接的最小的放到前面&#x…

android数据库查找一个字符,Android - 如何在Firebase数据库中对字符串进行简单搜索?_android_开发99编程知识库...

这个问题可能很旧&#xff0c;但是&#xff0c;有一种文档化方式&#xff0c;如何实现这种方式&#xff0c;很简单&#xff0c;引用 &#xff1a;要启用云Firestore数据的全文搜索&#xff0c;请使用第三方搜索服务(如Algolia &#xff0c;考虑一个笔记记录应用程序&#xff0c…

料酒有什么用?

http://zhidao.baidu.com/question/201086759.html?frala&devicemobile&ssid0&from844b&uid0&pusz%401320_1001%2Cta%40iphone_2_4.1_3_537%2Cusm%400&bd_page_type1&baiduidDFA2DBA38D5C3AEB12431C4258DC1F40&tjzhidao_1_0_10_title

jmeter对自身性能的优化

测试环境 apache-jmeter-2.13 1. 问题描述 单台机器的下JMeter启动较大线程数时可能会出现运行报错的情况&#xff0c;或者在运行一段时间后&#xff0c;JMeter每秒生成的请求数会逐步下降&#xff0c;直到为0&#xff0c;即JMeter运行变得很“卡”。 2. 解决方法 1&#x…

站在历史的长河中做农活

苹果的生长周期 国庆节回老家呆了3天时间&#xff0c;陪爸爸妈妈吃喝吃睡&#xff0c;除此之外就是帮爸爸妈妈去家里的果园做一些农活。 我们老家的 苹果种植是家庭主要的收入&#xff0c;每一家人或多或少都有一些果园。从春的剪枝&#xff08;高中生物中的降低顶端优势&…

html 基本用法

html表单表格基本用法&#xff0c;直接贴代码。 [html] view plaincopy<html> <head> <title>html基础</title> </head> </body> <center><h2><font color"CYAN">html基础&…

ecliplse 调试android 断点,如何在Github maven项目上开始调试

您将需要在 nifi-registry.sh 脚本中编辑此行以启用远程调试run_nifi_registry_cmd"${JAVA} -cp ${BOOTSTRAP_CLASSPATH} -Xms12m -Xmx24m ${BOOTSTRAP_DIR_PARAMS} org.apache.nifi.registry.bootstrap.RunNiFiRegistry $"它只是我&#xff0c;还是记忆足迹真的很小…

Linux认证体系

就像网络工程师的认证有思科系统和华为系列一样&#xff0c;Linux认证方面&#xff0c;不同的机构也有不同的证书&#xff0c;比如国内有红旗Linux的认证RCE&#xff08;红旗Linux认证工程师&#xff09;&#xff0c;国际方面有红帽的认证RHCSA&#xff08;Redhat认证的Linux系…

python2.7 Cheetah You don't have the C version of NameMapper installed

python2.7 Cheetah You dont have the C version of NameMapper installed 问题&#xff1a;You dont have the C version of NameMapper installed sudo vi /usr/lib/python2.7/site-packages/Cheetah/Compiler.py 将第1506行起以下代码注释掉&#xff1a; if not NameMapper.…

C++ 从双重检查锁定问题 到 内存屏障的一些思考

文章目录1. 问题描述2. DCLP 的问题 和 指令执行顺序2.1 Volatile 关键字2.2 C11 的内存模型3. C11内存模型 解决DCLP问题3.1 内存屏障和获得、释放语义3.2 atomic 的完整介绍3.2.1 原子操作的三种类型3.2.2 atomic 内存序3.2.3 atomic 成员函数4. 总结1. 问题描述 单例模式 是…

android系统的iphone,iPhone上安装Android系统详细步骤。

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼在iphone安装android系统的详细步骤首先&#xff0c;准备好iphone的多点触屏和wlan固件。因为法律的缘故&#xff0c;我们不能分享这些文件&#xff0c;你可以去ipsw文件里提取或去marvell网站下载。1、在linux的home目录下创建一个…

Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入) 转

http://www.crazyant.net/2011/10/29/linux%E4%B8%8Bgcc%E5%92%8Cmakefile%E5%AE%9E%E4%BE%8B%EF%BC%88%E4%BB%8Egcc%E7%9A%84%E7%BC%96%E8%AF%91%E5%88%B0makefile%E7%9A%84%E5%BC%95%E5%85%A5%EF%BC%89/ 很给力的说&#xff0c;回头去搞搞&#xff01;

服务端如何识别是selenium在访问以及解决方案参考二

有不少朋友在开发爬虫的过程中喜欢使用Selenium Chromedriver&#xff0c;以为这样就能做到不被网站的反爬虫机制发现。 先不说淘宝这种基于用户行为的反爬虫策略&#xff0c;仅仅是一个普通的小网站&#xff0c;使用一行Javascript代码&#xff0c;就能轻轻松松识别你是否使用…

LSM 优化系列(二)-- dCompaction: Speeding up Compaction of the LSM-Tree via Delayed Compaction

文章目录背景描述dCompaction设计触发条件 VCT触发VT 合并的条件 VSMT测试数据优化的重心集中在减少写放大上&#xff0c;同时将读性能维持在和rocksdb 原生读性能接近&#xff0c;优化思想是中国科学院的2位博士 提出的。论文原地址&#xff1a;dCompaction: Speeding up Comp…

Android应用系列:完美运行GIF格式的ImageView(附源码)

前言 我们都知道ImageView是不能完美加载Gif格式的图片&#xff0c;如果我们在ImageView中src指定的资源是gif格式的话&#xff0c;我们将会惊喜的发觉画面永远停留在第一帧&#xff0c;也就是不会有动画效果。当然&#xff0c;经过略加改造&#xff0c;我们是可以让gif在Image…

wordpress怎么修改html,WordPress后台编辑器HTML模式界面中添加修改删除按钮

在WordPress编辑器HTML模式界面中添加按钮一文中&#xff0c;我大致介绍了怎么在后台添加一些自定义的按钮&#xff0c;本文则更为详细全面的对wordpress后台编辑器HTML模式下的按钮自定义进行详解&#xff0c;以让开发者肆意的修改按钮及其布局。自定义按钮起效的两种途径 ↑首…

OCA读书笔记(9) - 管理数据同步

9.Managing Data Concurrency 描述锁机制以及oracle如何管理数据一致性监控和解决锁冲突 管理数据的并发--管理锁数据的不一致&#xff1a;脏读更改丢失幻影读 脏读:数据是指事务T2修改某一数据&#xff0c;并将其写回磁盘&#xff0c;事务T1读取同一数据后&#xff0c;T2由于某…

Java EE学习笔记(四)

Spring的数据库开发 1、Spring JDBC 1)、Spring JDBC模块的作用&#xff1a;Spring的JDBC模块负责数据库资源管理和错误处理&#xff0c;大大简化了开发人员对数据库的操作&#xff0c;使得开发人员可以从繁琐的数据库操作中解脱出来&#xff0c;从而将更多的精力投入到编写业务…

SpringBoot 中实现订单30分钟自动取消的策略

在电商和其他涉及到在线支付的应用中,通常需要实现一个功能:如果用户在生成订单后的一定时间内未完成支付,系统将自动取消该订单。本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案,并提供实例代码。

一键部署 SpringCloud 微服务,这套流程值得学习一波儿!

一键部署 springcloud 微服务,需要用到 Jenkins K8S Docker等工具。本文使用jenkins部署,流程如下图开发者将代码push到git运维人员通过jenkins部署,自动到git上pull代码通过maven构建代码将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry通过k8s发起 发布/更新 服务 操作其中 2~5步骤都会在jenkins中进行操作。