本就不能wwWzzz559CoM登入福建安全教育平台了,还可以继续zzz559收视的

我这里不谈功利的内容,完全从个人感受出发讲一点点。&br&1.文学是距离,是陌生化。&br&你每天都在吃饭睡觉开门打电话洗澡,当这一切熟练到不加思考的时候,你活一天和一百天就没有区别。&br&沉湎于名利也好,沉湎于爱情也好,沉湎于日常琐碎的生活也好,在这些时候,支配你的已经不是智慧了,而是习惯和本能。只有保持适当的距离,才能让你跳出来思考自己的存在状态和生活方式。&br&这不是精神和物质的区别,很多人有个误解,认为精神的就是崇高的,然而并非如此,比如爱情,当它浓烈到一定程度的时候,反而写不出诗来,因为那个时候你已经彻底陷进去了。当你陷进去的时候你是盲目的,因为没有距离,所以无法思想。而思想才是最崇高的。&br&为什么古人咏物要绕来绕去?写月亮为什么不直接写“月亮真好看”,要使用各种典故,从侧面各种刻画?因为营造距离才能产生审美。当月亮重新变得陌生的时候,它在读者心中就有了第二次生命,这种重逢的喜悦会让你更加理解月亮。这才是思想。&br&文学就是让你跳出来重新审视自身和世界万物的工具。&br&&br&2.文学是理解,是共情。&br&我如果说“我高考落榜了”,六个字,人人都理解,但是这只是日常语言层面的理解。这句话只能交代粗略的事实,而在情绪的传达上面非常浅显。如果一个人没有经历过落榜,只凭这六个字,显然是很难体会你的感受的。&br&只有使用文学语言,可以精确地描述出来高考落榜这件事所能体现的心理状态。文学是超越日常语言的高清无码的传输情绪的工具。&br&通过文学,你可以表达自己,可以接受古往今来所有人的表达。这是人类最重要的技能之一。&br&&br&3.文学是美,是道德&br&美有什么用?这个问题更复杂了,我没有办法回答,知者自知吧。&br&相比之下道德更好理解一些,毕竟古往今来儒家就看重道德教化,而伟大的文学最后都要落在真善美上面。这一点给我震撼最大的是《悲惨世界》,我高中的时候熬夜看完,之后发呆了好久,心里默默地想,我一定要做一个好人。这是任何空洞地说教都无法代替的。&br&&br&4.说了这么多,完全不读文学书有什么坏处?&br&这就像一个从来不走出自己的村庄的人,问我“不出门看看世界会对我现有的生活有什么坏处”?&br&没什么坏处,因为你以前也没出过门,还不是照样在过日子?所以如果只把目光聚焦在“现有的生活”,那坏处是没有的。&br&但是呢,终究是很遗憾,对吧。理想国中里面终日对着山洞里的影子的人,他也可以愉快地度过这一生。但是当他走出山洞,看到一个新世界,他就再也不想回去了。此时再让他终日对着影子,反而就是一种折磨。从这个角度看,文学反而是有坏处的,它让你的眼光更加挑剔了。&br&&br&5*.感觉我上述话里似乎有一些优越感…不过不是我的本意。热情地全身心投入现实生活的人也是值得敬佩的。(至少我这样的loser就做不到
我这里不谈功利的内容,完全从个人感受出发讲一点点。 1.文学是距离,是陌生化。 你每天都在吃饭睡觉开门打电话洗澡,当这一切熟练到不加思考的时候,你活一天和一百天就没有区别。 沉湎于名利也好,沉湎于爱情也好,沉湎于日常琐碎的生活也好,在这些时候…
&p&  阅读要求:了解容器(Docker)、虚拟机等相关概念,如果没有Docker、虚拟机概念的同学,就等快哥下波福利吧。&/p&&p&  k8s是什么?&/p&&p&  k8s 是kubernetes的简称,因为k与s之间有8个字母,而且发音也接近,因此就发音为k8s了。&/p&&p&  k8s的由来?&/p&&p&  k8s是google开源的容器集群管理系统,能方便管理跨集群运行容器化的应用,提供应用部署、维护、扩展机制等功能。&/p&&p&  为了高效描述k8s,我们先放图,看架构、概念和流程。&/p&&p&  本身k8s官方图相对比较复杂的,快哥找了一个简易图如下:&/p&&figure&&img src=&https://pic2.zhimg.com/v2-7dbecbee4e23bf3ec19c91d1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&528& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic2.zhimg.com/v2-7dbecbee4e23bf3ec19c91d1_r.jpg&&&/figure&&p&&br&&/p&&p&  用户通过kubectl提交需要运行的容器。&/p&&p&  api server将请求存储在etcd里面。&/p&&p&  Scheduler扫描,分配机器&/p&&p&  kubelet找到要跑的container,在本机上运行&/p&&p&  replication controller监视集群中的容器并保持数量&/p&&p&  kube proxy负责具体的工作流量转发&/p&&p&  1.
整体拓扑&/p&&p&  Kubernetes将集群中的机器划分为一个Master节点和一群工作节点(Node)。&/p&&p&  Master节点上运行着集群管理相关的一组进程etcd、API Server、Controller Manager、Scheduler,构成了Kubernetes的总控中心。&/p&&p&  这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且全都是自动完成。&/p&&p&  每个Node上运行Kubelet、Proxy、Docker daemon三个组件,负责对本节点上的Pod的生命周期进行管理,以及实现服务代理的功能。&/p&&p&  2.
文中相关概念&/p&&p&  Pod&/p&&p&  Pod是k8s的基本操作单元,一个Pod由一个或多个容器组成,通常pod里的容器运行的相同的应用。这些容器使用相同的网络命令空间、IP地址、存储卷空间和端口,相互之间能通过localhost来发现和通信。在k8s中创建,调度和管理的最小单位就是Pod,而非容器,Pod通过提供更高层次的抽象,提供了更加灵活的部署和管理模式;&/p&&p&  Node&/p&&p&  Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的Kubelet、kube-proxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡。&/p&&p&  RC(Replication Controller)&/p&&p&  k8s通过RC中定义的Pod模板来创建一个新的Pod,然后将此Pod调度到合适的Node上启动运行,直到Pod实例数量达到预定目标。&/p&&p&  3.
详细的官方架构前面是一个稍微简易的架构图,官方复杂的架构图如下,大伙可以点击慢慢看,或者保存成屏保桌面。后面富有详细的工作流程解释。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-b545bb160be9b192dfd3620_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&600& data-rawheight=&494& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic1.zhimg.com/v2-b545bb160be9b192dfd3620_r.jpg&&&/figure&&p&&br&&/p&&p&  详细工作流程如下:&/p&&p&  通过Kubectl提交一个创建RC的请求,请求通过API Server被写入etcd中。&/p&&p&  Controller Manager通过API Server的监听资源变化的接口监听到这个RC事件,分析之后,发现当前集群中还没有它所对应的Pod实例,于是根据RC里的Pod模板定义生成一个Pod对象,通过API Server写入etcd。&/p&&p&  Scheduler发现后,执行调度流程,为这个新Pod选定一个落户的Node,然后通过API Server将结果写入到etcd中。&/p&&p&  随后,目标Node上运行的Kubelet进程通过API Server监测到这个“新生的”Pod,并按照它的定义,启动该Pod直到Pod的生命结束。&/p&&p&  接着,用户通过Kubectl提交一个新的映射到该Pod的Service的创建请求,Controller Manager会通过Label标签查询到相关联的Pod实例,生成Service的Endpoints信息,并通过API Server写入到etcd中,接下来,所有Node上运行的Proxy进程通过API Server查询并监听Service对象与其对应的Endpoints信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能。&/p&&p&  各个进程的作用如下:&/p&&p&  etcd 用于持久化存储集群中所有的资源对象,如Node、Service、Pod、RC、Namespace等;API Server提供了操作etcd的封装接口API,这些API基本上都是集群中资源对象的增删改查及监听资源变化的接口。&/p&&p&  API Server 提供了资源对象的唯一操作入口,其他所有组件都必须通过它提供的API来操作资源数据,通过对相关的资源数据“全量查询”+“变化监听”,这些组件可以很“实时”地完成相关的业务功能。&/p&&p&  Controller Manager 集群内部的管理控制中心,其主要目的是实现Kubernetes集群的故障检测和恢复的自动化工作,比如根据RC的定义完成Pod的复制或移除,以确保Pod实例数符合RC副本的定义;根据Service与Pod的管理关系,完成服务的Endpoints对象的创建和更新;其他诸如Node的发现、管理和状态监控、死亡容器所占磁盘空间及本地缓存的镜像文件的清理等工作也是由Controller Manager完成的。&/p&&p&  Scheduler 集群中的调度器,负责Pod在集群节点中的调度分配。&/p&&p&  Kubelet 负责本Node节点上的Pod的创建、修改、监控、删除等全生命周期管理,同时Kubelet定时“上报”本Node的状态信息到API Server里。&/p&&p&  Proxy 实现了Service的代理与软件模式的负载均衡器。&/p&
阅读要求:了解容器(Docker)、虚拟机等相关概念,如果没有Docker、虚拟机概念的同学,就等快哥下波福利吧。 k8s是什么? k8s 是kubernetes的简称,因为k与s之间有8个字母,而且发音也接近,因此就发音为k8s了。 k8s的由来? k8s是google开源的容器集群管理…
&p&之前的回答本来就觉得一些细节处并不严谨,现在回看=/=。我觉得严谨是一个讨论技术的必要条件,觉得现在也有能力写的严谨,于是想把回答改的尽量严谨,最后发现不如重写,顺便补充了我想补充的内容,结果就是更长=.=。Paxos是个精巧,又强大的协议,仅从过程的复杂度来说,确实如作者本人一再说的那样是个“简单的协议”,但是可以从非常多的角度来理解它为何正确,而原本的流程也并不适合直接工程化,这也是大概为什么工程上它存在如此多的变体。希望这个回答的让人更快的感受paxos的魅力,建立一个初步印象的同时不给人以误导。最后依然推荐larmport自己写的和paxos相关的三篇论文:&& The Part-Time Parliament&&、&&Paxos made simple&&、&&Fast Paxos&&前面关于Paxos的论述。&br&&/p&&p&上周和一个有真正paxos工程经验的人讨论一下paxos,paxos现在大多是应用于replication的一致性,用来实现一个 多节点一致的日志,和他 的讨论让我觉得要想真正的精确掌握paxos和它对应的强一致性领域,也许只有真正的在工程中实现过才行。这个回答只能当做是想要了解原理的入门吧,甚至可能有些微妙的地方还会产生误导。它介绍了paxos面向的问题,以及为何它的流程要这么设计,但还是希望对有兴趣阅读这个问题的有所帮助。&br&&/p&&p&现在看开头这段话是在是觉得有点羞耻,遂改之。我了解paxos是从找工作开始,比较详细的了解则是在毕设,自己动手了写了个类似Zookeeper的系统,paxos本身并不复杂,在&&paxos made simple&& Lamport用两段话就描述清楚了它的流程,他老人家也说paxos其实是个简单的算法。但是是我在工程领域见过最为精妙的算法。我想论述Paxos为什么难以理解会比描述Paxos的流程长的多的多。我最初学习Paxos是从《从Paxos到Zookeeper:分布式一致性原理与实践》,现在看来并不是个很好选择,作者讲解的方式是直接翻译论文,论述ZAB和paxos关系的部分我也觉得不是很严谨。如果真心觉得Paxos的原文不知所云,也不知道能拿来干嘛,可以从阅读Raft的论文开始,如果真的有兴趣,强推Raft作者Diego Ongaro那篇300页的博士论文《CONSENSUS: BRIDGING THEORY AND PRACTICE》,不只是讲解了Raft协议,而且系统的论述Paxos类似的一致性协议,不仅从原理,也从工程角度出发,涉及方方面面,在写毕设中了就是写不动就翻翻的良作。我个人觉得阅读任何&b&号称浅显易懂的解说Paxos算法的描述(比如下文=/=),最多只是让你更好的入门,要更深的理解Paxos以及所有等同于它的一致性协议,ZAB,Raft,ViewStamp,直接阅读相关论文,理解证明,理解它们哪里不同,为何本质上相同,与人探讨,在工程上自己实现,或者阅读开源实现的源代码才是最好的方式。分布式一致性是个有趣的领域,而Paxos和类似的协议对这个问题的重要性不喻,在过去的十年,Paxos几乎等价于分布式一致性。&/b&&br&&/p&&p&&br&&/p&&p&之前的答案最大的不严谨之处在于两个事件“先后”这种时序关系的处理上。paxos是个分布式一致性协议,它的事件需要多个节点共同参与,一个事件完成是指多个节点上均完成了自身负责的单机子事件(就让我门把这样的事件称为&分布式事件&),这样的分布式事件可以看作是多个单机子事件的复合,但&b&是即不能从两个分布式事件的先后推导出某个节点上它们的单机子事件的先后,也不能根据某个节点上两个单机子事件的先后断言它们对应的分布式事件的先后&/b&。举一个简单的例子,两个节点P1,P2;分布式事件a1设置每节点的本地变量v=1,分布式式事件a2设置每个节点本地变量v=2,如果我们称a1先于a2完成,那么对于节点P1而言,v=1发生在v=2之前还是之后都有可能;反之如果P1上v=1发生在v=2之前,a1和a2哪个县完成也都有可能。&br&&br&原来的回答有些地方论述 分布式事件a1在a2之后(先)时,默认了单节点上,a1会比a2先达成状态,或者反之。&br&&br&实际上为了论证paxos的正确性,并不需要借助于分布式事件的时序(起码无用太在意物理时序),对于paxos流程中的分布式事件,例如提案被通过,值被决定,让我们忘记它们之间物理时间上的先后关系吧。&/p&&p&&br&&/p&&p&下面就开始假装推导出paxos,作为一种理解协议的流程和协议如何保证正确性的方式。这样的推导的过程远比我想象的冗长;&b&相比之下,论文中Lamport自己推导出Paxos的过程简洁、巧妙、漂亮,但是更抽象。在末尾用自己的语言描述了这种方式,作为补充&/b&。补充的版本基本思路来自&&Paxos made simple&&,和原文略有不同;总共不到1500字,却既说明了Paxos是如何得到的,又严谨的论证了Paxos的正确性。&/p&&p&首先我们简单介绍paxos所保证的一致性的具体含义;达成一致的条件(何时达成一致);基于的一个基本的数学原理;以及它需要满足的假设。&br&&br&什么是一致性?实际上这个词在不同地方语义并不那么一致,Paxos面向的是一个理论的一致问题,这个问题的通俗描述是:&br&&br&有一个变量v,分布在N个进程中,每个进程都尝试修改自身v的值,它们的企图可能各不相同,例如进程A尝试另v=a,进程B尝试另v=b,但最终所有的进程会对v就某个值达成一致,即上述例子中如果v=a是v达成一致时的值,那么B上,最终v也会为a。&b&需要注意的是某个时刻达成一致并不等价于该时刻所有进程的本地的v值都相同&/b&,有一个原因是进程可能挂掉,你不能要求挂掉的进程任何事;更像是最终所有存活的进程本地v的值都会相同。&br&&br&这个一致性需要满足三个要求:&br&&br&1.v达成一致时的值是由某个进程提出的。这是为了防止像这样的作弊方式:无论如何,最终都令每个进程的v为同一个预先设置好的值,例如都令v=2,那么这样的一致也太容易了,也没有任何实际意义。&br&2.一旦v就某个值达成了一致,那么v不能对另一个值再次达成一致。这个要求称为安全性。&br&3.一致总是能够达成,即v总会被决定为某个值。这是因为不想无休止的等待,这个要求也称为活性。&/p&&p&Paxos中变量v达成一致的条件:
&b&N个进程中大多数(超过一半) 进程都认为v是同一个值,&/b&例如c,那么我们称&b&v被决定为c&/b&。这样即使少数进程挂掉了,也不会使得一致无法达成。&/p&&p&Paxos保证的一致性如下:&b&不存在这样的情形,某个时刻v被决定为c,而另一个时刻v又决定为另一个值d。&/b&由这个定义我们也看到,当v的值被决定后,Paxos保证了它就像是个单机的不可变变量,不再更改。也因此,对于一个客户端可以多次改写值的可读写变量在不同的节点上的一致性问题,Paxos并不能直接解决,它需要和状态机复制结合。&/p&&p&Paxos基于的数学原理:
我们称大多数进程组成的集合为法定集合,&b&两个法定集合必然存在非空交集,即至少有一个公共进程,称为法定集合性质&/b&。 例如A,B,C,D,F进程组成的全集,法定集合Q1包括进程A,B,C,Q2包括进程B,C,D,那么Q1和Q2的交集必然不在空,C就是Q1,Q2的公共进程。如果要说Paxos最根本的原理是什么,那么就是这个简单性质。同时,可以注意到,这个性质和达成一致的定义相呼应。&/p&&p&Paxos中进程之间是平等的,即不存在一个特殊的进程,这是由于&b&如果协议依赖于某个特殊的进程,那么这个进程挂掉势必会影响协议;而对于分布式环境,无法保证单个进程必然必活,能够容忍一定数量的进程挂掉,是分布式协议的必然要求。&/b&这是推导过程所要遵循的一个原则,就称为平等性原则好了。&/p&&p&消息是进程间通信的唯一手段,对于分布式环境来说,这是显然的。&/p&&p&Paxos要求满足的前置假设只有一个:消息内容不会被篡改;更正式的说是无拜占庭将军问题。&/p&&p&假装的推导总是先从一些具体的场景开始,既然Paxos的假设仅仅只是消息不会被篡改,保证了这点任意场景下都能保证一致性,那么对于举例的场景它必然是能够保证一致性的;因此不妨先使得协议流程能在当前场景下能保证一致性,然后再举出另一个场景,当前的协议流程无法再该场景下满足一致性,接着再丰富协议流程,满足该场景,如此往复,最终得到完整的paxos协议,最后再不失一般性的论证协议对任意场景都能保证一致性。&/p&&p&进程的平等性假设会带来如下的问题,考虑如下的场景1:三个进程的场景P1,P2P3(n个进程的场景类似),P1尝试令v的值被决定为a,P2尝试令v被决定为b。假设它们都先改写了自身的v值,然后发送消息尝试改修P3的v值。显然如果P3收到两个消息后都满足了它们的企图,那么v就会两次被决定为不同的值,这破坏了之前的定义。因此P3必须得拒绝掉其中一个进程的请求,&b&如何拒绝也是我们最先考虑的问题。&/b&一个最简单的拒绝策略是先来后到,P3只会接受收到的第一个消息,拒绝之后的消息,即只会改写v一次。按照这个策略,如果P1发送的消息首先到达P3,那么P3接受该消息令v=a,拒绝掉后到的来自P2的消息。但是这个策略会引入一个另外的问题;在场景1的基础上考虑这样的场景1’,P3也尝试决定v的值,P3尝试令v被决定为c,那么P1,P2,P3都尝试修改v的值,首先P1令v=a,P2令v=b,P3令v=c(相当于自己给自己发消息),按照之前的策略,每个进程只会改写v的值一次,那么将永远不会出现两个进程的v值相等的情况,即v永远无法被决定。更正式的说,这样的协议不满足活性,活性要求协议总能达成一致。由此我们也得到第一个结论:&b&进程必须能够多次改写v的值&/b&。同时我们也要意识到:&b&当进程收到第一个消息时,进程是没有任何理由拒绝这个消息的请求的。&/b&&/p&&p&&br&&/p&&p&拒绝策略总是需要有一个依据,之前我们的依据是消息到达的先后,只接受第一个到达的消息,但这导致不满足活性。现在我们需要另一个拒绝策略,也就是需要另一个依据,这个依据至少能够区分两个消息。&b&为此我们引入一个ID来描述这个消息,这样就可以根据ID的大小来作为拒绝或接受的依据;&/b&选择ID更大的消息接受和选择ID更小的消息接受是两种完全对称的策略,不妨选择前者。这个策略不会导致明显的活性问题,ID更大的消息总是能被接受,一个节点可以多次更改v的值。例如在场景1'中,只要P1的消息ID比P3发送给自己的消息ID更大,P3就会接受P1的消息,令v=a,从而令v的值被决定为a。再来考虑最初的场景1,不妨假设P1的消息ID大于P2的消息ID,根据P3收到消息的先后可以分为两种情况:&br&&br&1. P3先收到P1的消息,记做场景1-2。由于P1的消息是P3收到的第一个消息,P3接受该请求,令v=a;同时为了能对之后收到的消息作出是否接受的判断,P3需要记录该消息的ID作为判断的依据。之后P3又收到P2的消息,该消息的ID小于P3记录的ID(即P1的消息ID),因此P3拒绝该消息,这样我们的目的就达到。&br&&br&2. P3先收到P2的消息,记作场景1-3。同样P3接受该消息,令v=b,记录该消息的ID。之后P3收到P1的消息,由于P1的消息ID大于P3记录的ID,因此P3无法拒绝该消息,之前的问题依旧存在。&/p&&p&尽管对于场景1-3,目前的策略依旧无法保证一致性,但是起码我们缩小协议不适用的范围。先总结下我们目前的策略,并定义一些称谓以方便后面的论述。&b&我们称呼进程P发送的尝试修改另一个进程中变量v的值的消息称之为提案,记作Proposal;提案的ID记作proposal_id;提案中会附带一个值,如果一个进程接受一个提案,则修改自身的v值为该提案中的值。如果一个提案被大多数进程所接受,那么称提案被通过,此时显然v被决定为提案中的值。进程P记录的接受的提案ID记做a_proposal_id。&/b&&/p&&p&之前我们尚未清晰定义a_proposal_id,实际上我们也就并未清晰的定义我们的拒绝策略,当P收到一个提案Proposal-i时,可能已经收到过多个提案,Proposal-i.proposal_id该和其中哪个提案的proposal_id比较,我们并未定义。我们定义为其中的最大者,这样实际上进程P只需维护一个a_proposal_id即可,当收到一个Proposal时,更新a_proposal_id = Max(Proposal.proposal_id,a_proposal_id)。同时在之前的描述中我们应当注意到实际上一个进程存在&b&两个功能&/b&:&br&&br&1. 进程主动尝试令v的值被决定为某个值,向进程集合广播提案。&br&&br&2. 进程被动收到来自其它进程的提案,判断是否要接受它。&br&&br&因此可以把一个&b&进程分为两个角色,称负责功能1的角色是提议者,记作Proposer,负责功能2的角色是接受者,记作Acceptor。&/b&由于两者完全没有耦合,所以&b&并不一定需要在同个进程&/b&,但是为了方面描述,我们假定一个进程同时担任两种角色,而实际的工程实现也往往如此。&/p&&p&接着我们尝试解决场景1-3,这看起来很难。P3作为接受者,收到P2的提案之前未收到任何消息,只能接受该提案,而由于P1的提案proposal_id大于P2的提案,我们的拒绝策略也无法让P3拒绝P2。我们先不急着推导具体可行的策略,先考虑下解决1-3场景可能的角度,有如下三种角度可以入手:&br&&br&1. P3能够拒绝掉P2的提案。&br&&br&2. P3能够拒绝掉P1的提案。&br&&br&3. 限制P1提出的提案中的值,如果P1的提案中的值与P2的提案一致,那么接受P1也不会破坏一致性。&br&&br&接着我们分析三个角度的可行性:&br&&br&角度1需要P3有做出拒绝的依据,由于消息是进程间通信唯一手段,这要求P3在收到P2的提案之前必须先收到过其它消息。对于场景1-3,只有P1,P2是主动发送消息的进程,P2当然不可能额外还发送一个消息试图令P3拒绝自己随后的提案。那么唯一的可能是P1在正式发送提案前,还发送了一个消息给P3,这个消息先于P2的提案到达,给了P3拒绝P2提案的理由。如果沿用目前的拒绝策略,那么P1只需先发送随后提案的proposal_id给P3,P3更新a_proposal_id 为 该消息附带的proposal_id,这样a_proposal_id将大于P2的提案的proposal_id,而导致P2的提案被拒绝,似乎这是一个可行的角度。&br&&br&对于角度2,我们目前的策略无法做到这一点,因此除了proposal_id外,我们还得给提案附加上额外的信息作为另外的拒绝策略的依据。提案由进程提出,也许我们可以附加进程的信息,但是就算P3得知P1的提案由P1提出,P3又凭什么歧视P1,这违反进程的平等性假设。似乎这个角度不是一个好角度。&br&&br&最后我们分析一下角度3,角度3提供了与1,2截然不同的思路,它不再是考虑如何拒绝,而把注意力放在&b&如何对提案的值做出恰当的限制上&/b&。对于场景1-3而言,从这个角度,由于P3无法拒绝P1和P2的提案中的任何一个,因此&b&P1的提案的值就必须与P2的提案一致&/b&;这也意味着了P1在正式提出提案前,需要有途径能获悉P2的提案的值。如我们上面一直强调的,消息是唯一的通信手段,P1必须收到来自其它节点消息才有可能得知P2提出的提案的值。P1可以被动的等待收到消息,也可以主动的去询问其它节点等待回复。后者显然是更好的策略,没有收到想要的消息就一直等待未免也太消极了,这种等待也可能一直持续下去从而导致活性问题。&/p&&p&经过上面的分析,我们暂时排除了从角度2入手(实际上后面也不会再考虑,因为从1,3入手已经足以解决问题)。下面将沿着角度1,3进行更深入的分析,我们先尝试从角度1出发,毕竟考虑如何拒绝已经有了经验。先来总结下我们在分析角度1时引入的额外的流程:&br&&br&进程P在发送提案前,先广播一轮消息,消息附带着接下来要发送的提案的proposal_id。由于该消息和接下来发送的提案相关,且在提案被提出之前发送,不妨称这个消息为&b&预提案,记作PreProposal,预提案中附带着接下来的提案的proposal_id&/b&。当作为接受者的进程Pj收到预提案后,更新Pj. a_proposal_id。还记得我们之前的拒绝策略中a_proposal_id的更新策略嘛:a_proposal_id = max(proposal_id,a_proposal_id),a_proposal_id是递增的。因此如果预提案的proposal_id小于Pj.a_proposal_id,Pj完全可以忽略这个预提案,因为这代表了该预提案对应的提案的proposal_id小于Pj.a_proposal_id,必然会被拒绝。我们沿用之前拒绝策略中a_proposal_id的更新策略。这样当收到预提案或者提案后,a_proposal_id的值均更新为 max(a_proposal_id,proposal_id)。&br&&br&接着我们来看看引入了预提案后,能否真正解决场景1-3。根据P1和P2的预提案到达P3的先后也存在两种场景:&br&&br&1.场景1-3-1:P1的预提案先到达,P3更新a_proposal_id 为该提案的proposal_id,这导致随后到达的P2的提案的proposal_id小于a_proposal_id,被拒绝。满足一致性&br&&br&2.场景1-3-2:P2的提案先到达,P3接受P2的提案,此时和原始的场景1-3存在同样的问题。归根结底,预提案阶段&b&能否使得P3拒绝该拒绝的,也依赖消息到达的顺序&/b&,和提案阶段的拒绝策略存在相同的问题,但至少又缩小了不能保证安全性的场景范围。&br&&br&幸好我们还有角度3可以着手考虑,所以仍有希望完全解决场景1-3。在深入角度3之前,先总结下协议目前为止的流程,现在协议的流程已经分为了两个阶段:&b&预提案阶段和提案阶段&/b&,两种消息:&b&&i&预提案 &/i&&/b&和&b&&i&提&/i&案&/b&,两种角色:&b&&i&接受者 &/i&&/b&和 &b&&i&提议者&/i&&/b&,流程如下:&/p&&p&&b&&i&阶段一&/i&&/b& &b&提议者Proposer:向接受者Acceptor广播预提案,附带接下来提案Proposal的proposal_id&/b& &b&接受者Acceptor:收到预提案后更新a_proposal_id = max(proposal_id,a_proposal_id)&/b& &/p&&p&&b&&i&阶段二
&/i&&/b& &b&提议者Proposer:向接受者Acceptor广播提案,和之前的预提案共享同一个proposal_id&/b& &b&接受者Acceptor:如果收到的提案的proposal_id&= a.proposal_id,那么接受这个提案,更新a_proposal_id = max(proposal_id,a_proposal_id)&/b&&/p&&p&&br&&/p&&p&为了更形象,之前的讨论是基于三个进程的场景,实际上对于N进程的场景也是一样的。N个进程时,与之前场景1对应的场景是:&/p&&p&N个进程,存在两个进程Pi,Pj,Pi尝试另v被决定为a,Pj尝试另v被决定为b,Pi提出的预提案记作PreProposal-i,提案记作Proposal-i;Pj的预提案PreProsal-j,提案Proposal-j。&/p&&p&之拒绝策略的讨论都是基于一个关键的进程P3,只要P3最终能拒绝Proposal-i和Proposal-j中的一个,两个提案就不会都被通过,那么一致性就不会被破坏。Pi的提案被通过代表了存在一个法定集合Q-i,Q-i中的进程都接受了Proposal-i,Pj同理,存在一个Q-j,Q-j中的进程都接受了Proposal-j。&b&由于法定集合的性质,两个多数集Q-i和Q-j中必然存在一个公共进程Pk。Pk即相当于场景1中的P3,只要Pk能够拒绝Proposal-i和Proposal-j中的一个,协议依旧是安全的。&/b&为了不失一般性,下&b&面我们都以N个进程的场景作为讨论的基础,&/b&称为场景2,由于&b&场景1和场景2可以一一对应&/b&,所以接下来顺着限制提案的值的角度,&b&我们直接针对场景2-3-2,之前的场景和场景1一样,我们的拒绝策略已经足以应付。&/b&v的值被决定代表有一个提案,它被法定数目的集合接受,我们称这为提案被通过。&/p&&p&首先我们看下场景2-3-2,Pi对应场景1-3-2中的P1,Pj对应P2,Pk对应P3。Pj的提案Proposal-j最终会被法定集合Q-j接受,即v的值被决定为b,且Proposal-i.proposal-id & Proposal-j.proposal_id。我们需要限制Pi的提案的值,不能让Pi自由的给Proposal-i中的v赋值。在2-3-2中,&b&由于拒绝策略失效,所以只能令Proposal-i.v = Proposal-j.v=b&/b&。要做到这一点,正如前面的分析所言,Pi需要先主动询问进程集合,来得知Proposal-j.v =b这一事实。显然Pi是没有先验信息来得知Proposal-j由哪个进程提出,也不知道Q-i和Q-j的公共节点Pk是谁,因此Pi只能广播它的查询。由于我们需要允许少数进程失败,Pi可能只能得到大多数进程的回复,而这之中可能不包括Pj。我们称这些回复Pi的查询的进程的集合为Q-i-2,为了描述更简单,无妨假设Q-i-2=Q-i。尽管Pi的查询可能得不到Pj的回复,好在作为将会被通过的提案,Proposal-j将会被Q-j内所有进程接受,因此如果进程作为接受者在接受提案时,顺便记录该提案,那么Q-j内所有进程都将得知Proposal-j.v=b。&b&由于Pk属于Q-i和Q-j的交集,所以Pk即收到了Pi的查询,又接受了提案Proposal-j。&/b&之前我们已经引入了预提案阶段,显然我们可以为预提案附带上查询的意图,即Pk作为接受者收到Pi的预提案后,会回复它记录的接受过的提案。有一个问题是Pk此时是否已经记录了Proposal-j呢?很巧的是&b&在场景2-3-2中,Pj的提案Proposal-j是先于Pi的预提案PreProposal-i先到达&/b&,所以Pk已经记录了Proposal-j.v = b,Pj收到的来自Pk的回复中包含了提案Proposal-j,而2-3-2之外的场景,拒绝策略已经足以应付。这里依旧还有两个问题,先讨论第一个:&br&&br&实际上除了Pi和Pj外可能还会有多个进程发起预提案和提案,所以收到 PreProposal-i时Pk可能已经接受过多个提案,并非只有Proposal-j,那么Pk应该回复PreProposal-i其中哪个提案,或者都回复?Pk并不知道Proposal-j会被通过,它只知道自己接受了该提案。&b&都回复是个效率很低但是稳妥,可以保证Pk不会遗漏Proposal-j&/b&,Pk已经回复了它所能知道的全部,我们也无法要求更多。需要注意到的是进程是平等的,所以Q-i中所有进程都和Pk一样回复了它接受过的所有提案。当Pi收到所有来自Q-i的回复时,随之而来的是第二个问题:&br&&br&Pi收到了多个Proposal作为一个Acceptor组成的法定集合Q-i对PreProposal-i的回复,记这些Proposal组成的集合记坐K-i,那么它应当&b&选择K-i中哪个一个提案的值作为它接下来的提案Proposal-i的v值&/b&?记最终选择的这个提案为Proposal-m。&/p&&p&在场景2-3-2中,我们第一直觉是希望选择的Proposal-m 即是 Proposal-j,但是实际上,我们只要&b&保证Proposal-m .v = Proposal-j.v即可&/b&。从另一个角度 ,K-i中很可能存在这样的&b&提案Proposal-f,Proposal-f.v!=Proposal-j.v&/b&,我们要做的是&b&避免&/b&选择到这类提案。我们可以根据一些依据瞎选碰碰运气,但是这并明智。我们不妨假设存在一个策略cf,cf满足需求,使得选择出提案Proposal-m满足Proposal-m.v= Proposal-j.v。然后让我们来分析一下此时Proposal-f有什么特征。&/p&&p&&b&Proposal-f能够被提出,代表存在一个多数集合Q-f,Q-f中每个进程都接受了PreProposal-f&/b&,同时假设是进程P-f提出了PreProposal-f和Proposal-f。Q-f和Q-j必然存在一个公共节点,记做Ps,Ps即接受了PreProposal-f又接受了Proposal-j。Ps收到PreProposal-f和Proposal-j的顺序只有两种可能:&br&&br&1.Ps先收到PreProposal-f&br&&br&2.Ps先收到Proposal-j&br&&br&PreProposal-f.proposa-id和Proposal-j. proposal_id的大小也只有两种可能,&b&不妨先假设PreProposal-f.proposal_id & Proposal-j.proposal_id&/b&。&/p&&p&对于情形1,Ps先收到PreProposal-f,接受它,更新Ps.a_proposal_id = PreProposal-f.proposal_id & Proposal-j.proposal_id,同时之前的a_proposal_id的更新策略又使得Ps.a_proposal_id是递增的,于是导致收到Proposal-j时,Proposal-j.proposal_id小于Ps.a_proposal_id,被拒绝,而这于Ps的定义矛盾。&br&&br&对于情形2,Ps将把提案Proposal-j回复给PreProposal-f。&b&由于我们假设了策略cl的存在,于是P-f在收到所有Q-f对PreProposal-f的回复后,将令Proposal-f.v=Proposal-j.v&/b&,cl就是干这个的。因此由于Proposal-f.v!=Proposal-j.v矛盾。&br&&br&于是当假设PreProposal-f.proposal_id & Proposal-j.proposal_id 时,情形1,2我们都得出了矛盾,同时两者的proposal_id又不相等(最初的假设),所以&b&必然PreProposal-f.proposal_id & Proposal-j.proposal_id,即Propsoal-f.proposal_id & Proposal-j.proposal_id&/b&。&br&&br&于是我们得到的结论是:如果策略cl存在,提案Proposal-j最终会被通过,任意一个proposal_id更大的预提案PreProposal-i,对于它得到的Q-i的回复K-i中的Proposal-f,只要Proposal-f.v!= Proposal-j.v,那么必然 Proposal-f.proposal_id & Proposal-j.proposal_id。&br&&br&既然K-i中所有v值不等于Proposal-j.v的提案,proposal_id都比Proposal-j更小,&b&那代表所有proposal_id比Proposal-j更大的提案,v值都等于Proposal-j.v&/b&,&b&因此选择K-i中proprosal_id最大的提案,就能保证Proposal-i.v = Proposal-j.v&/b&。于是我们得到了策略cl的具体形式。&br&&br&我们得到了具体可行的策略cl是&b&建立在策略cl存在这一前提之上&/b&,因此反过来,对于这个具体的选值策略cl,结合之前我们得到了协议流程,它是否能保证如下的性质&b&CP1&/b&,依旧需要进一步的论证 :&br&&b&如果一个提案Proposal-j最终会被通过,那么对于任意的一个提案Proposal-i,如果Proposal-i.proposal_id & Proposal-j.proposal_id,那么Proposal-i.v = Proposal-j.v。&/b&&/p&&p&我们先总结下目前得到的协议流程:&/p&&p&&b&&i&阶段一 预提案阶段&/i&&/b& &b&提议者Proposer:向接受者Acceptor广播预提案,附带接下来提案Proposal的proposal_id&/b& &b&接受者Acceptor:收到预提案后更新a_proposal_id = max(proposal_id,a_proposal_id),如果预提案的proposal_id大于a_proposal_id,那么回复该预提案的提议者改接受者接受过的所有提案。&/b&&/p&&p&&b&&i&阶段二 提案阶段&/i&&/b& &b&提议者Proposer:等待直到收到大多数接受者对预提案的回复,从所有回复的提案组合成的集合K中挑选proposal_id最大的提案,以该提案的值作为本次提案的值。如果K是空集,那么可以给提案任意赋值。&/b& &b&向接受者Acceptor广播提案,和之前的预提案共享同一个proposal_id&/b& &b&接受者Acceptor:如果收到的提案的proposal_id&= a.proposal_id,那么接受这个提案,更新a_proposal_id = max(proposal_id,a_proposal_id)&/b&&/p&&p&这些流程是为了解决举例的场景而不断丰富的,接着就让我们论证下协议流程是否总是可以确保CP1。&/p&&p&&b&首先假设Proposal-i.v != Proposal-j.v,如果得出矛盾即可证明CP1。&/b&在尝试推出矛盾前,我们先做一些定义,以便后续的推导。&br&&br&记大多数接受者组成的法定集合为Q,&b&K是提议者在提案阶段收到的所有Q回复的提案组成的集合&/b&,如果K不为空&b&,记K中proposal_id最大的提案是MaxProposal(K),本次提案的值即是MaxProposal(K).v&/b&;如果K是空集,那么MaxProposal(K).v = null。特别的,对于提案Proposal-i,回复它预提案接受者的集合为Q-i,回复的提案组成的集合为K-i,&b&Proposal-i.v = MaxProposal(K-i)&/b&,Proposal-i.v=null代表可以随意赋值。为了描述方便,我们令Proposal-i的proposal_id为i,即Proposal-i代表了proposal_id=i的提案,Proposal-j意味着Proposal-j.proposal_id =j。&br&&br&论证过程如下:&br&&br&(1) Proposal-i.v!=Proposal-j.v,即MaxProposal(K-i) .v!= Proposal-j.v,即MaxProposal(K-i)!=Proposal-j&br&&br&(2) Proposal-j最终会被通过,代表最终会存在一个多数集合Q-j,Q-j中每个接受者都接受了Proposal-j。&br&&br&(3) 两个多数集必然存在公共成员,故Q-j和Q-i必然存在一个公共的进程Pk,Pk即收到了PreProposal-i又收到了Proposal-j,且都接受了它们;Pk收到消息的先后关系只存在如下两种可能:&br&&br&1.Pk先收到了PreProposal-i&br&&br&2.Pk先收到了Proposal-j&br&&br&(4) 情形1中Pk先收到了PreProposal-i,那么Pk收到Proposal-j时,Pk.a_proposal &= PreProposal-i.proposal_id >Proposal-j.proposal_id,Pk会拒绝Proposal-j,与(3)矛盾,因此情况1不可能,&b&Pk必然是先收到Proposal-j&/b&。&br&&br&(5) 情形2中Pk收到PreProposal-i时,已经接受了Proposal-j,因此Pk回复PreProposal-i的提案中包含了Proposal-j,因此K-i中必然包含了Proposal-j。&br&&br&(6) 由(1)已知MaxProposal(K-i) != Proposal-j,即&b&存在另一个提案Proposal-m&/b& = MaxProposal(K-i),而Proposal-j属于K-i,因此&b&Proposal-m.proposal_id & Proposal-j.proposal_id&/b&,且&b&Proposal-m.v != Proposal-j.v&/b&。&br&&br&(7)由预提案阶段,接受者回复预提案的条件可知:Proposal-i.proposal_id大于集合K-i中任意一个提案的Proposal-id,&b&故Proposal-i.proposal_id&Proposal-m.proposal_id。&/b&&br&&br&(8) 目前我们已经论证如下一点:&br&&br&在Proposal-j最终会被通过的前提下,&b&如果存在一个提案Proposal-i.v!=Proposal-j.v,且Proposal-i.proposal_id &Proposal-j.proposal_id,&/b&我们一个数学符号来带表示这个情况,记&b&CF(j,i);那么 必然存在&/b&一个提案&b&Proposal-m, Proposal-m!=Proposal-j.v,且Proposal-m.proposal_id & Proposal-j.proposal_id&/b&,同样的我们可以记做&b&&i&CF(j,m)&/i&&/b&。并且Proposal-m.proposal_id & Proposal-i.proposal_id,&b&m & i&/b&。&br&&br&即如果CF(i,j)成立,那么必然CF(m,j)成立,且i&m,即 &b&CF(i,j) —& CF(m,j)&/b&。这个过程可以继续往下递归,但由于区间[j,i]范围是有限的,因此一定会递归到一个CF(j,e),此时不可能存在一个提案,它的proposal_id在区间(j,e)内,无法往下递归,这与(8)矛盾。这也就意味着CF(e,j)不成立,而如果CF(i,j)成立,那么CF(e,j)成立,因此CF(i,j)不成立,故假设不成立,即Proposal-i.v 必然等于Proposal-j.v,即证CP1。&/p&&p&通过归约的方式得出矛盾的方式依旧有些抽象,我们可以通过更好的定义假设来更容易得到的矛盾:&br&&br&我们加强对Proposal-i的约束;先假设存在一个提案的非空集合KD,KD中的任意一个提案Proposal-k,Proposal-k.v!=Proposal-j.v,且Proposal-k.proposal_id & Proposal-j.v;再假设&b&Proposal-i是KD中proposal_id最小的提案&/b&;由于KD是非空集合,故Proposal-i必然存在。&br&&br&我们依旧可以从Proposal-i出发,(1)~(7)与上面相同,同理得到:存在一个提案Proposal-m, Proposal-m!=Proposal-v,且Proposal-m.proposal_id & Proposal-j.proposal_id,且Proposal-m.proposal_id & Proposal-i.proposal_id。&br&&br&显然Proposal-m满足集合KD对提案的要求,故Proposal-m属于KD,又Proposal-m.proposal_id&Proposal-i.proposal_id,这和Proposal-i是KD中proposal_id最小的提案的定义矛盾。因此不存在这样的非空集合KD,即不存在一个提案Proposal-k,Proposal-k.v!=Proposal-j.v且Proposal-k.proposal_id&Proposal-j.proposal_id,即如果一个提案Proposal-j最终会被通过,对于任意的一个提案Proposal-i,如果Proposal-i.proposal_id & Proposal-j.proposal_id,那么必定Proposal-i.v = Proposal-j.v,即CP1。&/p&&p&CP1约束了proposal_id大于Proposal-j的提案的值,保证了如果一个提案Proposal-j最终会被通过,不会存在另一个proposal-id更大且值不同的提案被通过,因为这些提案的值都和Proposal-j相同。那么对于proposal_id更小的提案呢? 我们假设存在一个提案Proposal-o,Proposal-o.proposal_id & Proposal-j.proposal_id,且Proposal-o.v!=Proposal-j.v,Proposal-o最终会被通过,将CP1应用于Proposal-o,则可知Proposal-j不存在,这矛盾,故Proposal-o不存在。故由CP1我们可知:如果一个提案Proposal-j最终会被通过,那么不存在另一个提案,它最终会被通过,且它的值与Proposal-j不同。由此协议必然是安全的。&/p&&p&虽然我们得到了一个安全的一致性协议,基本上它就是Paxos,但是真正的Paxos要比我们假装推导出的协议更简单一点。&br&&br&回过头来看下我们的阶段1中接受者Acceptor的行为,它要回复所有的它接受过的提案,从实践的角度,不论是在本地保存所有它接受过的提案还是通过网络将它们传输给提议者,开销都太大且不可控。再看下阶段二中,提议者的选值策略,它只是选择了收到的多数集接受者回复的提案中proposal_id最大的那一个,因此&b&接受者实际上只需要回复它接受过的proposal_id最大的提案即可,因为其它提案根本不可能会被选值策略选中&/b&。因此最终的协议如下,它就是Paxos:&/p&&p&&b&&i&阶段一 预提案阶段&/i&:&/b& &b&提议者Proposer:向接受者Acceptor广播预提案,附带接下来提案Proposal的proposal_id&/b& &b&接受者Acceptor:收到预提案后更新a_proposal_id = max(proposal_id,a_proposal_id),如果预提案的proposal_id&a_proposal_id,Acceptor回复记录的接受过的proposal_id最大的提案。&/b& &/p&&p&&b&&i&阶段二 提案阶段&/i&:&/b& &b&提议者Proposer:等待直到收到大多数接受者对预提案的回复,从所有回复的提案组成的法定数目的提案集合K中挑选proposal_id最大的提案,以该提案的值作为本次提案的值。如果K是空集,那么可以给提案任意赋值。然后把该提案广播给接受者们,提案和预提案共享同一个proposal_id。&/b& &b&接受者Acceptor:如果收到的提案的proposal_id&= a.proposal_id,那么接受这个提案,更新a_proposal_id = max(proposal_id,a_proposal_id),更新记录的提案。&/b&&/p&&p&&br&&/p&&p&&br&&/p&&p&&b&补充部分&/b&:&br&&br&上面的过程从具体的场景开始推导Paxos,虽然直观但是繁琐,如果从抽象的概念和分析入手,那么过程将会相当简洁和漂亮,这也是Lamport的原始论文中的方式。这种方式理解起来更困难的地方在于:&br&&br&1.没有任何具体的认知下,直接抽象的讨论容易让人摸不着头脑。&br&&br&2.大神总是在一些地方觉得显然而不加以展开论述,而普通读者如我的内心OS:显然你mei!&br&&br&但是原文引出Paxos算法的过程实在是简洁、漂亮;而经过上面的轮述,相信有了直观的印象后,再来看抽象的方式也不那么困难,所以补充下。&/p&&p&回顾下定理&b&CP1&/b&:&br&&br&如果一个提案Proposal-j最终会被通过,那么对于任意的一个提案Proposal-i,如果Proposal-i.proposal_id & Proposal-j.proposal_id,那么必定Proposal-i.v = Proposal-j.v。&/p&&p&上面我们已经论证了只要协议能够保证CP1就能够保证一致性。但是CP1依旧过于宽泛,从CP1引出具体的协议流程依然是一头雾水,那么我们是否可以得到一个更加具体的定理CP2,保证CP2即可保证CP1,同时从CP2出发更容易引出协议的具体流程。为了描述方便,我们令Proposal-i的proposal_id为i,即Proposal-i代表了proposal_id=i的提案。&/p&&p&要导出CP2不妨先考虑下如何证明CP1,利用归纳法,只要如能证明如下性质成立,即可证明CP1:&br&&b&如果proposal_id在区间[j,i)内任意的提案,提案的值均为Proposal-j.v,那么必定Proposal-i.v=v;这个定理记做CP1_2。&/b&&br&&br&现在我们用高中时简单而效果神奇的归纳法,利用CP1_2证明下CP1:&/p&&p&假设propsal_id小于i的提案中最大的提案是Proposal-(i-1)。&/p&&p&1.如果对于[j,i-1)内的任意提案,值均为Proposal-j.v,那么由CP1_2可知Proposal-i.v = Proposal-j.v。&/p&&p&2.由1可知如果对于[j,i-1)内的任意提案,值均为Proposal-j.v,[j,i)内的任意提案,值均为Proposal-j.v&/p&&p&3.假设Proposal-(j+1)是proposal-id大于j的最小提案,由CP1_2可知Proposal-(j+1).v = Proposal-j.v&/p&&p&4.由3,2归纳可知[j, &img src=&//www.zhihu.com/equation?tex=%5Cinfty& alt=&\infty& eeimg=&1&& )内任意提案Proposal-i,Proposal-i.v = Proposal-j.v,即CP1&/p&&p&来看下CP1_2,相比CP1,它结论不变,但是多了一个前置条件:&b&proposal_id在区间[j,i)内任意的提案值均为Proposal-j.v;这是一个重大的进步。&/b&CP1_2相比CP1看起来容易保证 很多,但是它们却是等价的。考虑CP1_2的三个前置条件:&/p&&p&1.i & j&br&2.提案Proposal-j最终会被通过。因此由提案被通过的定义可知必然存在一个法定集合Q-j,Q-j中任意一个接受者最终都接受了Proposal-j&br&3.proposal_id在区间[j,i)内的提案的值均为Proposal-j.v&br&&br&对于任意的一个法定集合Q,&b&考虑Q最终(包括过去和未来的所有时空)会接受的所有proposal_id小于i的提案组成的集合K&/b&。根据法定集合性质,Q和Q-j必然存在一个公共的节点,即Q中必然存在一个节点,该节点最终会接受Proposal-j,因此&b&集合K包含Proposal-j。&/b&&/p&&p&由K包含Proposal-j可知K中最大的提案proposal_id &= j;由CP1_2的前置条件3和K的定义可知如果K中存在proposal-id大于j的提案,那么该提案的值等于Proposal-j.v,因此K中proposal_id最大的提案的值等于Proposal-j.v。&br&&br&综上所述由CP1_2的前置条件可知:&b&对于任意的一个法定集合Q,Q最终会接受的proposal_id小于i的提案组成的集合K,K中proposal_id最大的提案的值必定为Proposal-j.v&/b&。如果我们能证明该条件下,Proposal-i.v = Proposal-j.v,即可证明CP1_2。将CP1_2的前置条件替换为该条件,我们可以得到一个如下的性质&b&CP2&/b&,保证CP2即可保证CP1_2:&br&&b&对于任意的一个法定集合Q,Q最终会接受的所有proposal_id小于i的提案组成的集合K,如果K中proposal_id最大的提案的值为Proposal-j.v;那么Proposal-i.v = Proposal-j.v。&/b&&/p&&p&而引出满足CP2的流程就比较容易了,由于集合K中proposal_id最大的提案的值等于Proposal-j.v,看起来只要令Proposal-i的值为K中proposal-id最大提案的值就可以保证CP2。由于Q是任意一个法定集合,因此获取K似乎在实现上也不难,提出Proposal-i的提议者只要向Q中所有接受者询问即可。&/p&&p&&b&然后: CP2 —& CP1_2—& CP1 —&一致性&/b&&/p&&p&但是实际上获取K没有那么简单,K包含的是Q所有最终接受的proposal-id小于i的的提案,不仅包含&b&已经接受过&/b&的提案,还包括&b&未来会接受&/b&的提案。获取&b&已经接受过的提案是容易的&/b&,Q中的接受者只需记录它所有接受过的提案,当收到提出Proposal-i的提议者询问时,回复当中proposal_id小于i的提案即可;&b&但是如何知晓未来?&/b&我们可以换个思路,&b&既然无法知晓未来,那么我们约束未来&/b&,收到询问后,&b&令Q中的接受者都承诺不再接受任何proposal_id小于i的提案&/b&,即接受者未来将不接受任何proposal_id小于i的提案;既然未来已不存在,那么Proposal-i的提议者根据Q的回复获能得到&b&完整的K。&/b&&/p&&p&&br&&/p&&p&于是协议的流程如下:&br&&br&对于提议者,在正式提案前,先向任意的法定集合Q发送一个消息,这个消息即是预提案,消息中要附带提案的proposal-id,作为接受者&b&承诺&/b&和&b&回复&/b&的依据。&br&&br&接受者收到预提案后,&b&承诺:&/b&不再接受比预提案中附带的proposal-id更小的提案;并&b&回复:&/b&已经接受的proposal-id比于提案的proposal-id更小的提案,如之前所论述的,回复的所有满足条件的提案可以优化为只回复一个比预提案proposal_id更小的提案中proposal_id最大的那个提案。&/p&&p&提议者收到所有Q中接受者回复的提案后,挑选其中proposal_id最大的提案的值作为本次提案的值。&/p&&p&这样我们就得到了Paxos中最为关键的几步,阅读了之前冗长的假装推导,相信读者很容易就能补全它得到完整的Paxos。&/p&&p&相比于之前近万字的假装推导,这个推导过程才1500字左右,但是即说清了Paxos是如何得出的,又论证Paxos为何正确,简洁却更有力。所以最后还是建议真有兴趣的话去看下原文,在我看来它无疑是计算机领域那数不尽的论文中最值得阅读的那一类。末尾我所描述的版本思路来自&&Paxos made simple&&,基本一致但也并不完全相同;而&& The Part-Time Parliament&&则别有一番风味。&/p&&p&最后需要注意的是Paxos并不完全满足开头解决一致性问题需要满足的三个条件中的3。理论上,Paxos存在永远无法达成一致的可能,哪怕是在所有进程都存活的情况下。想象一下这样的场景,一个提案Proposal-j被提出时,恰好一个proposal-id更大的预提案Proposal-i被提出,导致Proposal-j无法被通过,而Proposal-i同样的 又因为一个proposal_id更大的其它预提案被提出,导致无法被通过。这种情况理论上存在无限递归的可能,这个问题也称为活锁;FLP早就证明了就算是容忍一个进程的失败,异步环境下任何一致性算法都存在永不终止的可能。但是实际的工程中,很多手段可以来减小两个提案的冲突概率,使得v被决定的均摊开销是一个提案,多个提案还无法决定v值的情形是极小概率事件,且概率随着提案个数增加越来越小。另外的一点,通常认为Paxos可以容忍少数进程挂掉 ,但这只是为了保证它的活性,对于安全性,实际上Paxos永远满足1,2,哪怕进程都挂掉了,此时只是显然一致无法达成而已。&/p&
之前的回答本来就觉得一些细节处并不严谨,现在回看=/=。我觉得严谨是一个讨论技术的必要条件,觉得现在也有能力写的严谨,于是想把回答改的尽量严谨,最后发现不如重写,顺便补充了我想补充的内容,结果就是更长=.=。Paxos是个精巧,又强大的协议,仅从过…
&figure&&img src=&https://pic1.zhimg.com/v2-607cbe771a65deb6b5942e_b.jpg& data-rawwidth=&1226& data-rawheight=&912& class=&origin_image zh-lightbox-thumb& width=&1226& data-original=&https://pic1.zhimg.com/v2-607cbe771a65deb6b5942e_r.jpg&&&/figure&&p&文章很长,总字数10000左右,建议&b&先收藏并点赞后&/b&(敲黑板!人与人之间需要信任!),于公交上,地铁上,马桶上阅读。&/p&&hr&&p&更新:&/p&&p&如果你看完文章不过瘾,想系统的认识和学习手机摄影,可以参加我的Live课程,课程详情可以点击下面的链接:&/p&&a href=&https://www.zhihu.com/lives/794368& class=&internal&&&span class=&invisible&&https://www.&/span&&span class=&visible&&zhihu.com/lives/9543063&/span&&span class=&invisible&&&/span&&span class=&ellipsis&&&/span&&/a&&br&&p&&br&&/p&&hr&&p&以下为原文:&/p&&p&&b&写在前面&/b&&/p&&p&这个世界上,每天会产生很多张照片,其中绝大多数都是由智能手机拍摄的。&/p&&p&这个世界上,智能手机每天会产生很多张照片,其中绝大多是都是iPhone拍摄的。&/p&&p&这个世界上,iPhone拍摄了很多张照片,但其中绝大多数的人并不了解他手机的内置相机。&/p&&p&&b&所以,我写下这一份iPhone完全操作指南,让你重新认识这个叫做iPhone的相机到底能够做什么。&/b&&/p&&p&我相信,到时候你一定会回头看,哦,原来不需要什么软件,这内置相机就已经足够强大。&/p&&p&在过去的五年里我一直在使用手机进行拍照,绝大多数是拍照,很少的时候是摄影,这里是有区别的。在我接触对许多手机拍摄感兴趣的人中,当我发布一张照片在社交网络的时候,他们往往会问出两类问题:&/p&&p&问题一:你用的什么APP&/p&&p&问题二:你用的什么手机&/p&&p&这两个问题的疑惑,本质上就和摄影师在朋友圈放一张照片,你在下面回复一句:你用的什么相机,镜头是多少,如出一辙。&/p&&p&在这些疑问中有一个非常重要的前提,那就是几乎所有人,都会本能地认为一张好照片的原因是:你用的app好,你用的手机好。&/p&&p&可有意思的现象是,有的时候还会有人站出来说你拍摄的照片根本不可能是手机拍的,例如下面这张:&/p&&figure&&img data-rawheight=&2252& src=&https://pic4.zhimg.com/v2-77adcf411bfb0d8842df73ffba5dbc32_b.jpg& data-size=&normal& data-rawwidth=&4004& class=&origin_image zh-lightbox-thumb& width=&4004& data-original=&https://pic4.zhimg.com/v2-77adcf411bfb0d8842df73ffba5dbc32_r.jpg&&&figcaption&使用iPhone SE拍摄&/figcaption&&/figure&&p&很多人都会说,你这一看就是骗人的,手机怎么还能拍摄光轨呢?&/p&&p&所以,今天这一篇文章,我就认认真真的回答一下什么手机和什么APP:&/p&&p&手机摄影,只要iPhone 的内置相机,就已经足够强大。重要的是这个iPhone并不要求你是最新的iPhone X。我自己无论是从iPhone 4到今天的iPhone X用过几乎每一代iPhone手机进行拍摄,但照片顶多是画质上的进步和创作的多元。甚至是,有些人今天还会特意找iPhone 4 手机进行黑白摄影,因为那种味道很独特,就像不同的胶卷有不同的味道。 &/p&&p&更需要说明的是,手机摄影有着独特的进化方向,例如在算法的人像模式,影视灯光线等这些弯道超车的手法上有着很好的思路,虽然今天还不够好(但在光线充足下,已经足够使用),但成熟的时候就是新的开始。&/p&&p&除此以外,iPhone 的摄像功能可以说是异常强大。相机拍照素质如果还有手机与之一战,但摄像功能绝对的无出其右。iPhone 8的4k 60P,P慢动作,无论是纸面参数还是实际拍摄效果都是出类拔萃。想要自己拍摄一部小电影?(不是你想的那种小电影)iPhone就可以了。&/p&&p&说到这里,就开始我自己关于iPhone内置相机的分享,文章主要内容结构有:&/p&&figure&&img data-rawheight=&1404& src=&https://pic2.zhimg.com/v2-e73b94f997f063d1e5e6_b.jpg& data-size=&normal& data-rawwidth=&1550& class=&origin_image zh-lightbox-thumb& width=&1550& data-original=&https://pic2.zhimg.com/v2-e73b94f997f063d1e5e6_r.jpg&&&/figure&&p&需要说明的是,本篇文章的iPhone是以IOS 11的iPhone 7为基础。但是几乎适用于所有目前的iPhone,其中iPhone X唯一多了一个前置摄像头的人像模式(当然,并不是说iPhone X比iPhone 7只多这一点,第二颗长焦摄像头带防抖以及光圈升级,都对画质是本质性的进步)&/p&&hr&&p&&b&1.认识你的镜头&/b&&/p&&p&我们先从硬件开始说起,在使用相机拍照的时候,有两个不可分割的部分,这就是机身和镜头。不同镜头往往因为焦距和光圈等带来不同的题材感受。这里贴一张镜头基本知识入门,感兴趣可以自行阅读:&/p&&figure&&img data-rawheight=&715& src=&https://pic1.zhimg.com/v2-557fd4eacaed72f5cea225d60b197902_b.jpg& data-size=&normal& data-rawwidth=&1448& class=&origin_image zh-lightbox-thumb& width=&1448& data-original=&https://pic1.zhimg.com/v2-557fd4eacaed72f5cea225d60b197902_r.jpg&&&/figure&&p&但是,由于手机的高度集成,因此今天绝大多数的手机有着一些天然劣势,这其中最重要的就是光圈固定。另一方面,由于手机内部的空间有限,手机的单颗镜头一般都是一颗不可以光学变焦的定焦镜头。你在上述途中看到,相同的镜头在不同画幅上需要进行换算。iPhone经过换算后,焦距为30mm左右。那么综上,我们可以得出一个结论:&/p&&p&&b&手机是一颗30mm左右的广角定焦镜头,且光圈不可以更改。&/b&&/p&&p&那知道这些,对于我们来说有什么意义呢?&/p&&p&首先,广角镜头最大的特点就是可以拍摄更多的画面内容,其次广角镜头的透视效果决定了边缘的畸变。&/p&&p&先说广角畸变,广角畸变的效果就是越靠近画面边缘就会拉伸,越靠近画面中央就越压缩。换个说法就是,姑娘们的腿放在画面的边缘就可以拥有一双大长腿,放在画面中央那就是柯基小短腿,如下面这张:&/p&&figure&&img data-rawheight=&1400& src=&https://pic2.zhimg.com/v2-75b7cb89cbfe0_b.jpg& data-size=&normal& data-rawwidth=&1050& class=&origin_image zh-lightbox-thumb& width=&1050& data-original=&https://pic2.zhimg.com/v2-75b7cb89cbfe0_r.jpg&&&/figure&&p&让姑娘的腿靠近画面边缘,就会有自然拉伸效果。&/p&&p&所以,敲重点,如何拍摄大长腿,学到了吗?&/p&&p&当然,广角的应用绝不只是大长腿,例如当你想要表现一座建筑的高耸的时候就可以利用边缘拉伸建筑:&/p&&figure&&img data-rawheight=&1618& src=&https://pic3.zhimg.com/v2-e4923406ccddaa533960_b.jpg& data-size=&normal& data-rawwidth=&1080& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic3.zhimg.com/v2-e4923406ccddaa533960_r.jpg&&&/figure&&figure&&img data-rawheight=&517& src=&https://pic3.zhimg.com/v2-c5798eda2bfb9_b.jpg& data-size=&normal& data-rawwidth=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/v2-c5798eda2bfb9_r.jpg&&&figcaption&(在设置-相机-网格打开)&/figcaption&&/figure&&figure&&img data-rawheight=&859& src=&https://pic3.zhimg.com/v2-8b37cf29bb560b89dfa64c35ccb5a0af_b.jpg& data-size=&normal& data-rawwidth=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic3.zhimg.com/v2-8b37cf29bb560b89dfa64c35ccb5a0af_r.jpg&&&/figure&&p&(以上是九宫格和打开方式)&/p&&p&而更多的拍摄内容就需要良好的构图,这个时候iPhone的基本九宫格网格,不仅仅可以用来帮你找到水平线,更重要的是最常用的三分构图法的使用,即我们可以把我们的拍摄焦点放置在网格线上,或者是他们的焦点上。&/p&&p&&br&&/p&&p&目前,双镜头基本上都是主流旗舰机的必备。但是本质上有着不同的方案,主流有:黑白加彩色,以及广角加长焦。而iPhone 就是后者,这也是我认为最好的方式。&/p&&p&上面的表格中说到,不同的焦距有不同的拍摄效果,最直接的就是画面的放大和缩小,也就是拍的远近。那在这里,就需要说明一个概念:&/p&&p&什么是光学变焦,什么又是数码变焦?&/p&&p&最简单的理解就是,光学变焦是从光学结构上改变画面内容,所以并不损失画质。但,数码变焦本质上相当于拍摄一张照片对其进行放大,最多也就是进行优化,本质上并不能改变画质的下降。这个时候,iPhone 的第二颗镜头就非常重要了。第二颗镜头是等效56mm焦距,这个焦距不仅放大画面内容,也减少了畸变。在光线条件好的情况下,直接使用56mm拍摄,不需要人像模式都可以产生一定的虚化(焦距是虚化程度的一个影响因素,焦距越长虚化越好)。更重要的是,长焦可以简化画面内容,极大的丰富了我们的拍摄题材。这里也有个敲黑板知识点,很多男孩子给女孩子拍照不是找到画面中的人?用第二颗长焦,锁定你的美!&/p&&p&需要说明的是,iPhone上的变焦其实是两颗镜头进行切换,所以1倍变焦和两倍变焦是没有进行数码变焦的,画质最好。如下图:&/p&&figure&&img data-rawheight=&552& src=&https://pic2.zhimg.com/v2-f774ea8abcbff2_b.jpg& data-size=&normal& data-rawwidth=&658& class=&origin_image zh-lightbox-thumb& width=&658& data-original=&https://pic2.zhimg.com/v2-f774ea8abcbff2_r.jpg&&&/figure&&p&&br&&/p&&p&1-2之间,2-10之间都是数码的,有损画质尽量不要使用,因为你可以在后期自由裁切,更方面。&/p&&p&&b&2.主动曝光和对焦—手机大片的开始&/b&&/p&&p&其实在使用相机拍摄一张照的时候,所有的摄影师知道我们需要做两件事,一个是曝光一个是对焦。但是目前所有的智能手机都已经把整个拍摄流程简化为“按一个快门”。但这并不意味着,手机拍摄过程不需要对焦和测光。只不过,对焦和测光已经由手机帮你决定了。但可惜的是,今天的手机还没有发达到可以知道你想要拍摄怎样画面的能力,他们仅仅拍摄出一张正确的照片,这种正确都是算法的结果。在开始讲解对焦和测光之前,我们先看几张照片:&/p&&figure&&img data-rawheight=&864& src=&https://pic3.zhimg.com/v2-f61d2a5d0ce8aa865a5323c_b.jpg& data-size=&normal& data-rawwidth=&642& class=&origin_image zh-lightbox-thumb& width=&642& data-original=&https://pic3.zhimg.com/v2-f61d2a5d0ce8aa865a5323c_r.jpg&&&/figure&&figure&&img data-rawheight=&912& src=&https://pic1.zhimg.com/v2-607cbe771a65deb6b5942e_b.jpg& data-size=&normal& data-rawwidth=&1226& class=&origin_image zh-lightbox-thumb& width=&1226& data-original=&https://pic1.zhimg.com/v2-607cbe771a65deb6b5942e_r.jpg&&&/figure&&figure&&img data-rawheight=&932& src=&https://pic1.zhimg.com/v2-8aecf282ebaef4df7a22_b.jpg& data-size=&normal& data-rawwidth=&686& class=&origin_image zh-lightbox-thumb& width=&686& data-original=&https://pic1.zhimg.com/v2-8aecf282ebaef4df7a22_r.jpg&&&/figure&&figure&&img data-rawheight=&4032& src=&https://pic4.zhimg.com/v2-d3ec7ed730_b.jpg& data-size=&normal& data-rawwidth=&3024& class=&origin_image zh-lightbox-thumb& width=&3024& data-original=&https://pic4.zhimg.com/v2-d3ec7ed730_r.jpg&&&/figure&&p&以上几张照片都是iPhone 的官方样张,你一定会奇怪,为什么一样的手机我们拍出的照片完全不一样。总结起来,你会发现iPhone 的很多照片都很耐看,用今天流行的话说绝不“糖水”。这些低调照片,光影层次十分丰富,构图精彩。尤其是夜景的光影关系,尤为突出。可为什么,我们自己拍摄夜景的时候,就模糊和满屏幕的躁点。根本原因,就是我们忽略了对画面曝光的控制。&/p&&p&那么iPhone如何进行曝光调节呢?&/p&&p&主要有两个操作:&/p&&p&&b&(1)点按屏幕,你点触的的地方为曝光基准。&/b&说人话就是,你点暗的的地方就变亮,点亮的地方就变暗。例如,像下面这张照片,拍摄时如果采用点按拍摄,点按的区域大概就是这个位置。&/p&&figure&&img data-rawheight=&4032& src=&https://pic4.zhimg.com/v2-9d1de0ec0a5f_b.jpg& data-size=&normal& data-rawwidth=&3024& class=&origin_image zh-lightbox-thumb& width=&3024& data-original=&https://pic4.zhimg.com/v2-9d1de0ec0a5f_r.jpg&&&/figure&&p&&b&(2)长按锁定曝光,使用点按框滑杆调节。&/b&长按锁定曝光的功能,其实绝大多数人不知道,这个功能其实异常好用,稍后我们也会继续运用。&/p&&p&所以,下面的场景:&/p&&figure&&img data-rawheight=&640& src=&https://pic4.zhimg.com/v2-8b1d849eed9d5d900e83c_b.jpg& data-size=&normal& data-rawwidth=&1136& class=&origin_image zh-lightbox-thumb& width=&1136& data-original=&https://pic4.zhimg.com/v2-8b1d849eed9d5d900e83c_r.jpg&&&/figure&&p&我们先长按任意地方,出现自动曝光锁定,这个时候向下滑动即可变暗。但是你会发现,这个滑杆有限度,这个限度其实是基于你所选的点的。所以,没有达到你想要的效果,可以尝试画面其他地方曝光锁定。&/p&&p&在上述曝光锁定时,在长按画面对焦的时候,还有一个自动对焦锁定。那这是什么呢?AF就是自动对焦的缩写,其实在你选择测光点的时候,你也在选择对焦点。但是,很多人会疑惑?手机对焦?好像我在点按不同的点的时候,并没有发生什么改变?&/p&&p&那么,要理解这一个问题就要知道,对焦的目的是什么。&/p&&p&&b&对焦其实就是景深的控制,关于景深,下面是一段小科普:&/b&&/p&&p&由于照片是二维的,但实际生活是三维的,假设我们的照片是二维坐标的XY,所以当我们看到一张画面中有清晰,有模糊的时候我们会觉得,清晰和模糊是在XY中进行选择。但其实,照片清晰和模糊的范围是在Z轴上进行选择,看图:&/p&&figure&&img data-rawheight=&1536& src=&https://pic1.zhimg.com/v2-0c8b269ec652ceed7ef9bc576f8f089e_b.jpg& data-size=&normal& data-rawwidth=&2048& class=&origin_image zh-lightbox-thumb& width=&2048& data-original=&https://pic1.zhimg.com/v2-0c8b269ec652ceed7ef9bc576f8f089e_r.jpg&&&/figure&&p&通过上图,我们可以看到,景深是一个清晰的范围,这个清晰范围越短,我们就叫浅景深,那么背景的模糊(也就是虚化)越明显。那么这样回答了,为什么大光圈拍人像,会有背景虚化?因为,光圈越大,景深也就越浅,也就是越容易虚化。&/p&&p&那么,影响景深范围(即L的长短)有哪些因素呢?&/p&&p&1.光圈,光圈越大,景深越小;光圈越小,景深越大。&/p&&p&2.焦距,焦距越长,景深越小;焦距越短,景深越大。这也为是为什么85mm,70-200mm等焦距适合人像的原因,因为虚化好。这也是为什么,手机不能虚化的原因,因为手机的等效焦距是20mm以下。(双镜头的虚化是算法,不是光学)&/p&&p&3.对焦距离,在其他条件相同情况下,对焦越近,景深越小。&/p&&p&4.相机画幅,画幅越大,景深越小。这也是为什么,手机不能获得很好的虚化效果的主因。&/p&&p&&br&&/p&&p&那么这个时候,我们回来看,手机由于是广角,传感器面积小等等都是虚化弱的因素,因此你看起来点哪里都是一样的(但实际上还是有差别的)。但,如果你与拍摄物体近一点,如下面两张图,你就会明显的发现,区别非常大,而且背景还会出现虚化效果(是光学的)。&/p&&figure&&img data-rawheight=&2691& src=&https://pic1.zhimg.com/v2-4cde7ef0c350afbbcd2ce12_b.jpg& data-size=&normal& data-rawwidth=&4032& class=&origin_image zh-lightbox-thumb& width=&4032& data-original=&https://pic1.zhimg.com/v2-4cde7ef0c350afbbcd2ce12_r.jpg&&&/figure&&figure&&img data-rawheight=&3024& src=&https://pic4.zhimg.com/v2-45d371ddfab8626dc84cecf01650f96d_b.jpg& data-size=&normal& data-rawwidth=&4032& class=&origin_image zh-lightbox-thumb& width=&4032& data-original=&https://pic4.zhimg.com/v2-45d371ddfab8626dc84cecf01650f96d_r.jpg&&&/figure&&figure&&img data-rawheight=&4032& src=&https://pic4.zhimg.com/v2-c_b.jpg& data-size=&normal& data-rawwidth=&3024& class=&origin_image zh-lightbox-thumb& width=&3024& data-original=&https://pic4.zhimg.com/v2-c_r.jpg&&&/figure&&p&说到具体操作上,iPhone 的对焦方式也很简单,只要你点按画面中的任意你想要拍摄的画面,就可以了。但是,有的时候,你稍微一动就会重新对焦。这个时候,我们依然可以长按画面,锁定对焦。这样焦点不再改变。&/p&&p&这个时候,你一定会问了,长按又锁定对焦又锁定曝光,但是如果我们的对焦和曝光不在一个点上,怎么办?&/p&&p&一般情况下,对焦的优先级高于曝光。也就是说,选择你希望对焦的点,长按锁定对焦和曝光,这个时候,如果曝光不是你想要的,我们可以通过滑杆来调节。如果滑杆调节依然不够,我们可以后期。曝光后期很简单就可以调整,但是对焦就不是了。因此,对焦优先级高于曝光。&/p&&p&要注意的是,很多时候,只有我们有意识的自主进行曝光和对焦,我们才能拍到更好的照片。&/p&&p&在上面说到了,手机的天然劣势导致我们很难获得相机上的虚化效果。但最近两年的双镜头技术,却有了新的虚化方式。&/p&&p&先说一个结论:&/p&&p&目前,iPhone上的人像模式已经到了高度可用的程度,只要方法得当,拍出好的人像佳作不是不可能。&/p&&p&那么,如何更好的使用iPhone 的人像模式呢?&/p&&p&1.保证足够的进光量。这其实也是一切手机摄影画质的根基,手机拍摄想要高画质,光源的充足与否至关重要。所以你会发现,在艳阳高照的晴天拍摄,人像模式特别好。那你说晚上就不能用了吗?也可以,只要有意识的进行光源补充,例如下面的这一张照片。这种补光并不一定需要专业的不光设备,有的时候仅仅是另一部手机的手电筒就可以了。&/p&&figure&&img data-rawheight=&3024& src=&https://pic4.zhimg.com/v2-c2cc0f256c72273cc9ffd_b.jpg& data-size=&normal& data-rawwidth=&3038& class=&origin_image zh-lightbox-thumb& width=&3038& data-original=&https://pic4.zhimg.com/v2-c2cc0f256c72273cc9ffd_r.jpg&&&/figure&&p&2.尽可能的让主体和背景有区分并有一定距离。要注意的是,即使是相机上的正常虚化人物和背景如果距离近,也不会有很好的背景虚化。因此,让姑娘距离背景远一点,虚化效果杠杠的。&/p&&figure&&img data-rawheight=&2378& src=&https://pic1.zhimg.com/v2-642ee8bae85_b.jpg& data-size=&normal& data-rawwidth=&4032& class=&origin_image zh-lightbox-thumb& width=&4032& data-original=&https://pic1.zhimg.com/v2-642ee8bae85_r.jpg&&&/figure&&p&最后,需要说明的是,人像虚化的计算有时候需要时间,你拍出来的照片可能刚看起来比较假,但是过一会也许会变得更好(可能是苹果会对其进行优化)。&/p&&p&除了人像模式的虚化,iPhone在今年更新了影视灯系列,首先对影视灯的每一个模式做一个说明:&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/441408& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic2.zhimg.com/80/v2-54fccc08ae7ea6234fab61_b.jpg& data-lens-id=&441408&&
&img class=&thumbnail& src=&https://pic2.zhimg.com/80/v2-54fccc08ae7ea6234fab61_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/441408&/span&
&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&结果上看,第二种摄影室灯光模式更符合中国人的审美,因为他会在你的脸上补光,让你的面部更加有光泽。轮廓光相信更受欧美人喜欢,轮廓光的意义也在于光影关系的勾勒。而目前,这两种模式的实用性还是很高的。已经到了,可以使用的地步。而后两者……说实话,无论是技术上,还是审美上都比较难接受。但,apple最近官方po出了这样一组图片:&/p&&figure&&img data-rawheight=&1136& src=&https://pic2.zhimg.com/v2-e1ec6bbda7b_b.jpg& data-size=&normal& data-rawwidth=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic2.zhimg.com/v2-e1ec6bbda7b_r.jpg&&&/figure&&figure&&img data-rawheight=&750& src=&https://pic4.zhimg.com/v2-b905efb328dd1c01a561b_b.jpg& data-size=&normal& data-rawwidth=&629& class=&origin_image zh-lightbox-thumb& width=&629& data-original=&https://pic4.zhimg.com/v2-b905efb328dd1c01a561b_r.jpg&&&/figure&&figure&&img data-rawheight=&737& src=&https://pic4.zhimg.com/v2-a5f4e15f38df_b.jpg& data-size=&normal& data-rawwidth=&640& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic4.zhimg.com/v2-a5f4e15f38df_r.jpg&&&/figure&&p&不出意外,应该是这个模式拍摄的,所以,限制我们的真的是我们的想象力。&/p&&p&需要说明的是,即使你拍摄完成,也可以进行调整,更换其他模式。这一点,我一直很喜欢,iPhone的内置调整都有重来的机会。&/p&&p&其实,某种意义上,我觉得这次的人像模式新加入的特性我非常喜欢。也许它现在还不够好,但是等到成熟的那一天,就是人工智能和摄影的结合,目前看这种结合只能在手机上实现,而传统的相机厂商们还在憋他们的画质。至少,iPhone让我们瞥了一眼,人工智能对于未来的摄影可以做什么。&/p&&p&&b&&a href=&https://link.zhihu.com/?target=http%3A//3.live/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&3.live&/a& photo能做的比你想的更多&/b&&/p&&p&说到live photo安卓用户们一定是激动的,因为他们觉得这不就是GIF吗,我们安卓早就有了。但需要说明的是,live photo和GIF完全不是一个概念。因为Live photo是一种拍摄理念,Gif不过是一种文件格式。&/p&&p&我曾经分享到这样一个故事,和逝去的老人拍过一张照片,偶然间发现是一张live photo,发现在拍摄的过程中,本来严肃的老人突然开心的笑了一下。这也是我心里关于科技和人文关怀上佳的案例。不信,你现在可以去找到相册里自己所有的live photo,依次看一下哪些拍照前后的瞬间,一定有很多画面你都会感动。(也可能是爆笑)所以,iPhone Live photo的本质是希望帮我们在拍摄照片的一瞬间,不仅仅能够留住一个瞬间,而是一段记忆。(这也是Apple的魅力所在)&/p&&p&当然也可以是一些有趣的创作,如下面这张:&/p&&p&&br&&/p&&p&&br&&/p&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/883520& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic2.zhimg.com/80/v2-5a83d9adec9_b.jpg& data-lens-id=&883520&&
&img class=&thumbnail& src=&https://pic2.zhimg.com/80/v2-5a83d9adec9_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/883520&/span&
&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&所以,live photo绝不仅仅是一个像GIF的东西。&/p&&p&在ios11里,Apple对live进行了一次重大升级,添加了几项重要功能。主要可以分为两个类别,一个是播放模式的选择:&/p&&p&来回播放和循环播放。我用一个案例展示一下两种模式的不同区别。&/p&&p&&br&&/p&&p&&br&&/p&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/030272& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic3.zhimg.com/80/v2-51c5e1fdfe70a4e454c2_b.jpg& data-lens-id=&030272&&
&img class=&thumbnail& src=&https://pic3.zhimg.com/80/v2-51c5e1fdfe70a4e454c2_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/030272&/span&
&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&这两个模式,可玩性还是很高的,大家可以无限制发挥自己的脑洞创造有意思的画面。&/p&&p&第二个,也是我自己的最喜欢的长曝光模式。&/p&&p&要说明的是,iPhone 的内置长曝光模式来的有点晚,很多安卓主打拍照的手机早就有了这个模式(但其实,iPhone只要下一个软件就够了)。什么是长曝光模式呢?&/p&&p&在相机摄影上,慢门摄影可以带来很多独特的视觉效果,例如下面我拍摄的溪水:&/p&&figure&&img data-rawheight=&2000& src=&https://pic1.zhimg.com/v2-ae3a5ad25c16f5e52f1fa0_b.jpg& data-size=&normal& data-rawwidth=&2000& class=&origin_image zh-lightbox-thumb& width=&2000& data-original=&https://pic1.zhimg.com/v2-ae3a5ad25c16f5e52f1fa0_r.jpg&&&/figure&&p&但是,这需要减光镜。但这种丝绸般的水流效果,也可以通过多张合成的形式。所以,手机也通过这种方式拍出长曝光的丝绸效果。原理不再提,你只要知道,这个模式可以让动态的如水流,云彩等模糊。&/p&&p&&br&&/p&&p&&br&&/p&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/182080& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic4.zhimg.com/80/v2-457ab457fc83_b.jpg& data-lens-id=&182080&&
&img class=&thumbnail& src=&https://pic4.zhimg.com/80/v2-457ab457fc83_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/182080&/span&
&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&但,模糊的也不仅仅只是水流,只要你开脑洞,还有很多玩法,比如转动的雨伞:&/p&&figure&&img data-rawheight=&2682& src=&https://pic3.zhimg.com/v2-c0e3c113b08e1e7382946a_b.jpg& data-size=&normal& data-rawwidth=&2687& class=&origin_image zh-lightbox-thumb& width=&2687& data-original=&https://pic3.zhimg.com/v2-c0e3c113b08e1e7382946a_r.jpg&&&/figure&&p&需要注意的是,尽量保证拍摄的瞬间不要画面抖动,不然合成效果会很差。有一个三脚架,那是最好不过(即使相机拍摄,也需要三脚架)&/p&&p&&b&4.什么又是HDR功能?&/b&&/p&&figure&&img data-rawheight=&636& src=&https://pic3.zhimg.com/v2-e2bec4ea792cab82c4f43bd258d1d49a_b.jpg& data-size=&normal& data-rawwidth=&636& class=&origin_image zh-lightbox-thumb& width=&636& data-original=&https://pic3.zhimg.com/v2-e2bec4ea792cab82c4f43bd258d1d49a_r.jpg&&&/figure&&p&&br&&/p&&p&HDR在过去一段时间里,是摄影的热门词汇了。一些摄影小白,一听HDR就一定会觉得高大上。但实际上,HDR远没有大家想的那么神秘。HDR是高动态范围的缩写,这项技术本质上是解决相机的动态范围的。简单来说,我们在使用相机拍摄的时候,一定会遇到一些大光比场景,最明显的就是你背对着阳光的时候,脸清楚了阳光就过曝了,而阳光准了,脸又是一片黑。这就是因为,相机的宽容度不能够同时记录画面中的最亮和最暗。这个时候,HDR就应运而生了。你不是一张解决不了吗,那我多拍几张,然后只选择正确的部分合成在一起。&/p&&p&iPhone 的内置HDR功能很强大,自动HDR会根据场景情况进行匹配,需要的时候自动开启HDR。如果,没有识别,我们也可以强制打开。&/p&&p&一个小建议是,HDR并不是用了就是好,有的时候拍照不是每一个部分都看得见,好的光影关系更重要。&/p&&p&&b&5.需要驾驭的闪光灯。&/b&&/p&&p&几乎在任何的手机摄影里面,闪光灯似乎并不是经常被提到的一点。这是因为,即使是一些入门的数码相机的机顶闪光灯,在实际使用中也不常用。最直接的原因就是,在取景正前方的直接闪光拍出的一片惨白,实在是不能接受。回到手机这里,更是如此,我相信大家一定宁可忍受没有闪光灯的低画质,也不用闪光灯。&/p&&p&但其实,闪光灯也有很多用处,最直接的就是补光:&/p&&figure&&img data-rawheight=&3024& src=&https://pic1.zhimg.com/v2-85e725abac6eb7c05331b82_b.jpg& data-size=&normal& data-rawwidth=&3024& class=&origin_image zh-lightbox-thumb& width=&3024& data-original=&https://pic1.zhimg.com/v2-85e725abac6eb7c05331b82_r.jpg&&&/figure&&p&上面这张照片,就是通过另一只手机的闪光灯(手电筒功能)补光在人脸在夜间进行的拍摄。&/p&&p&布光图如下:&/p&&figure&&img data-rawheight=&1536& src=&https://pic4.zhimg.com/v2-47be3db1f453dac977110a_b.jpg& data-size=&normal& data-rawwidth=&2048& class=&origin_image zh-lightbox-thumb& width=&2048& data-original=&https://pic4.zhimg.com/v2-47be3db1f453dac977110a_r.jpg&&&/figure&&p&但是在补光过程中要柔和光线。例如,我们可以打开手电筒功能,不要直接照射在被摄物体身上,而是想办法尽可能的反射。比如用一张A4纸放在闪光灯前进行反射,这样光线就会柔和许多。&/p&&p&但是,如果你是iPhone 8和iPhone X,这个问题就会简单很多。因为iPhone的全新闪光灯技术,可以智能的帮你柔滑光线。关于这项技术,官方是这样描述的:&/p&&p&&br&&/p&&figure&&img data-rawheight=&536& src=&https://pic1.zhimg.com/v2-3dd58d610bedb62523a6_b.jpg& data-size=&normal& data-rawwidth=&1080& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&https://pic1.zhimg.com/v2-3dd58d610bedb62523a6_r.jpg&&&/figure&&p&&br&&/p&&p&简单来说,这种技术像极了在专业闪光人像中的“闪烧结合”,这就意味着,闪光灯的使用效率大大提高了,它甚至可以让我们在一些光线环境不好的情况下进行补光,下面两对比图:&/p&&figure&&img data-rawheight=&3024& src=&https://pic1.zhimg.com/v2-b4d664b2e3ae15d7ac8e42d6f27408b5_b.jpg& data-size=&normal& data-rawwidth=&4032& class=&origin_image zh-lightbox-thumb& width=&4032& data-original=&https://pic1.zhimg.com/v2-b4d664b2e3ae15d7ac8e42d6f27408b5_r.jpg&&&/figure&&figure&&img data-rawheight=&3024& src=&https://pic1.zhimg.com/v2-d58c55c36fb05a12d6ab1aa9e6448fd2_b.jpg& data-size=&normal& data-rawwidth=&4032& class=&origin_image zh-lightbox-thumb& width=&4032& data-original=&https://pic1.zhimg.com/v2-d58c55c36fb05a12d6ab1aa9e6448fd2_r.jpg&&&/figure&&p&以上两张照片,是我分别使用打开闪光灯和关闭闪光灯的情况下拍摄的照片。可以看到,打开闪光灯的照片画面质量,尤其是姑娘的肤质有着非常好的提高。也正是

我要回帖

更多关于 公众号登入 的文章

 

随机推荐