(一) etcd3-server-API

etcd3项目分为两部分,一是etcd clientv3,一是etcd3 server。etcd3与etcd2是不同的代码实现,同时etcd3 server支持etcd2 api,但是数据不是共用的,V2和V3 server分别独立维护自己的数据。

etcd clientv3是将对V3 server的grpc请求封装成go packge供go程序员调用的库。

本文旨在概述etcd3 的grpc API,所有代码协议均是grpc。


(一)    etcd3  gRPC API概述


发送到etcd服务器的每个API请求都是gRPC远程过程调用。etcd3中的RPC根据功能分类为:

1、处理etcd key空间的API包括:

KV - 创建,更新,提取和删除key-value对。

Watch - 监视对key的更改。

Lease - 指定时间(秒)的TTL,用于关联多个key。

2、管理集群本身的API包括:

Auth - 基于角色的身份验证机制,用于验证用户身份。

Cluster - 提供集群成员信息和配置方法。

Maintenance - 获取恢复快照,维护人员用于恢复。


1.1     Request和Response


etcd3中的所有gRPC都遵循相同的格式。每个gRPC都有一个函数Name,该函数NameRequest作为参数并NameResponse作为响应返回。详细gRPC API描述:

service KV  {

            /* Range gets the keys in the range from the key-value store. */

            Range (RangeRequest)  returns  (RangeResponse)

            /* Put puts the given key into the key-value store.  A put request increments the revision of the key-value store  and generates one event in the event history.*/

            Put (PutRequest)  returns  (PutResponse) 

            /* DeleteRange deletes the given range from the key-value store.  A delete request increments the revision of the key-value store  and generates a delete event in the event history for every deleted key.*/

            DeleteRange (DeleteRangeRequest)  returns  (DeleteRangeResponse) 

            /* Txn processes multiple requests in a single transaction. A txn request increments the revision of the key-value store and generates events with the same revision for every completed request.  It is not allowed to modify the same key several times within one txn.*/

            Txn (TxnRequest)  returns  (TxnResponse)

            /* Compact compacts the event history in the etcd key-value store. The key-value  store should be periodically compacted or the event history will continue to grow  indefinitely.*/

            Compact (CompactionRequest)  returns  (CompactionResponse)

}

service Watch {

            /* Watch watches for events happening or that have happened. Both input and output  are streams; the input stream is for creating and canceling watchers and the output  stream sends events. One watch RPC can watch on multiple key ranges, streaming events  for several watches at once. The entire event history can be watched starting from the  last compaction revision.*/

            Watch (stream WatchRequest)  returns  (stream WatchResponse)

}

service Lease {

            /*  LeaseGrant creates a lease which expires if the server does not receive a keepAlive  within a given time to live period. All keys attached to the lease will be expired and deleted if the lease expires. Each expired key generates a delete event in the event history.*/

            LeaseGrant (LeaseGrantRequest)  returns  (LeaseGrantResponse)

            /* LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted. */

            LeaseRevoke (LeaseRevokeRequest)  returns  (LeaseRevokeResponse)

            /* LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client  to the server and streaming keep alive responses from the server to the client. */

            LeaseKeepAlive (stream  LeaseKeepAliveRequest)  returns  (stream  LeaseKeepAliveResponse)

            /* LeaseTimeToLive retrieves lease information. */

            LeaseTimeToLive (LeaseTimeToLiveRequest)  returns  (LeaseTimeToLiveResponse)

           /* LeaseLeases lists all existing leases. */

            LeaseLeases (LeaseLeasesRequest)  returns  (LeaseLeasesResponse)

}

service Auth {

            /*  AuthEnable enables authentication. */

            AuthEnable (AuthEnableRequest)  returns  (AuthEnableResponse)

            /* AuthDisable disables authentication. */

            AuthDisable (AuthDisableRequest)  returns  (AuthDisableResponse)

            /*  Authenticate processes an authenticate request.  */

            Authenticate (AuthenticateRequest)  returns  (AuthenticateResponse)

            /*  UserAdd adds a new user. */

            UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse)

            /*  UserGet gets detailed user information.*/

            UserGet(AuthUserGetRequest) returns (AuthUserGetResponse)

            /*  UserList gets a list of all users.*/

            UserList(AuthUserListRequest) returns (AuthUserListResponse)

            /* UserDelete deletes a specified user. */

            UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse)     

            /*  UserChangePassword changes the password of a specified user.*/       

            UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse)            

            /* UserGrant grants a role to a specified user.  */

            UserGrantRole(AuthUserGrantRoleRequest) returns (AuthUserGrantRoleResponse)  

            /*  UserRevokeRole revokes a role of specified user.*/          

            UserRevokeRole(AuthUserRevokeRoleRequest) returns (AuthUserRevokeRoleResponse)     

            /* RoleAdd adds a new role.  */       

            RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse)            

            /* RoleGet gets detailed role information. */

            RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse)            

            /*  RoleList gets lists of all roles.*/

            RoleList(AuthRoleListRequest) returns (AuthRoleListResponse)        

            /*  RoleDelete deletes a specified role.*/    

            RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse)         

            /*  RoleGrantPermission grants a permission of a specified key or range to a specified role.*/   

            RoleGrantPermission(AuthRoleGrantPermissionRequest) returns (AuthRoleGrantPermissionResponse) 

            /* RoleRevokePermission revokes a key or range permission of a specified role. */

            RoleRevokePermission(AuthRoleRevokePermissionRequest) returns (AuthRoleRevokePermissionResponse)

}

service Cluster {

            /* MemberAdd adds a member into the cluster.*/

            MemberAdd(MemberAddRequest) returns (MemberAddResponse)

            /* MemberRemove removes an existing member from the cluster. */

            MemberRemove(MemberRemoveRequest) returns (MemberRemoveResponse)

            /* MemberUpdate updates the member configuration. */

            MemberUpdate(MemberUpdateRequest) returns (MemberUpdateResponse)

            /* MemberList lists all the members in the cluster. */

            MemberList(MemberListRequest) returns (MemberListResponse)

}

service Maintenance {

            /*  Alarm activates, deactivates, and queries alarms regarding cluster health. */

            Alarm(AlarmRequest) returns (AlarmResponse)

            /* Status gets the status of the member. */

            Status(StatusRequest) returns (StatusResponse)

            /* Defragment defragments a member's backend database to recover storage space. */

            Defragment(DefragmentRequest) returns (DefragmentResponse)

            /* Hash computes the hash of whole backend keyspace,  including key, lease, and other buckets in storage.  This is designed for testing ONLY!  Do not rely on this in production with ongoing transactions, since Hash operation does not hold MVCC locks. Use "HashKV" API instead for "key" bucket consistency checks. */

            Hash(HashRequest) returns (HashResponse)

            /*  HashKV computes the hash of all MVCC keys up to a given revision. It only iterates "key" bucket in backend storage.*/

            HashKV(HashKVRequest) returns (HashKVResponse)

            /* Snapshot sends a snapshot of the entire backend from a member over a stream to a client. */

            Snapshot(SnapshotRequest) returns (stream SnapshotResponse)

            /*  MoveLeader requests current leader node to transfer its leadership to transferee. */

            MoveLeader(MoveLeaderRequest) returns (MoveLeaderResponse)

}


1.2    Response Header


来自etcd API的所有响应都有一个附加的响应头,其中包含响应的集群元数据:

message    ResponseHeader  {

        /*  cluster_id is the ID of the cluster which sent the response. */

        uint64  cluster_id=1;

         /* member_id is the ID of the member which sent the response. */

        uint64  member_id=2;

         /* revision is the key-value store revision when the request was applied.  For watch progress responses, the header.revision indicates progress. All future events  recieved in this stream are guaranteed to have a higher revision number than the  header.revision number. */

        int64    revision=3;

        /* raft_term is the raft term when the request was applied. */

        uint64  raft_term=4;

}

Cluster_ID - 生成响应的集群的ID。

Member_ID - 生成响应的成员的ID。

Reversion - 生成响应时key-value存储的修订版。

Raft_Term - 生成响应时成员的Raft术语。


(二)    KV API


2.1    Key-Value


Key-Value是KV API可以操作的最小单位。每个key-value对都有许多以protobuf格式定义的字段:

message     KeyValue  {

         /* key is the key in bytes. An empty key is not allowed.  */

        bytes    key=1;

        /*  create_revision is the revision of last creation on this key.  */

        int64    create_revision=2;

        /* mod_revision is the revision of last modification on this key.  */

        int64    mod_revision=3;

         /* version is the version of the key. A deletion resets  the version to zero and any modification of the key  increases its version. */

        int64    version=4;

         /* value is the value held by the key, in bytes.  */

        bytes    value=5;

         /* lease is the ID of the lease that attached to key.  When the attached lease expires, the key will be deleted.  If lease is 0, then no lease is attached to the key.  */

        int64    lease=6;

}

Key --- 以字节为单位的key, 不允许使用空ke'y。

Value --- 以字节为单位的value。

Version --- 版本是key的版本。删除version将重置为零,并且对key的任何修改都会增加其版本。

Create_Revision --- 最后一次创建key的版本号。

Mod_Revision --- 最后一次修改key的版本号。

Lease --- 附加到key的Lease的ID。如果Lease为0,表明没有将任何Lease附加到key。


2.2    Range Request


使用Range API调用从KV存储中获取key,其中包含RangeRequest:

message RangeRequest {

  enum SortOrder {

        NONE = 0; // default, no sorting

        ASCEND = 1; // lowest target value first

        DESCEND = 2; // highest target value first

  }

  enum SortTarget {

        KEY = 0;

        VERSION = 1;

        CREATE = 2;

        MOD = 3;

        VALUE = 4;

  }

  /*  key is the first key for the range.  If range_end is not given, the request only looks up key. */

  bytes   key = 1;

  /*  range_end is the upper bound on the requested range [key, range_end). If range_end is '\0', the range is all keys >= key. If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"), then the range request gets all keys prefixed with key. If both key and range_end are '\0', then the range request returns all keys. */

  bytes     range_end = 2;

  /* limit is a limit on the number of keys returned for the request. When limit is set to 0, it is treated as no limit. */

  int64     limit = 3;

  /*  revision is the point-in-time of the key-value store to use for the range.  If revision is less or equal to zero, the range is over the newest key-value store. If the revision has been compacted, ErrCompacted is returned as a response. */

  int64     revision = 4;

  /*  sort_order is the order for returned sorted results. */

  SortOrder     sort_order = 5;

  /*  sort_target is the key-value field to use for sorting. */

  SortTarget     sort_target = 6;

  /*  serializable sets the range request to use serializable member-local reads.  Range requests are linearizable by default; linearizable requests have higher  latency and lower throughput than serializable requests but reflect the current consensus of the cluster. For better performance, in exchange for possible stale reads, a serializable range request is served locally without needing to reach consensus with other nodes in the cluster. */

  bool     serializable = 7;

  /*  keys_only when set returns only the keys and not the values. */

  bool     keys_only = 8;

  /*  count_only when set returns only the count of the keys in the range. */

  bool     count_only = 9;

  /*  min_mod_revision is the lower bound for returned key mod revisions; all keys with lesser mod revisions will be filtered away. */

  int64     min_mod_revision = 10; 

  /*  max_mod_revision is the upper bound for returned key mod revisions; all keys with  greater mod revisions will be filtered away. */

  int64     max_mod_revision = 11;

  /* min_create_revision is the lower bound for returned key create revisions; all keys with  lesser create revisions will be filtered away. */

  int64     min_create_revision = 12;

  /* max_create_revision is the upper bound for returned key create revisions; all keys with  greater create revisions will be filtered away. */

  int64     max_create_revision = 13;

}

Key,Range_End --- 要获取的key范围。

Limit ---限制请求返回的最大key数量。当limit设置为0时,将其视为无限制。

Revision --- 用于key Range内的KV存储的版本范围限制。如果revision小于或等于零,则范围超过最新的key-value存储如果压缩修订,则返回ErrCompacted作为响应。

Sort_Order --- 请求倒序还是顺序。

Sort_Target --- 要排序的类型(key, value, version, create_version, mod_version)。

Serializable --- 设置范围请求以使用可序列化的成员本地读取。默认情况下,Range是可线性化的; 它反映了该集群目前的共识。为了获得更好的性能和可用性,为了换取可能的过时读取,可在本地提供可序列化范围请求,而无需与群集中的其他节点达成共识。

Keys_Only --- 仅返回key而不返回value。

Count_Only --- 仅返回range中key的计数。

Min_Mod_Revision --- key mod version的下限; 

Max_Mod_Revision --- key mod version的上限; 

Min_Create_Revision --- key create version的下限; 

Max_Create_Revision --- key create version的上限; 


2.3    Range Response


message    RangeResponse {

    ResponseHeader    header=1;

    /* kvs is the list of key-value pairs matched by the range request.  kvs is empty when count is requested. */

    repeated   KeyValue    kvs=2;

    /* more indicates if there are more keys to return in the requested range. */

    bool    more=3;

   /*  count is set to the number of keys within the range when requested. */

    int64    count=4;

}

Header ---见ResponseHeader

Kvs --- 范围请求匹配的key-value对列表。当Count_Only设置为true时,Kvs为空。

More --- 表明RangeRequest中的limit为true。

Count --- 满足范围请求的key总数。


2.4    Put Request


通过发出Put Request将key-value保存到KV存储中:

message    PutRequest {

    /* key is the key, in bytes, to put into the key-value store. */

    bytes    key=1;

    /* value is the value, in bytes, to associate with the key in the key-value store. */

    bytes    value=2;

    /* lease is the lease ID to associate with the key in the key-value store. A lease  value of 0 indicates no lease. */

    int64    lease=3;

   /*  If prev_kv is set, etcd gets the previous key-value pair before changing it. The previous key-value pair will be returned in the put response. */

     bool    prev_kv=4;

   /* If ignore_value is set, etcd updates the key using its current value. Returns an error if the key does not exist. */

    bool    ignore_value=5;

    /* If ignore_lease is set, etcd updates the key using its current lease.  Returns an error if the key does not exist. */

    bool    ignore_lease=6;

}

Key --- 放入key-value存储区的key的名称。

Value --- 与key-value存储中的key关联的值(以字节为单位)。

Lease ---与key-value存储中的key关联的Lease ID。Lease值为0表示没有Lease。

Prev_Kv --- 设置时,在从此Put请求更新之前使用key-value对数据进行响应。

Ignore_Value --- 设置后,更新key而不更改其当前值。如果key不存在,则返回错误。

Ignore_Lease --- 设置后,更新key而不更改其当前Lease。如果key不存在,则返回错误。


2.5    Put Response


message   PutResponse    {

    ResponseHeader    header=1;

    /*  if prev_kv is set in the request, the previous key-value pair will be returned. */

    KeyValue    prev_kv=2;

}

Header ---见ResponseHeader

Prev_Kv --- 由Putif Prev_Kv设置的key-value对PutRequest。


2.6    Delete Range Request


使用该DeleteRange呼叫删除key范围,其中DeleteRangeRequest:

message    DeleteRangeRequest {

    /* key is the first key to delete in the range. */

    byteskey=1;

    /* range_end is the key following the last key to delete for the range [key, range_end).  If range_end is not given, the range is defined to contain only the key argument.  If range_end is one bit larger than the given key, then the range is all the keys  with the prefix (the given key).  If range_end is '\0', the range is all keys greater than or equal to the key argument. */

    bytesrange_end=2;

    /*  If prev_kv is set, etcd gets the previous key-value pairs before deleting it.  The previous key-value pairs will be returned in the delete response. */

    boolprev_kv=3;

}

Key,Range_End - 要删除的key范围。

Prev_Kv - 设置后,返回已删除key-value对的内容。


2.6    Delete Range Request


message    DeleteRangeResponse {

    ResponseHeader    header=1;

    /* deleted is the number of keys deleted by the delete range request. */

    int64    deleted=2;

   /*  if prev_kv is set in the request, the previous key-value pairs will be returned. */

    repeated    KeyValue    prev_kvs=3;

}

Deleted --- 已删除的key数。

Prev_Kv --- DeleteRange操作删除的所有key-value对的列表。


2.7    Transaction


事务是KV存储上的原子If / Then / Else构造。它提供了一个原语,用于将请求分组在原子块(即then / else)中,这些原子块的执行基于key-value存储的内容被保护(即if)。事务可用于保护key免受意外的并发更新,构建比较和交换操作以及开发更高级别的并发控制。

事务可以在单个请求中以原子方式处理多个请求。对于key-value存储的修改,这意味着商店的修订仅针对事务递增一次,并且事务生成的所有事件将具有相同的修订。但是,禁止在单个事务中多次修改同一个key。

所有交易都通过比较结合来保护,类似于“如果”声明。每次比较都会检查商店中的单个key。它可以检查值的缺失或存在,与给定值进行比较,或检查key的修订版本或版本。两种不同的比较可适用于相同或不同的key。所有的比较都是原子地应用的; 如果所有比较都为真,则说事务成功并且etcd应用事务的then / successrequest块,否则称其失败并应用else / failurerequest块。

每个比较都编码为一条Compare消息:

message    Compare {

        enum    CompareResult {

            EQUAL=0;

            GREATER=1;

            LESS=2;

            NOT_EQUAL=3;

        }

        enum    CompareTarget {

            VERSION=0;

            CREATE=1;

            MOD=2;

            VALUE=3;

        }

        CompareResult    result=1;        // target is the key-value field to inspect for the comparison.

        CompareTarget    target=2;        // key is the subject key for the comparison operation.

        bytes    key=3;

        oneof    target_union {

                /*  version is the version of the given key. */

                int64    version=4;

                 /*  create_revision is the creation revision of the given key */

                int64    create_revision=5;

                /*   mod_revision is the last modified revision of the given key.  */

                int64    mod_revision=6;

                 /*  value is the value of the given key, in bytes. */

                bytes    value=7;

                 /*   lease is the lease id of the given key. */

                int64 lease = 8;

        }

}

Result --- 逻辑比较操作的类型(例如,等于,小于等)。

Target --- 要比较的key-value字段。key的版本,创建修订版,修改版本或值。

Key --- 比较的key。

Target_Union --- 用于比较的用户指定数据。

在处理比较块之后,事务应用一个请求块。块是RequestOp消息:

message RequestOp {

  /* request is a union of request types accepted by a transaction. */

  oneof  request {

        RangeRequest     request_range =1;

        PutRequest     request_put =2;

        DeleteRangeRequest     request_delete_range =3;

        TxnRequest     request_txn =4;

    }

}

Request_Range --- a RangeRequest。

Request_Put --- a PutRequest。钥匙必须是唯一的。它可能不与任何其他Puts或Deletes共享key。

Request_Delete_Range --- a DeleteRangeRequest。它可能不会与任何Puts或Deletes请求共享key。

总之,一个事务是通过TxnAPI调用发出的,它需要TxnRequest:

message     TxnRequest  {

         /* compare is a list of predicates representing a conjunction of terms. If the comparisons succeed, then the success requests will be processed in order, and the response will contain their respective responses in order. If the comparisons fail, then the failure requests will be processed in order,  and the response will contain their respective responses in order. */

         repeated   Compare   compare =1;

        /* success is a list of requests which will be applied when compare evaluates to true. */

          repeated   RequestOp  success =2;

        /* failure is a list of requests which will be applied when compare evaluates to false. */

          repeated   RequestOp  failure =3;

}

Compare --- 表示保护事务的术语组合的谓词列表。

Success --- 如果所有比较测试评估为true,则处理请求列表。

Failure --- 如果任何比较测试评估为false,则处理的请求列表。

客户端收到TxnResponse来自Txn呼叫的消息:

message     TxnResponse{

          ResponseHeader header =1;

        /* succeeded is set to true if the compare evaluated to true or false otherwise. */

          bool     succeeded =2;

        /* responses is a list of responses corresponding to the results from applying success if succeeded is true or failure if succeeded is false. */

          repeated   ResponseOp   responses =3;

}

Success --- 无论是Compare评估为真还是假。

Responses --- Success如果成功,则应用块的结果对应的响应列表为true或Failure if成功为false。

该Responses列表对应于应用RequestOp列表的结果,每个响应编码为ResponseOp:

message ResponseOp {

          /* response is a union of response types returned by a transaction.  */

          oneof   response {

                    RangeResponse   response_range =1;

                    PutResponse  response_put =2;

                    DeleteRangeResponse   response_delete_range =3;

                     TxnResponse   response_txn =4;

    }

}


(三)    Watch   API



Watch API提供基于事件的接口,用于异步监视key更改。etcd3 watch通过持续watch当前或历史的给定修订,等待key的更改,并将key更新流回客户端。


3.1    Events


每个key的每次更改都用Event消息表示。一个Event消息同时提供更新的数据和更新的类型:

message Event{

      enum EventType {

            PUT =0;

            DELETE =1;

    }

      /* type is the kind of event. If type is a PUT, it indicates new data has been stored to the key. If type is a DELETE, it indicates the key was deleted. */

      EventType type =1;

        /*  kv holds the KeyValue for the event. A PUT event contains current kv pair. A PUT event with kv.Version=1 indicates the creation of a key. A DELETE/EXPIRE event contains the deleted key with  its modification revision set to the revision of deletion. */

      KeyValue kv =2;

     /*  prev_kv holds the key-value pair before the event happens. */

      KeyValue prev_kv =3;

}

Type --- 事件的类型。PUT类型表示新数据已存储到Key中。DELETE表示Key已删除。

KV --- 与事件关联的KeyValue。PUT事件包含当前的kv对。kv.Version = 1的PUT事件表示创建key。DELETE事件包含已删除的key,其修改修订版设置为删除修订版。

Prev_KV --- 紧接事件之前修订的key的key-value对。为了节省带宽,只有在watch明确启用它时才会填写。


3.2    Watch streams


Watch是长时间运行的请求,并使用gRPC流来传输事件数据。Watch streams是双向的; 客户端写入流以建立监视和读取以接收监视事件。单个监视流可以通过使用每个监视标识符标记事件来复用许多不同的监视。这种多路复用有助于减少核心etcd集群的内存占用和连接开销。

Watch对事件做出三点保证:

有序 --- 事件按修订排序; 如果事件发生在已经发布的事件之前,则该事件将永远不会出现在watch上。

可靠 --- 一系列事件永远不会丢失任何事件的后续序列; 如果有事件按时间顺序排列为

原子 --- 事件清单保证包含完整的修订; 多个key上相同修订版的更新不会分成几个事件列表。


3.3    WatchCreateRequest


message WatchCreateRequest {

  /* key is the key to register for watching. */

  bytes    key =1;

/* range_end is the end of the range [key, range_end) to watch. If range_end is not given, only the key argument is watched. If range_end is equal to '\0', all keys greater than or equal to the key argument are watched. If the range_end is one bit larger than the given key,  then all keys with the prefix (the given key) will be watched. */

  bytes    range_end =2;

/* start_revision is an optional revision to watch from (inclusive). No start_revision is "now". */

  int64   start_revision =3;

/* progress_notify is set so that the etcd server will periodically send a WatchResponse with no events to the new watcher if there are no recent events. It is useful when clients wish to recover a disconnected watcher starting from a recent known revision. The etcd server may decide how often it will send notifications based on current load. */

  bool   progress_notify =4;

enum  FilterType{

    NOPUT =0;   // filter out put event.

    NODELETE =1;  // filter out delete event.

}

  /* filters filter the events at server side before it sends back to the watcher. */

  repeated   FilterType  filters =5;

/* If prev_kv is set, created watcher gets the previous KV before the event happens.  If the previous KV is already compacted, nothing will be returned. */

  bool   prev_kv =6;

/* If watch_id is provided and non-zero, it will be assigned to this watcher. Since creating a watcher in etcd is not a synchronous operation,  this can be used ensure that ordering is correct when creating multiple watchers on the same stream. Creating a watcher with an ID already in  use on the stream will cause an error to be returned. */

  int64   watch_id =7;

/* fragment enables splitting large revisions into multiple watch responses. */

  bool   fragment =8;

}

Key,Range_End --- 要watch的key范围。

Start_Revision --- 包含开始watch的可选修订版。如果没有给出,它将在修改监视创建响应标题修订版之后流式传输事件。可以从最后一次压缩修订开始watch整个可用事件历史记录。

Progress_Notify --- 设置后,如果没有最近的事件,watch将定期收到没有事件的WatchResponse。当客户希望从最近的已知修订版本开始恢复断开连接的watcher时,它非常有用。etcd服务器根据当前服务器负载决定发送通知的频率。

Fliters --- 要在服务器端过滤掉的事件类型列表。

Prev_Kv --- 设置后,watch会在事件发生之前接收key-value数据。这对于了解已覆盖的数据非常有用。


3.5    WatchCreateResponse:


message WatchResponse {

  ResponseHeader header =1;

/* watch_id is the ID of the watcher that corresponds to the response. */

  int64    watch_id =2;

/* created is set to true if the response is for a create watch request.  The client should record the watch_id and expect to receive events for the created watcher from the same stream.  All events sent to the created watcher will attach with the same watch_id.  */

  bool    created =3;

/* canceled is set to true if the response is for a cancel watch request.  No further events will be sent to the canceled watcher.  */

  bool   canceled =4;

/* compact_revision is set to the minimum index if a watcher tries to watch  at a compacted index.  This happens when creating a watcher at a compacted revision or the watcher cannot  catch up with the progress of the key-value store. The client should treat the watcher as canceled and should not try to create any  watcher with the same start_revision again.  */

  int64   compact_revision =5;

/* cancel_reason indicates the reason for canceling the watcher.  */

  string   cancel_reason =6;

/* framgment is true if large watch response was split over multiple responses.  */

  bool   fragment =7;

repeated   Event events =11;

}

Watch_ID --- 与响应对应的监视的ID。

Created --- 如果响应是针对创建监视请求,则设置为true。客户端应记录ID并期望在流上接收监视事件。发送给创建的watcher的所有事件都将具有相同的watch_id。

Canceled --- 如果响应是取消watch请求,则设置为true。不会向已取消的watcher发送更多事件。

Compact_Revision --- 如果watcher尝试watch压缩版本,则设置为etcd可用的最小历史版本。在压缩版本中创建watch程序或watcher无法跟上key-value存储的进度时会发生这种情况。watcher将被取消; 使用相同的start_revision创建新watch将失败。

Events - 与给定监视ID对应的顺序新事件列表。


3.6    WatchCancelRequest:


message WatchCancelRequest {

  /* watch_id is the watcher id to cancel so that no more events are transmitted. */

  int64 watch_id =1;

}

Watch_ID - 要取消的watch的ID,以便不再传输任何事件。


(四)    Lease API


Lease是一种检测客户活跃度的机制。集群授予Lease生存时间。如果etcd集群在给定的TTL周期内没有收到keepAlive,则Lease到期。

为了将Lease绑定到key-value存储中,每个key可以附加到最多一个Lease。当Lease到期或被撤销时,附加到该Lease的所有key都将被删除。每个过期的key在事件历史记录中生成删除事件。


4.1   LeaseGrantRequest ( 获得Lease)


message   LeaseGrantRequest{

  /* TTL is the advisory time-to-live in seconds. Expired lease will return -1. */

  int64    TTL =1;

/* ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID. */

  int64    ID =2;

}

TTL --- 咨询生存时间,以秒为单位。

ID --- 请求的Lease ID。如果ID设置为0,则etcd将选择一个ID。


4.2    LeaseGrantResponse


   message LeaseGrantResponse{

  ResponseHeader header =1;

/* ID is the lease ID for the granted lease. */

  int64 ID =2;

/* TTL is the server chosen lease time-to-live in seconds. */

  int64 TTL =3;

string error =4;

}

ID - 授予的LeaseID。

TTL - 服务器为Lease选择的生存时间(以秒为单位)。


4.3    LeaseRevokeRequest


message   LeaseRevokeRequest{

  /* ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted. */

  int64    ID =1;

}

ID --- 要撤消的LeaseID。撤销Lease后,将删除所有附加的key。


4.4    LeaseRevokeResponse


message   LeaseRevokeResponse{

  ResponseHeader header =1;

}


4.5    LeaseKeepAliveRequest


使用通过LeaseKeepAliveAPI调用创建的双向流刷新Lease。当客户希望刷新Lease时,它会通过LeaseKeepAliveRequest流发送:

message LeaseKeepAliveRequest{

  /* ID is the lease ID for the lease to keep alive. */

  int64 ID =1;

}

ID - 要保持活动的Lease的ID。


4.6    LeaseKeepAliveResponse


message LeaseKeepAliveResponse{

  ResponseHeader header =1;

/* ID is the lease ID from the keep alive request. */

  int64   ID =2;

/* TTL is the new time-to-live for the lease.*/

  int64   TTL =3;

}

ID - 使用新TTL刷新的Lease。

TTL - Lease剩余的新生存时间(以秒为单位)。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 本文将介绍的是我们自研的RPC框架Dapeng-soa(https://github.com/dapeng-soa...
    枫叶_huazhe阅读 7,243评论 3 7
  • 因为工作需求,公司需要使用ETCD来做gRPC服务的负载均衡,以及集群管理,所以对etcd做了一些研究,希望能给大...
    Jay_Guo阅读 46,563评论 8 47
  • 与etcd交互 本文翻译自官方文档:https://coreos.com/etcd/docs/latest/dev...
    雨中星辰0阅读 12,552评论 0 5
  • from http://www.infoq.com/cn/articles/etcd-interpretation...
    小树苗苗阅读 13,938评论 3 38
  • 小娅打电话来:“姐,我是小娅,我回来了,晚上见见啊?四五年没有见了”“好的” 小娅,是我上上届的学生,她是2012...
    十指花香阅读 213评论 0 0