发布于 2015-12-05 10:57:32 | 835 次阅读 | 评论: 0 | 来源: 网络整理
译者注:Content-Type不翻译,直接关联到HTTP的使用
在Mesos 0.24.0版本添加了v1 Scheduler HTTP API的实验性支持。
调度器通过“/api/v1/scheduler”主机地址经过Mesos管理器与Mesos进行通信。描述完整的唯一地址URL看起来像如下形式:
http://masterhost:5050/api/v1/scheduler
注意:将会在这篇文档的剩余部分在唯一地址提供“/scheduler”的后缀。这个地址接收以HTTP POST请求的JSON格式编码数据(Content-Type: application/json)或者二进制协议缓冲(Content-Type: application/x-protobuf)。第一次请求时,调度器给地址“/scheduler”发送订阅,返回应答流的结果(“200 OK” 状态码的传输编码方式:分块传输)。调度器会尽可能的保持订阅连接(除了网络、软件、硬件等错误。)并且增量处理响应 (注意: HTTP客户端的开发库只能对连接后的响应发生连接不可用的情况进行分析)。关于编码的使用,请参考下面的事件部分。
所有向“/scheduler”地址订阅之后的(非订阅)请求(详细见下面的调用段落)必须使用不同的连接方式发送给订阅的一个不同的连接 必须以使用订阅的不同连接方式进行发送。Mesos会对这些HTTP POST请求进行响应,“202 Accepted”状态码(或者,如果请求不成功,返回4xx或者5xx的状态码;在后面的章节中介绍)。“202 Accepted”的响应意味着接受处理请求,而不是请求已经被处理完成。这些请求不能确定经Mesos执行。(举例来说,管理器在处理请求时失败)。从这些请求派生的任何异步的响应,响应被传输到长生命周期的订阅连接。
调用之后的属于正常请求。信息的标准来源是scheduler.proto(注意:在beta API完成后协议缓冲定义会经受改变)。注意,当发送以JSON编码的调用时,调度器应当按照把UTF-8字符串按照Base64原始比特进行编码。
这是调度器和管理器通信过程的第一步。我们考虑后把订阅划分到“/scheduler”事件流。
向管理器进行订阅时,调度器发送以FrameworkInfo请求的编码SUBSCRIBE
信息的HTTP POST请求。注意:没有设置“subscribe.framework_info.id”,管理器认为是一个新的调度器,给他分配FrameworkID进行订阅。在第一个SUBSCRIBE
事件,HTTP响应是一个RecordIO编码的流。(请看下面事件章节)。
订阅请求 (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
Accept: application/json
Connection: close
{
"type": "SUBSCRIBE",
"subscribe": {
"framework_info": {
"user": "foo",
"name": "Example HTTP Framework"
},
"force": true
}
}
订阅响应事件 (JSON):
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
<event length>
{
“type” : “SUBSCRIBED”,
“subscribed” : {
“framework_id” : {“value”:“12220-3440-12532-2345”},
"heartbeat_interval_seconds" : 15
}
}
<more events>
另外,如果设置“subscribe.framework_info.id”, 管理器认为这是一个从已经订阅过的调度器断开,再次连接的请求(举例来说, 由于故障或者网络断开)并且SUBSCRIBED事件的应答包含同一FrameworkID。“subscribe.force”字段描述如下,当分布的调度器实例(具有相同framework id)如何试图在同一时间对管理器发出订阅,管理器如何执行(举例来说,由于分区网络)。请看下面的断开章节的定义部分。
注意:旧版本的API,(重新)注册回调函数同样也包换MasterInfo,关于管理器驱动所包含现有连接的信息。新的API,自从调度器明确订阅领导管理器(请看下面的章节,在管理器检测部分)今后不在相关。
无论什么原因发生订阅失败(例如,无效的请求),作为信息关闭主体的一部分返回一个的HTTP 4xx响应的错误信息。
仅仅在调度器开启持久链接通过发送SUBSCRIBE请求和接收SUBSCRIBED响应之后,调度器必须向“/scheduler”地址执行额外的HTTP请求。调用在没有订阅的情况下将会导致以“403 Forbidden“应答代替“202 Accepted“应答的结果。如果HTTP请求错误(例如,扭曲了HTTP报文头),调度器还可能接收“400 Bad Request”应答。
当调度器希望把自己终结时,由调度器发送卸载调用。当Mesos接收这一请求,将会关闭所有执行器(并且因此杀死任务)并且移除持久的卷(如果请求过)。之后删除计算框架并关闭所有调度器向管理器开启的连接。
TEARDOWN Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “TEARDOWN”,
}
TEARDOWN Response:
HTTP/1.1 202 Accepted
当调度器接受管理器发送的票据时,由调度器发送接受调用。ACCEPT请求包含几种操作(例如,启动任务,后备资源,创建卷)这几种操作调度器希望在票据上执行。注意:直到调度器给票据回复(接受或者拒绝),那些资源给计算框架深思熟虑的分配号。同样的,在ACCEPT调用的票据的资源(例如,任务启动)不能使用,那些经过考虑拒绝的可能被重新定给其他计算框架。换句话说,具有相同的OfferID不能用于多于一个ACCEPT调用。当我们给Mesos添加新的特征,这些定义可能会发生变化(例如,持久化,可保留的,乐观的票据,调整任务,等等)。
ACCEPT Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “ACCEPT”,
“accept” : {
“offer_ids” : [
{“value” : “12220-3440-12532-O12”},
{“value” : “12220-3440-12532-O12”}
],
“operations” : [ {“type” : “LAUNCH”, “launch” : {...}} ],
“filters” : {...}
}
}
ACCEPT Response:
HTTP/1.1 202 Accepted
为了明确拒绝接收票据,由调度器发送拒绝调用。注意:拒绝调用同样会发送没有操作的ACCEPT调用。
DECLINE Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “DECLINE”,
“decline” : {
“offer_ids” : [
{“value” : “12220-3440-12532-O12”},
{“value” : “12220-3440-12532-O13”}
],
“filters” : {...}
}
}
DECLINE Response:
HTTP/1.1 202 Accepted
为了删除任何/所有的事先通过设定ACCEPT或者DECLINE调用的过滤器,通过调度器发送恢复调用。
REVIVE Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “REVIVE”,
}
REVIVE Response:
HTTP/1.1 202 Accepted
为了杀死特定的任务,由调度器发送调用。如果调度器有一个特定的执行器,杀死调用发送给执行器并且直到执行器来杀死任务后,发送TASK_KILLED (或者TASK_FAILED)更新。Mesos一旦接收任务的终止状态更新,释放任务资源。如果是对于管理器不知道任务状态,将会产生TASK_LOST。
KILL Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “KILL”,
“kill” : {
“task_id” : {“value” : “12220-3440-12532-my-task”},
“agent_id” : {“value” : “12220-3440-12532-S1233”}
}
}
KILL Response:
HTTP/1.1 202 Accepted
为了关闭特定的定制的执行器,由调度器发送关闭调用(注意:这个是新调用,在旧API中不会出现)。当执行器获取关闭事件,将会杀死它名下所有的任务(并且发送TASK_KILLED更新)并且终止。如果执行器在一定时间内(通过“–executor_shutdown_grace_period”代理标志配置)没有终止,代理会强行销毁容器(执行器和相关任务)并且把对应的运行状态的任务转换为TASK_LOST。
SHUTDOWN Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “SHUTDOWN”,
“shutdown” : {
“executor_id” : {“value” : “123450-2340-1232-my-executor”},
“agent_id” : {“value” : “12220-3440-12532-S1233”}
}
}
SHUTDOWN Response:
HTTP/1.1 202 Accepted
由调度器发送确认状态更新。注意:随着新的API,调度器负责通过“status.uuid()”设置明确地确认状态更新收到。这些更新状态会确实地重试,知道他们通过调度器确认。当“status.uuid()”设置为不能重试时,调度器必须不能够对状态更新进行确认。“uuid”是用Base64原始二进制编码。
ACKNOWLEDGE Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “ACKNOWLEDGE”,
“acknowledge” : {
“agent_id” : {“value” : “12220-3440-12532-S1233”},
“task_id” : {“value” : “12220-3440-12532-my-task”},
“uuid” : “jhadf73jhakdlfha723adf”
}
}
ACKNOWLEDGE Response:
HTTP/1.1 202 Accepted
由调度器发送调解,为了查询未终结的任务状态。导致管理器返回所有任务列表的UPDATE事件。那些不在被Mesos了解状态的任务导致TASK_LOST更新。如果任务列表为空,管理器为了所有当前已知任务将给计算框架发送UPDATE事件。
RECONCILE Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “RECONCILE”,
“reconcile” : {
“tasks” : [
{ “task_id” : { “value” : “312325” },
“agent_id” : { “value” : “123535” }
}
]
}
}
RECONCILE Response:
HTTP/1.1 202 Accepted
调度给执行器发送指挥二进制数据。注意:对于传递给执行器的这些信息,Mesos既不会解析这些数据也不会对这些数据做出任何保证。“data”是以Base64的原始二进制编码。
MESSAGE Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “MESSAGE”,
“message” : {
“agent_id” : {“value” : “12220-3440-12532-S1233”},
“executor_id” : {“value” : “my-framework-executor”},
“data” : “adaf838jahd748jnaldf”
}
}
MESSAGE Response:
HTTP/1.1 202 Accepted
从master/allocator由调度器发送资源请求。内嵌分层分配器简单的忽略掉这些请求,但是其他的分配器(模块)可以以定制的方式去解释请求。
Request (JSON):
POST /api/v1/scheduler HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
{
“framework_id” : {“value” : “12220-3440-12532-2345”},
“type” : “REQUEST”,
“requests” : [
{
“agent_id” : {“value” : “12220-3440-12532-S1233”},
“resources” : {}
},
]
}
REQUEST Response:
HTTP/1.1 202 Accepted
调度器希望对“/scheduler”地址保持持久连接的开启状态,甚至在获取SUBSCRIBED HTTP应答事件之后。通过没有设置“Content-Length”的“Connection: keep-alive”和“Transfer-Encoding: chunked”头来表明。在链接上,所有后续事件实质是计算框架通过Mesos产生的数据流。管理器在RecordIO格式下编码所有事件,举例来说,用字符串长度表现事件,以字节为单位通过JSON或者二进制Protobuf(可能有压缩)编码事件。注意:长度值永远不会是‘0’并且长度的大小将是无符号整形(64位)。同时,注意:RecordIO编码应当通过调度器解码,然而底层HTTP块的编码通常在应用(调度器)层是看不到的。 用于事件的内容类型的编码由POST请求(例如,Accept: application/json)的报文头确定。
以下事件通常由管理器发送。标准资料来源在scheduler.proto。注意:当发送JSON编码的事件,管理器以UTF-8用字符串和Base64的形式编码原始字节。
管理器发送的第一个事件是订阅事件,当调度器在持久连接中发送SUBSCRIBE请求。请看当前版面SUBSCRIBE的调用部分。
无论何时有新资源可以提供给计算框架时由管理器发送票据事件。在代理上所有票据对应一组资源。除非发生取消票据,例如因为丢失代理或者票据超时(--offer_timeout),否则直到调度器‘接受’或者'拒绝’,这些资源会经过仔细考虑后分配给调度器。
OFFERS Event (JSON)
<event-length>
{
“type” : “OFFERS”,
“offers” : [
{
“offer_id”:{“value”: “12214-23523-O235235”},
“framework_id”:{“value”: “12124-235325-32425”},
“agent_id”:{“value”: “12325-23523-S23523”},
“hostname”:“agent.host”,
“resources”:[...],
“attributes”:[...],
“executor_ids”:[]
}
]
}
由管理器发送解除事件,当不在有效的特定票据(举例,应当由代理保持一致的票据,被删除后)时因此需要解除。在未来的调用(ACCEPT / DECLINE)通过调度器关联的票据是无效的。
RESCIND Event (JSON)
<event-length>
{
“type” : “RESCIND”,
“rescind” : {
“offer_id” : { “value” : “12214-23523-O235235”}
}
}
无论何时由执行器、代理或者管理器产生状态更新通过管理器发送。状态更新应为了管理这些任务当通过执行器用于可靠传输状态。至关重要的是,一旦任务终止由执行器发送的终止更新(举例,TASK_FINISHED, TASK_KILLED, TASK_FAILED),为了Mesos去释放已经分配给任务的资源。 同样是调度器负责,为了明确地告知以收到状态更新的收据,会反复进行可靠性发送。请看ACKNOWLEDGE的Call在上面的部分的定义。注意:uuid和数据的原始字节编码是Base64。
UPDATE Event (JSON)
<event-length>
{
“type” : “UPDATE”,
“update” : {
“status” : {
“task_id” : { “value” : “12344-my-task”},
“state” : “TASK_RUNNING”,
“source” : “SOURCE_EXECUTOR”,
“uuid” : “adfadfadbhgvjayd23r2uahj”,
"bytes" : "uhdjfhuagdj63d7hadkf"
}
}
}
通过管理器,执行器产生定义信息由调度器进行转发。注意:信息是通过Mesos不会进行解析,仅仅进行向调度器转发(不保证可靠性)。如果信息以任何原因丢失执行器将会重试。注意:数据的原始字节编码为Base64。
MESSAGE Event (JSON)
<event-length>
{
“type” : “MESSAGE”,
“message” : {
“agent_id” : { “value” : “12214-23523-S235235”},
“executor_id” : { “value” : “12214-23523-my-executor”},
“data” : “adfadf3t2wa3353dfadf”
}
}
管理器当代理移除时(举例,错误的健康检查)或者当执行器终止时给集群发送故障事件。注意:故障事件伴随着如下两个事件同时发生,属于代理或者执行器任何活跃任务中断UPDATE事件,所有属于代理的未完成要约收到RESCIND事件。注意:不能保证FAILURE、UPDATE和RESCIND事件的顺序。
FAILURE Event (JSON)
<event-length>
{
“type” : “FAILURE”,
“failure” : {
“agent_id” : { “value” : “12214-23523-S235235”},
“executor_id” : { “value” : “12214-23523-my-executor”},
“status” : 1
}
}
当异步错误事件发生时,管理器发送ERROR事件(举例,计算框架是不会向给定的角色授权订阅)订阅权限是采用选举的方式产生,计算框架当接收错误并尝试订阅时必须终止。
ERROR Event (JSON)
<event-length>
{
“type” : “ERROR”,
“message” : “Framework is not authorized”
}
这个事件是由管理器定期给调度器发送连接是激活状态的信息。同时也能帮助确保网络中间设备不会因为缺乏数据流而关闭持久订阅连接。请看下一部分,调度器使用这个事件来解决网络分区。
HEARTBEAT Event (JSON)
<event-length>
{
“type” : “HEARTBEAT”,
}
管理器如果注意到调度器持续的向“/scheduler”订阅链接(通过SUBSCRIBE
请求开启)请求,则断开调度器链接。链接可能会有若干种断开原因,举例来说,调度器重启、调度器失效、网络错误。注意:管理器不会持续跟踪“/scheduler”的非订阅链接,因为不需要成为持续链接。
如果管理器了解订阅链接断开,将会给调度器以“disconnected”标记并启动故障转移超时(故障转移超时是FrameworkInfo的一部分)。另外会把队列中任何挂起的事件丢弃。此外,会以“403 Forbidden”拒绝随后向“/scheduler”发起的没有订阅的HTTP请求,直到调度器再次发送向“/scheduler”订阅。如果故障转移超时后调度器没有再次订阅,管理器认为调度器永久丢失并且关闭该调度器所有的执行器,从而杀死所有的任务。因此,我们推荐所有生产的调度器使用最高等级(举例来说,4周)的故障转移超时。
注意:在计算框架超时过后,会强制关闭计算框架(例如,在计算框架开发和测试时候),或者计算框架可以发送TEARDOWN调用(属于Scheduler API的部分),或者可以用地址“/master/teardown”操作(属于Operator API部分)。
如果调度器知道向“/scheduler”发送的订阅链接断开,将会试图向“/scheduler”开启新的持久链接(在管理器检查的结果的基础上,尽可能新的管理器)和订阅。直到获取SUBSCRIBED事件才会向“/scheduler”发送新的非订阅HTTP请求;这样的请求将导致“403 Forbidden”。
如果管理器不知道订阅链接断开,但是调度器知道,调度器可能向“/scheduler”通过SUBSCRIBE开启新持久链接。在这种情况下,依据协议中定义的subscribe.force的值。如果设置为true,管理器关闭已经存在的订阅链接并允许新链接的订阅。如果设置未false,新链接尝试驳回现存的链接。这里不变的是,在管理器中只允许给出FrameworkID的持久订阅链接。对于高可用性集群的调度器,我们推荐把调度器实例的subscribe.force值设置为true,为了随后所有尝试重新连接的调度器(举例,由于断开或者管理器故障转移),仅仅把选举出来的调度器的值设置为false。
网络分裂Network partitions
在网络分裂的情况下,在调度器和管理器之间的订阅链接可能不发生断开。假设能够检测到这种情况,管理器周期性的(举例,15秒)发送HEARTBEAT心跳事件(按照Twitter的Streaming API相似的脉络)。如果调度器没有在一定时间范围内(举例,5)收到一组心跳,将会立刻断开链接并尝试重新订阅。上面的策略高度推荐给调度器使用,这是一个指数级的退避策略(举例,最大上限15秒)可以避免在极端情况下管理器重新连接时发生。调度器为了那些HTTP请求可以用类似超时(举例,75秒)接受应答。
Mesos具有分布式Mesos管理器的高可用模式;一个主管理器(最新的文档称之为领导者或者主管理器)并且在他失败的情况下有几个备份。管理者在ZooKeeper协调下选举出领导者。更多情况请了解相关文档。
调度器预计给主管理器发送HTTP请求。如果作为一个无主管理器的“HTTP 307 Temporary Redirect”请求 调度器将会接收指向主管理器”Location“报文头。
以订阅流程举例,当调度器发现没有主管理器时进行重定向。
Scheduler → Master
POST /api/v1/scheduler HTTP/1.1
Host: masterhost1:5050
Content-Type: application/json
Accept: application/json
Connection: keep-alive
{
“framework_info” : {
“user” : “foo”,
“name” : “Example HTTP Framework”
},
“type” : “SUBSCRIBE”
}
Master → Scheduler
HTTP/1.1 307 Temporary Redirect
Location: masterhost2:5050
Scheduler → Master
POST /api/v1/scheduler HTTP/1.1
Host: masterhost2:5050
Content-Type: application/json
Accept: application/json
Connection: keep-alive
{
“framework_info” : {
“user” : “foo”,
“name” : “Example HTTP Framework”
},
“type” : “SUBSCRIBE”
}
如果调度器知道某集群的管理器域名清单,就可以使用上面这种机制查找到负责订阅的主管理器。另外,调度器可以通过设定ZooKeeper(或者etcd)URL使用Pure语言库来检测主管理器。对于C++库,ZooKeeper基于管理器检测,请查看src/scheduler/scheduler.cpp