什么是幂等?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 3170 次浏览 • 2017-05-02 16:09 • 来自相关话题

什么是 AMQP协议?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2415 次浏览 • 2017-04-24 11:20 • 来自相关话题

HTTP header 响应头详解

zkbhj 发表了文章 • 0 个评论 • 1264 次浏览 • 2017-04-14 17:24 • 来自相关话题

有四种头标:

1.通用头标    既可用于请求有可用于响应,并且是作为一个整体而不是特定资源与事务相关联。
2.请求头标    允许客户端传递关于自身信息和希望的响应形式。
3.响应头标    服务器用于传递自身信息和响应。
4.实体头标    定义被传送资源的信息。既可用于请求,也可用于响应


头标以如下的单行形式发送。
<name>:<value><crlf>
其中
name是头标名,大小写敏感
value是头标值;
crlf是回车换行符

以下是HTTP/1.1中用到的头标:





  查看全部
有四种头标:


1.通用头标    既可用于请求有可用于响应,并且是作为一个整体而不是特定资源与事务相关联。
2.请求头标    允许客户端传递关于自身信息和希望的响应形式。
3.响应头标    服务器用于传递自身信息和响应。
4.实体头标    定义被传送资源的信息。既可用于请求,也可用于响应



头标以如下的单行形式发送。
<name>:<value><crlf>
其中
name是头标名,大小写敏感
value是头标值;
crlf是回车换行符

以下是HTTP/1.1中用到的头标:

HTTP_header_响应头详解_-_leokelly001的专栏_-_博客频道_-_CSDN.N_.png

 

HTTP 长连接和短连接

zkbhj 发表了文章 • 0 个评论 • 1105 次浏览 • 2017-03-13 16:40 • 来自相关话题

1. HTTP协议与TCP/IP协议的关系

HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。

 
2. 如何理解HTTP协议是无状态的

HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

 
3. 什么是长连接、短连接?

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

3.1 TCP连接

当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需要4次握手,所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图:





 
经典的四次握手关闭图:





 
3.2 TCP短连接

我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server 发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在 client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段

3.3 TCP长连接

接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务 器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一: 
客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。


3.4 长连接短连接操作过程

短连接的操作步骤是:

建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接

长连接的操作步骤是:

建立连接——数据传输…(保持连接)…数据传输——关闭连接

 
4. 长连接和短连接的优点和缺点

由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。


5. 什么时候用长连接,短连接?

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
  查看全部
1. HTTP协议与TCP/IP协议的关系

HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。

 
2. 如何理解HTTP协议是无状态的


HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

 
3. 什么是长连接、短连接?

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。

但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:
Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

3.1 TCP连接

当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需要4次握手,所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图:

0064cTs2jw1exnxmvpy6ij30ld0cutbv.jpg

 
经典的四次握手关闭图:

0064cTs2jw1exnxmw4ffij30os0ffwtl22.jpg

 
3.2 TCP短连接

我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server 发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在 client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段

3.3 TCP长连接

接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务 器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一: 
  • 客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
  • 客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
  • 客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
  • 客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。



3.4 长连接短连接操作过程

短连接的操作步骤是:


建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接


长连接的操作步骤是:


建立连接——数据传输…(保持连接)…数据传输——关闭连接


 
4. 长连接和短连接的优点和缺点

由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。


5. 什么时候用长连接,短连接?

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
 

墨菲定律

zkbhj 发表了文章 • 0 个评论 • 1881 次浏览 • 2017-03-13 14:52 • 来自相关话题

“墨菲定律”(Murphy's Law)亦稱莫非定律、莫非定理、或摩菲定理,是西方世界常用的俚語。

“墨菲定律”:事情往往會向你所想到的不好的方向發展,只要有這個可能性。比如你衣袋裡有兩把鑰匙,一把是你房間的,一把是汽車的;如果你現在想拿出車鑰匙,會發生什麼?是的,你往往是拿錯了房間鑰匙。

這就是著名的“墨菲定律”。 查看全部
“墨菲定律”(Murphy's Law)亦稱莫非定律、莫非定理、或摩菲定理,是西方世界常用的俚語。

“墨菲定律”:事情往往會向你所想到的不好的方向發展,只要有這個可能性。比如你衣袋裡有兩把鑰匙,一把是你房間的,一把是汽車的;如果你現在想拿出車鑰匙,會發生什麼?是的,你往往是拿錯了房間鑰匙。

這就是著名的“墨菲定律”。

什么是快速排序?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2738 次浏览 • 2017-03-01 14:15 • 来自相关话题

什么是冒泡排序?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2481 次浏览 • 2017-03-01 11:51 • 来自相关话题

什么是单例模式?

回复

zkbhj 回复了问题 • 1 人关注 • 1 个回复 • 2351 次浏览 • 2017-02-23 17:38 • 来自相关话题

消息通信机制:同步和异步

zkbhj 发表了文章 • 0 个评论 • 1280 次浏览 • 2017-01-03 16:24 • 来自相关话题

消息通信的基本方式有两种:

1、同步方式

两个通信应用服务之间必须要进行同步,两个服务之间必须都是正常运行的。发送程序和接收程序都必须一直处于运行状态,并且随时做好相互通信的准备。

发送程序首先向接收程序发起一个请求,称之为发送消息,发送程序紧接着就会堵塞当前自身的进程,不与其他应用进行任何的通信以及交互,等待接收程序的响应,待发送消息得到接收程序的返回消息之后会继续向下运行,进行下一步的业务处理。

2、异步方式

两个通信应用之间可以不用同时在线等待,任何一方只需各自处理自己的业务,比如发送方发送消息以后不用登录接收方的响应,可以接着处理其他的任务。也就是说发送方和接收方都是相互独立存在的,发送方只管发送,接收方只能接收,无须去等待对方的响应。

Java中JMS就是典型的异步消息处理机制,JMS消息有两种类型:点对点、发布/订阅。
 
参考文章:http://www.cnblogs.com/candle806/archive/2013/02/19/2917155.html
  查看全部
消息通信的基本方式有两种:

1、同步方式

两个通信应用服务之间必须要进行同步,两个服务之间必须都是正常运行的。发送程序和接收程序都必须一直处于运行状态,并且随时做好相互通信的准备。

发送程序首先向接收程序发起一个请求,称之为发送消息,发送程序紧接着就会堵塞当前自身的进程,不与其他应用进行任何的通信以及交互,等待接收程序的响应,待发送消息得到接收程序的返回消息之后会继续向下运行,进行下一步的业务处理。

2、异步方式

两个通信应用之间可以不用同时在线等待,任何一方只需各自处理自己的业务,比如发送方发送消息以后不用登录接收方的响应,可以接着处理其他的任务。也就是说发送方和接收方都是相互独立存在的,发送方只管发送,接收方只能接收,无须去等待对方的响应。

Java中JMS就是典型的异步消息处理机制,JMS消息有两种类型:点对点、发布/订阅。
 
参考文章:http://www.cnblogs.com/candle806/archive/2013/02/19/2917155.html
 

CAP原则学习笔记

zkbhj 发表了文章 • 0 个评论 • 1938 次浏览 • 2017-01-03 12:26 • 来自相关话题

最近在学习消息中间件的时候,接触到了分布式系统,进而接触到CAP理论,上一次接触还是在年初的时候公司的技术分享会上,有人在介绍项目的时候简单介绍了这个CAP理论,但并没有深入研究。这次,该是时候研究一下这个CAP原则到底是个啥了。
其实,CAP理论在大部分的开发者心里都有一定的位置,在互联网界也有广泛的知名度,稍微经验丰富或者知识广泛的程序员都会把它作为衡量一个系统,尤其是分布式系统的设计准则,也就是我们说的CAP原则。大家都非常清晰的知道:任何的分布式系统,在可用性、一致性和分区容错性方面,是不可兼得的,就像是我们常说的“鱼和熊掌不可兼得”一样,最多值能得其二。所以说,任何一个分布式系统的设计,都是根据各自的实际应用场景和需求,对这三个维度的的不同取舍而已。
 
说了这么多,大家可能还是比较懵逼。到底什么是CAP原则?下面先知道下它的定义:

CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。换句话说,就是说在一个系统中对某个数据不存在一个算法同时满足 Consistency, Availability, Partition-tolerance。

 
定义就是定义,一句话,就把上面的一大段废话说的清晰明了!那可能接下来,又来了个“三脸懵逼”,到底啥是一致性、可用性和分区容错性?同样的,上定义:

● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。(等同于所有节点访问同一份最新的数据副本)
● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

 
现在大家应该对这些基本概念有了一个比较清晰的认识。那我们在深入理解CAP原则之前,先了解下CAP原则的前世今生。
 
为什么会产生这个CAP理论?
 
1985年Lynch证明了异步通信中不存在任何一致性的分布式算法(FLP Impossibility)的同时,人们就开始寻找分布式系统设计的各种因素。一致性算法既然不存在,但若能找到一些设计因素,并进行适当的取舍以最大限度满足实现系统需求成为当时的重要议题。比如,在CAP之前研究者就已经发现低延迟和顺序一致性不可能同时被满足。
2000年,Eric Brewer教授在PODC的研讨会上提出了一个猜想:一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个!这个猜想首次把一致性、可用性和分区容错三个因素提炼出来作为系统设计的重要特征,断言用此三者可以划分所有的分布式系统,并指明这三个特征之间的不可能性关系。Brewer猜想比单纯的“低延迟和顺序一致性不能被同时满足”的结论更具体,对实际系统的构建也更具有可操作性!Brewer教授当时想象的分布式场景是webservice,一组websevrice后台运行着众多的server,对service的读写会反应到后台的server集群,并对CAP进行了定义,就是上面列出的定义。高可用、数据一致是很多系统设计的目标,但是分区又是不可避免的事情,CAP的出现仿佛是一盏明灯,它揭露了分布式系统的本质,并给出了设计的准则,而这正是1985年以来人们正在寻找的东西!所以CAP在当时的影响力是非常大的!
2002年,Lynch与其他人证明了Brewer猜想,从而把CAP上升为一个定理。
 
这么一帆风顺吗?直至今日,对CAP理论的质疑声不断
 
就在这些理论被踢出来,大家觉得终于对分布式系统设计有了指导原则的时候,有些工程师和研究者就对CAP提出了各种质疑,纷纷有用反例证明着CAP在各种场合不适用性,同时挑战着Lynch的证明结果!你是否看了CAP的概念定义后还是感觉很模糊?如果是,你并不孤独,有很多人都是如此!CAP没有考虑不同的基础架构、不同的应用场景、不同的网络基础和用户需求,而C、A、P在这些不同场景中的含义可能完全不同,这种无视差异化的定义导致了非常大的概念模糊,同时也变成CAP被质疑的源头!其中,这些质疑主要集中在以下几个方面:
概念模糊混乱,废话一堆,不能作为定理不适用于数据库事务架构应该构建不可变模型避免CAP的复杂性分区容错概念有误导
 
其实,搞了半天,我也不是很清晰这些高大上的推论和证明,也不是我们该操心的,因为CAP理论的提出者和证明者也在后续对这些质疑进行了相应的“回击”!
 
回击和解释
 
面对大量的质疑,Brewer和Lynch终于坐不住了,因此两人纷纷出来澄清。Brewer于2012年重申”3个中的2个“这个表述是不准确的,在某些分区极少发生的情况下,三者能顺畅地在一起配合,而且CAP不仅仅是发生在整个系统中,可能是发生在某个子系统或系统的某个阶段。
Lynch也在10年后的2012年重写了论文,缩小CAP适用的定义,消除质疑的场景,展示了CAP在非单一一致性结果下的广阔的研究结果!并顺便暗示CAP定理依旧正确!
 
多么精彩的“撕逼”过程!但是对我们来说,真正有意义的还是CAP理论本身。
 
我们该如何看待CAP理论本身?
 
首先肯定的是,CAP并不适合再作为一个适应任何场景的定理,它的正确性更加适合基于原子读写的NoSQL场景。质疑虽然很多,但很多质疑者只是偷欢概念,并没有解决各个因素之间的取舍问题。而无论如何C、A、P这个三个概念始终存在任何分布式系统,只是不同的模型会对其有不同的呈现,可能某些场景对三者之间的关系敏感,而另一些不敏感。就像Lynch所说,现在分布式系统有很多特性,比如扩展性、优雅降级等,随着时间的发展,或许这些也会被纳入研究范畴,而作为开发者,这都是我们需要考虑的问题,而不仅是CAP三者!
 
对CAP三者的选择
 
当处理CAP的问题时,你会有几个选择。最明显的是:

 
1.(CA)放弃Partition Tolerance:
如果你想避免partition问题发生,你就必须要阻止其发生。一种做法是将所有的东西(与事务相关的)都放到一台机器上。或者放在像rack这类的atomically-failling单元上。无法100%地保证,因为还是有可能部分失败,但你不太可能碰到由partition问题带来的负面效果。当然,这个选择会严重影响scale限制。

2.(CP)放弃Availability:
相对于放弃partition tolerance来说,其反面就是放弃availability。一旦遇到partition 事件,受影响的服务需要等待数据一致,因此在等待期间就无法对外提供服务。在多个节点上控制这一点会相当复杂,而且恢复的节点需要处理逻辑,以便平滑地返回服务状态。

3.(AP)放弃Consistency:
或者如同Werner Vogels所提倡的,接受事情会变得“最终一致(Eventually Consistent)”(2008年12月更新)。Vogels的文章值得一读。他比我在这里讨论了更多的操作方面的细节。许多的不一致性并不比你想的需要更多的工作(意味着持续的consistency或许并不是我们所需要的)。在购书的例子中,如果一本库存的书,接到了2个订单,第二个就会成为备份订单。只要告知客户这种情况(请记住这是一种罕见的情况),也许每个人都会高兴的。
 

 
总结
 
在Consistency, Availability和Partition-tolerance中,你只能保证2点,这是确实的,并且已经被这个星球上最成功的网站证实了。如果对网站是有效的,我看不出在企业环境中,在日常的工作中,不考虑同样的折衷设计的理由。当然,CAP理论也只是对我们的分布式系统设计起到一个指导性的作用,我们在设计系统时,要考虑的方面也绝非只有这三个方面,正如上文所提到的,扩展性、降级等也是我们需要考虑的内容,所有,只有结合实际的业务需求和使用场景,才能设计出更加合适的系统。
 
参考资料:
1、http://blog.csdn.net/chen77716/article/details/30635543
2、http://blog.sina.com.cn/s/blog_493a8455010161hi.html
  查看全部
最近在学习消息中间件的时候,接触到了分布式系统,进而接触到CAP理论,上一次接触还是在年初的时候公司的技术分享会上,有人在介绍项目的时候简单介绍了这个CAP理论,但并没有深入研究。这次,该是时候研究一下这个CAP原则到底是个啥了。
其实,CAP理论在大部分的开发者心里都有一定的位置,在互联网界也有广泛的知名度,稍微经验丰富或者知识广泛的程序员都会把它作为衡量一个系统,尤其是分布式系统的设计准则,也就是我们说的CAP原则。大家都非常清晰的知道:任何的分布式系统,在可用性、一致性和分区容错性方面,是不可兼得的,就像是我们常说的“鱼和熊掌不可兼得”一样,最多值能得其二。所以说,任何一个分布式系统的设计,都是根据各自的实际应用场景和需求,对这三个维度的的不同取舍而已。
 
说了这么多,大家可能还是比较懵逼。到底什么是CAP原则?下面先知道下它的定义:


CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。换句话说,就是说在一个系统中对某个数据不存在一个算法同时满足 Consistency, Availability, Partition-tolerance。


 
定义就是定义,一句话,就把上面的一大段废话说的清晰明了!那可能接下来,又来了个“三脸懵逼”,到底啥是一致性、可用性和分区容错性?同样的,上定义:


● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。(等同于所有节点访问同一份最新的数据副本)
● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。


 
现在大家应该对这些基本概念有了一个比较清晰的认识。那我们在深入理解CAP原则之前,先了解下CAP原则的前世今生。
 
为什么会产生这个CAP理论?
 
1985年Lynch证明了异步通信中不存在任何一致性的分布式算法(FLP Impossibility)的同时,人们就开始寻找分布式系统设计的各种因素。一致性算法既然不存在,但若能找到一些设计因素,并进行适当的取舍以最大限度满足实现系统需求成为当时的重要议题。比如,在CAP之前研究者就已经发现低延迟和顺序一致性不可能同时被满足。
2000年,Eric Brewer教授在PODC的研讨会上提出了一个猜想:一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个!这个猜想首次把一致性、可用性和分区容错三个因素提炼出来作为系统设计的重要特征,断言用此三者可以划分所有的分布式系统,并指明这三个特征之间的不可能性关系。Brewer猜想比单纯的“低延迟和顺序一致性不能被同时满足”的结论更具体,对实际系统的构建也更具有可操作性!Brewer教授当时想象的分布式场景是webservice,一组websevrice后台运行着众多的server,对service的读写会反应到后台的server集群,并对CAP进行了定义,就是上面列出的定义。高可用、数据一致是很多系统设计的目标,但是分区又是不可避免的事情,CAP的出现仿佛是一盏明灯,它揭露了分布式系统的本质,并给出了设计的准则,而这正是1985年以来人们正在寻找的东西!所以CAP在当时的影响力是非常大的!
2002年,Lynch与其他人证明了Brewer猜想,从而把CAP上升为一个定理。
 
这么一帆风顺吗?直至今日,对CAP理论的质疑声不断
 
就在这些理论被踢出来,大家觉得终于对分布式系统设计有了指导原则的时候,有些工程师和研究者就对CAP提出了各种质疑,纷纷有用反例证明着CAP在各种场合不适用性,同时挑战着Lynch的证明结果!你是否看了CAP的概念定义后还是感觉很模糊?如果是,你并不孤独,有很多人都是如此!CAP没有考虑不同的基础架构、不同的应用场景、不同的网络基础和用户需求,而C、A、P在这些不同场景中的含义可能完全不同,这种无视差异化的定义导致了非常大的概念模糊,同时也变成CAP被质疑的源头!其中,这些质疑主要集中在以下几个方面:
  • 概念模糊混乱,废话一堆,不能作为定理
  • 不适用于数据库事务架构
  • 应该构建不可变模型避免CAP的复杂性
  • 分区容错概念有误导

 
其实,搞了半天,我也不是很清晰这些高大上的推论和证明,也不是我们该操心的,因为CAP理论的提出者和证明者也在后续对这些质疑进行了相应的“回击”!
 
回击和解释
 
面对大量的质疑,Brewer和Lynch终于坐不住了,因此两人纷纷出来澄清。Brewer于2012年重申”3个中的2个“这个表述是不准确的,在某些分区极少发生的情况下,三者能顺畅地在一起配合,而且CAP不仅仅是发生在整个系统中,可能是发生在某个子系统或系统的某个阶段。
Lynch也在10年后的2012年重写了论文,缩小CAP适用的定义,消除质疑的场景,展示了CAP在非单一一致性结果下的广阔的研究结果!并顺便暗示CAP定理依旧正确!
 
多么精彩的“撕逼”过程!但是对我们来说,真正有意义的还是CAP理论本身。
 
我们该如何看待CAP理论本身?
 
首先肯定的是,CAP并不适合作为一个适应任何场景的定理,它的正确性更加适合基于原子读写的NoSQL场景。质疑虽然很多,但很多质疑者只是偷欢概念,并没有解决各个因素之间的取舍问题。而无论如何C、A、P这个三个概念始终存在任何分布式系统,只是不同的模型会对其有不同的呈现,可能某些场景对三者之间的关系敏感,而另一些不敏感。就像Lynch所说,现在分布式系统有很多特性,比如扩展性、优雅降级等,随着时间的发展,或许这些也会被纳入研究范畴,而作为开发者,这都是我们需要考虑的问题,而不仅是CAP三者!
 
对CAP三者的选择
 
当处理CAP的问题时,你会有几个选择。最明显的是:


 
1.(CA)放弃Partition Tolerance:
如果你想避免partition问题发生,你就必须要阻止其发生。一种做法是将所有的东西(与事务相关的)都放到一台机器上。或者放在像rack这类的atomically-failling单元上。无法100%地保证,因为还是有可能部分失败,但你不太可能碰到由partition问题带来的负面效果。当然,这个选择会严重影响scale限制。

2.(CP)放弃Availability:
相对于放弃partition tolerance来说,其反面就是放弃availability。一旦遇到partition 事件,受影响的服务需要等待数据一致,因此在等待期间就无法对外提供服务。在多个节点上控制这一点会相当复杂,而且恢复的节点需要处理逻辑,以便平滑地返回服务状态。

3.(AP)放弃Consistency:
或者如同Werner Vogels所提倡的,接受事情会变得“最终一致(Eventually Consistent)”(2008年12月更新)。Vogels的文章值得一读。他比我在这里讨论了更多的操作方面的细节。许多的不一致性并不比你想的需要更多的工作(意味着持续的consistency或许并不是我们所需要的)。在购书的例子中,如果一本库存的书,接到了2个订单,第二个就会成为备份订单。只要告知客户这种情况(请记住这是一种罕见的情况),也许每个人都会高兴的。
 


 
总结
 
在Consistency, Availability和Partition-tolerance中,你只能保证2点,这是确实的,并且已经被这个星球上最成功的网站证实了。如果对网站是有效的,我看不出在企业环境中,在日常的工作中,不考虑同样的折衷设计的理由。当然,CAP理论也只是对我们的分布式系统设计起到一个指导性的作用,我们在设计系统时,要考虑的方面也绝非只有这三个方面,正如上文所提到的,扩展性、降级等也是我们需要考虑的内容,所有,只有结合实际的业务需求和使用场景,才能设计出更加合适的系统。
 
参考资料:
1、http://blog.csdn.net/chen77716/article/details/30635543
2、http://blog.sina.com.cn/s/blog_493a8455010161hi.html