From 9200404710ad4d849d3a4528d4cacff205f74a8c Mon Sep 17 00:00:00 2001 From: wudemiao Date: Mon, 27 May 2019 14:43:40 +0800 Subject: [PATCH] add Recommended Configuration Change-Id: I4f36434b2ef666879b7b6015c38a513e68aea2d1 --- conf/chunkserver.conf.example | 4 +- .../local/chunkserver/conf/chunkserver.conf.0 | 2 +- .../local/chunkserver/conf/chunkserver.conf.1 | 2 +- .../local/chunkserver/conf/chunkserver.conf.2 | 2 +- .../chunkserver/conf/chunkserver.conf.docker1 | 2 +- .../chunkserver/conf/chunkserver.conf.docker2 | 2 +- .../chunkserver/conf/chunkserver.conf.docker3 | 2 +- .../chunkserver/conf/chunkserver.conf.docker4 | 2 +- .../conf/chunkserver_docker.conf.0 | 2 +- .../conf/chunkserver_docker.conf.1 | 2 +- .../conf/chunkserver_docker.conf.2 | 2 +- proto/chunk.proto | 186 +++++++++--------- src/chunkserver/conf_epoch_file.h | 1 + src/chunkserver/copyset_node.h | 6 + src/chunkserver/copyset_service.cpp | 124 ++++++------ .../datastore/chunkserver_datastore.cpp | 4 +- src/chunkserver/op_request.cpp | 7 + 17 files changed, 188 insertions(+), 164 deletions(-) diff --git a/conf/chunkserver.conf.example b/conf/chunkserver.conf.example index 0b08fcbba4..d9baa71750 100644 --- a/conf/chunkserver.conf.example +++ b/conf/chunkserver.conf.example @@ -39,8 +39,8 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 -copyset.catchup_margin=50 +copyset.snapshot_interval_s=1800 +copyset.catchup_margin=20000 copyset.chunk_data_uri=local://./0/copysets copyset.raft_log_uri=local://./0/copysets copyset.raft_meta_uri=local://./0/copysets diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.0 b/deploy/local/chunkserver/conf/chunkserver.conf.0 index f0ffcec19e..c7d4df9f83 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.0 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.0 @@ -39,7 +39,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local://./0/copysets copyset.raft_log_uri=local://./0/copysets diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.1 b/deploy/local/chunkserver/conf/chunkserver.conf.1 index 37ca5eaa2c..3ace47f151 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.1 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.1 @@ -39,7 +39,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local://./1/copysets copyset.raft_log_uri=local://./1/copysets diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.2 b/deploy/local/chunkserver/conf/chunkserver.conf.2 index 85b26eb794..7180e16a2a 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.2 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.2 @@ -39,7 +39,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local://./2/copysets copyset.raft_log_uri=local://./2/copysets diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.docker1 b/deploy/local/chunkserver/conf/chunkserver.conf.docker1 index e307534b21..969b8ce60f 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.docker1 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.docker1 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/0/cs/data copyset.raft_log_uri=local:///root/data/0/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.docker2 b/deploy/local/chunkserver/conf/chunkserver.conf.docker2 index 75ea3b7c84..d6a2963eca 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.docker2 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.docker2 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/1/cs/data copyset.raft_log_uri=local:///root/data/1/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.docker3 b/deploy/local/chunkserver/conf/chunkserver.conf.docker3 index d2c6177e22..c4e42cd1a6 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.docker3 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.docker3 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/2/cs/data copyset.raft_log_uri=local:///root/data/2/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver.conf.docker4 b/deploy/local/chunkserver/conf/chunkserver.conf.docker4 index d6dda25206..afe59a4a33 100644 --- a/deploy/local/chunkserver/conf/chunkserver.conf.docker4 +++ b/deploy/local/chunkserver/conf/chunkserver.conf.docker4 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/2/cs/data copyset.raft_log_uri=local:///root/data/2/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver_docker.conf.0 b/deploy/local/chunkserver/conf/chunkserver_docker.conf.0 index 018c4ab10d..7be4979b6f 100644 --- a/deploy/local/chunkserver/conf/chunkserver_docker.conf.0 +++ b/deploy/local/chunkserver/conf/chunkserver_docker.conf.0 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/0/cs/data copyset.raft_log_uri=local:///root/data/0/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver_docker.conf.1 b/deploy/local/chunkserver/conf/chunkserver_docker.conf.1 index c5cf71b87e..21e42873a3 100644 --- a/deploy/local/chunkserver/conf/chunkserver_docker.conf.1 +++ b/deploy/local/chunkserver/conf/chunkserver_docker.conf.1 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/1/cs/data copyset.raft_log_uri=local:///root/data/1/cs/log diff --git a/deploy/local/chunkserver/conf/chunkserver_docker.conf.2 b/deploy/local/chunkserver/conf/chunkserver_docker.conf.2 index 398cd6c83c..7f2d67a61b 100644 --- a/deploy/local/chunkserver/conf/chunkserver_docker.conf.2 +++ b/deploy/local/chunkserver/conf/chunkserver_docker.conf.2 @@ -21,7 +21,7 @@ copyset.check_term=true copyset.disable_cli=false copyset.log_applied_task=false copyset.election_timeout_ms=5000 -copyset.snapshot_interval=30 +copyset.snapshot_interval_s=30 copyset.catchup_margin=50 copyset.chunk_data_uri=local:///root/data/2/cs/data copyset.raft_log_uri=local:///root/data/2/cs/log diff --git a/proto/chunk.proto b/proto/chunk.proto index 6e79537445..b939651878 100755 --- a/proto/chunk.proto +++ b/proto/chunk.proto @@ -1,92 +1,94 @@ -syntax = "proto2"; -package curve.chunkserver; - -option cc_generic_services = true; - -// Qos 参数 -message QosRequestParas { - optional uint32 clientId = 1; - optional int32 dmclockDelta = 2; - optional int32 dmclockRho = 3; -} - -message QosResponseParas { - optional int32 phase = 1; // 0: 代表 reservation 阶段; 1: 代表 priority 阶段 - optional int32 cost = 2; // -} - -// For chunk -enum CHUNK_OP_TYPE { - CHUNK_OP_DELETE = 0; // 删除 chunk - CHUNK_OP_READ = 1; // 读 chunk - CHUNK_OP_WRITE = 2; // 写 chunk - CHUNK_OP_READ_SNAP = 3; // read chunk snapshot - CHUNK_OP_DELETE_SNAP = 4; // delete chunk snapshot - CHUNK_OP_CREATE_CLONE = 5; // 创建clone chunk - CHUNK_OP_RECOVER = 6; // 恢复clone chunk - CHUNK_OP_PASTE = 7; // paste chunk 内部请求 - CHUNK_OP_UNKNOWN = 8; // 未知 Op -}; - -// read/write 的实际数据在 rpc 的 attachment 中 -message ChunkRequest { - required CHUNK_OP_TYPE opType = 1; // for all - required uint32 logicPoolId = 2; // for all // logicPoolId 实际上 uint16,但是 proto 没有 uint16 - required uint32 copysetId = 3; // for all - required uint64 chunkId = 4; // for all - optional uint64 appliedIndex = 5; // for read - optional uint32 offset = 6; // for read/write - optional uint32 size = 7; // for read/write/clone 创建快照请求中表示请求创建的chunk大小 - optional QosRequestParas deltaRho = 8; // for read/write - optional uint64 sn = 9; // for write/read snapshot 写请求中表示文件当前版本号,读快照请求中表示请求的chunk的版本号 - optional uint64 correctedSn = 10; // for CreateCloneChunk/DeleteChunkSnapshotOrCorrectedSn 用于修改chunk的correctedSn - optional string location = 11; // for clone chunk -}; - -enum CHUNK_OP_STATUS { - CHUNK_OP_STATUS_SUCCESS = 0; // 成功 - CHUNK_OP_STATUS_REDIRECTED = 1; // 不是 leader,重定向 - CHUNK_OP_STATUS_DISK_FAIL = 2; // 磁盘返回错误 - CHUNK_OP_STATUS_CRC_FAIL = 3; // CRC 校验失败 - CHUNK_OP_STATUS_INVALID_REQUEST = 4; // 请求参数不对 - CHUNK_OP_STATUS_NOSPACE = 5; // 空间不够 - CHUNK_OP_STATUS_COPYSET_NOTEXIST = 6; // copyset 不存在 - CHUNK_OP_STATUS_CHUNK_NOTEXIST = 7; // chunk或其快照文件不存在 - CHUNK_OP_STATUS_FAILURE_UNKNOWN = 8; // 其他错误 -}; - -message ChunkResponse { - required CHUNK_OP_STATUS status = 1; - optional string redirect = 2; // 自己不是 leader,重定向给 leader - optional uint64 appliedIndex = 3; // 返回当前最新的 committedIndex, 注意 read 和 write 都要返回 - optional QosResponseParas phaseCost = 4; // for read/write - optional uint64 chunkSn = 5; // for GetChunkInfo 表示chunk文件版本号,0表示不存在 - optional uint64 snapSn = 6; // for GetChunkInfo 表示chunk文件快照的版本号,0表示不存在 - -}; - -message GetChunkInfoRequest { - required uint32 logicPoolId = 1; - required uint32 copysetId = 2; - required uint64 chunkId = 3; -}; - -message GetChunkInfoResponse { - required CHUNK_OP_STATUS status = 1; - optional string redirect = 2; // 自己不是 leader,重定向给 leader - repeated uint64 chunkSn = 3; // chunk 版本号 和 snapshot 版本号 -}; - -service ChunkService { - rpc DeleteChunk (ChunkRequest) returns (ChunkResponse); - rpc ReadChunk (ChunkRequest) returns (ChunkResponse); - rpc WriteChunk (ChunkRequest) returns (ChunkResponse); - - rpc ReadChunkSnapshot (ChunkRequest) returns (ChunkResponse); - rpc DeleteChunkSnapshotOrCorrectSn (ChunkRequest) returns (ChunkResponse); - - rpc GetChunkInfo (GetChunkInfoRequest) returns (GetChunkInfoResponse); - - rpc CreateCloneChunk (ChunkRequest) returns (ChunkResponse); - rpc RecoverChunk (ChunkRequest) returns (ChunkResponse); -}; +syntax = "proto2"; +package curve.chunkserver; + +option cc_generic_services = true; + +// Qos 参数 +message QosRequestParas { + optional uint32 clientId = 1; + optional int32 dmclockDelta = 2; + optional int32 dmclockRho = 3; +} + +message QosResponseParas { + optional int32 phase = 1; // 0: 代表 reservation 阶段; 1: 代表 priority 阶段 + optional int32 cost = 2; // +} + +// For chunk +enum CHUNK_OP_TYPE { + CHUNK_OP_DELETE = 0; // 删除 chunk + CHUNK_OP_READ = 1; // 读 chunk + CHUNK_OP_WRITE = 2; // 写 chunk + CHUNK_OP_READ_SNAP = 3; // read chunk snapshot + // TODO(wudemiao): 后期替换成CHUNK_OP_DELETE_SNAP_OR_CORRECT_SN, + // 保证和chunkserver的接口一致 + CHUNK_OP_DELETE_SNAP = 4; // delete chunk snapshot + CHUNK_OP_CREATE_CLONE = 5; // 创建clone chunk + CHUNK_OP_RECOVER = 6; // 恢复clone chunk + CHUNK_OP_PASTE = 7; // paste chunk 内部请求 + CHUNK_OP_UNKNOWN = 8; // 未知 Op +}; + +// read/write 的实际数据在 rpc 的 attachment 中 +message ChunkRequest { + required CHUNK_OP_TYPE opType = 1; // for all + required uint32 logicPoolId = 2; // for all // logicPoolId 实际上 uint16,但是 proto 没有 uint16 + required uint32 copysetId = 3; // for all + required uint64 chunkId = 4; // for all + optional uint64 appliedIndex = 5; // for read + optional uint32 offset = 6; // for read/write + optional uint32 size = 7; // for read/write/clone 创建快照请求中表示请求创建的chunk大小 + optional QosRequestParas deltaRho = 8; // for read/write + optional uint64 sn = 9; // for write/read snapshot 写请求中表示文件当前版本号,读快照请求中表示请求的chunk的版本号 + optional uint64 correctedSn = 10; // for CreateCloneChunk/DeleteChunkSnapshotOrCorrectedSn 用于修改chunk的correctedSn + optional string location = 11; // for clone chunk +}; + +enum CHUNK_OP_STATUS { + CHUNK_OP_STATUS_SUCCESS = 0; // 成功 + CHUNK_OP_STATUS_REDIRECTED = 1; // 不是 leader,重定向 + CHUNK_OP_STATUS_DISK_FAIL = 2; // 磁盘返回错误 + CHUNK_OP_STATUS_CRC_FAIL = 3; // CRC 校验失败 + CHUNK_OP_STATUS_INVALID_REQUEST = 4; // 请求参数不对 + CHUNK_OP_STATUS_NOSPACE = 5; // 空间不够 + CHUNK_OP_STATUS_COPYSET_NOTEXIST = 6; // copyset 不存在 + CHUNK_OP_STATUS_CHUNK_NOTEXIST = 7; // chunk或其快照文件不存在 + CHUNK_OP_STATUS_FAILURE_UNKNOWN = 8; // 其他错误 +}; + +message ChunkResponse { + required CHUNK_OP_STATUS status = 1; + optional string redirect = 2; // 自己不是 leader,重定向给 leader + optional uint64 appliedIndex = 3; // 返回当前最新的 committedIndex, 注意 read 和 write 都要返回 + optional QosResponseParas phaseCost = 4; // for read/write + optional uint64 chunkSn = 5; // for GetChunkInfo 表示chunk文件版本号,0表示不存在 + optional uint64 snapSn = 6; // for GetChunkInfo 表示chunk文件快照的版本号,0表示不存在 + +}; + +message GetChunkInfoRequest { + required uint32 logicPoolId = 1; + required uint32 copysetId = 2; + required uint64 chunkId = 3; +}; + +message GetChunkInfoResponse { + required CHUNK_OP_STATUS status = 1; + optional string redirect = 2; // 自己不是 leader,重定向给 leader + repeated uint64 chunkSn = 3; // chunk 版本号 和 snapshot 版本号 +}; + +service ChunkService { + rpc DeleteChunk (ChunkRequest) returns (ChunkResponse); + rpc ReadChunk (ChunkRequest) returns (ChunkResponse); + rpc WriteChunk (ChunkRequest) returns (ChunkResponse); + + rpc ReadChunkSnapshot (ChunkRequest) returns (ChunkResponse); + rpc DeleteChunkSnapshotOrCorrectSn (ChunkRequest) returns (ChunkResponse); + + rpc GetChunkInfo (GetChunkInfoRequest) returns (GetChunkInfoResponse); + + rpc CreateCloneChunk (ChunkRequest) returns (ChunkResponse); + rpc RecoverChunk (ChunkRequest) returns (ChunkResponse); +}; diff --git a/src/chunkserver/conf_epoch_file.h b/src/chunkserver/conf_epoch_file.h index e2c0dd04ea..0a7af8a893 100644 --- a/src/chunkserver/conf_epoch_file.h +++ b/src/chunkserver/conf_epoch_file.h @@ -22,6 +22,7 @@ using curve::fs::LocalFsFactory; /** * 配置版本序列化和反序列化的工具类 + * TODO(wudemiao): 后期替换采用json编码 */ class ConfEpochFile { public: diff --git a/src/chunkserver/copyset_node.h b/src/chunkserver/copyset_node.h index d07dc7d861..f31ca92730 100755 --- a/src/chunkserver/copyset_node.h +++ b/src/chunkserver/copyset_node.h @@ -132,6 +132,12 @@ class CopysetNode : public braft::StateMachine, */ virtual bool IsLeaderTerm() const; + /** + * 返回当前的任期 + * @return 当前的任期 + */ + virtual uint64_t LeaderTerm() const; + /** * 返回leader id * @return diff --git a/src/chunkserver/copyset_service.cpp b/src/chunkserver/copyset_service.cpp index 7b83086cd6..89ac360680 100755 --- a/src/chunkserver/copyset_service.cpp +++ b/src/chunkserver/copyset_service.cpp @@ -1,58 +1,66 @@ -/* - * Project: curve - * Created Date: 18-8-23 - * Author: wudemiao - * Copyright (c) 2018 netease - */ - -#include -#include - -#include "src/chunkserver/copyset_service.h" -#include "src/chunkserver/copyset_node_manager.h" - -namespace curve { -namespace chunkserver { - -void CopysetServiceImpl::CreateCopysetNode(RpcController *controller, - const CopysetRequest *request, - CopysetResponse *response, - Closure *done) { - brpc::ClosureGuard doneGuard(done); - brpc::Controller *cntl = dynamic_cast(controller); - - // 解析request中的peers - Configuration conf; - for (int i = 0; i < request->peerid_size(); ++i) { - PeerId peer; - int ret = peer.parse(request->peerid(i)); - if (ret != 0) { - cntl->SetFailed(EINVAL, - "Fail to parse peer id %s", - request->peerid(i).c_str()); - return; - } - conf.add_peer(peer); - } - - LogicPoolID logicPoolID = request->logicpoolid(); - CopysetID copysetID = request->copysetid(); - GroupId groupId = ToGroupId(logicPoolID, copysetID); - if (false == copysetNodeManager_->IsExist(logicPoolID, - copysetID)) { - if (true == - copysetNodeManager_->CreateCopysetNode(logicPoolID, - copysetID, - conf)) { - response->set_status(COPYSET_OP_STATUS::COPYSET_OP_STATUS_SUCCESS); - } else { - response->set_status( - COPYSET_OP_STATUS::COPYSET_OP_STATUS_FAILURE_UNKNOWN); - } - } else { - response->set_status(COPYSET_OP_STATUS::COPYSET_OP_STATUS_EXIST); - } -} - -} // namespace chunkserver -} // namespace curve +/* + * Project: curve + * Created Date: 18-8-23 + * Author: wudemiao + * Copyright (c) 2018 netease + */ + +#include +#include + +#include "src/chunkserver/copyset_service.h" +#include "src/chunkserver/copyset_node_manager.h" + +namespace curve { +namespace chunkserver { + +void CopysetServiceImpl::CreateCopysetNode(RpcController *controller, + const CopysetRequest *request, + CopysetResponse *response, + Closure *done) { + brpc::ClosureGuard doneGuard(done); + brpc::Controller *cntl = dynamic_cast(controller); + + LOG(INFO) << "Received create copyset request: " + << ToGroupIdString(request->logicpoolid(), request->copysetid()); + + // 解析request中的peers + Configuration conf; + for (int i = 0; i < request->peerid_size(); ++i) { + PeerId peer; + int ret = peer.parse(request->peerid(i)); + if (ret != 0) { + cntl->SetFailed(EINVAL, + "Fail to parse peer id %s", + request->peerid(i).c_str()); + return; + } + conf.add_peer(peer); + } + + LogicPoolID logicPoolID = request->logicpoolid(); + CopysetID copysetID = request->copysetid(); + GroupId groupId = ToGroupId(logicPoolID, copysetID); + if (false == copysetNodeManager_->IsExist(logicPoolID, + copysetID)) { + if (true == + copysetNodeManager_->CreateCopysetNode(logicPoolID, + copysetID, + conf)) { + response->set_status(COPYSET_OP_STATUS::COPYSET_OP_STATUS_SUCCESS); + } else { + response->set_status( + COPYSET_OP_STATUS::COPYSET_OP_STATUS_FAILURE_UNKNOWN); + } + } else { + response->set_status(COPYSET_OP_STATUS::COPYSET_OP_STATUS_EXIST); + } + + LOG(INFO) << "Accomplish create copyset " + << ToGroupIdString(request->logicpoolid(), request->copysetid()) + << ", response code: " + << COPYSET_OP_STATUS_Name(response->status()); +} + +} // namespace chunkserver +} // namespace curve diff --git a/src/chunkserver/datastore/chunkserver_datastore.cpp b/src/chunkserver/datastore/chunkserver_datastore.cpp index 03cd5169f6..6c387ad67e 100644 --- a/src/chunkserver/datastore/chunkserver_datastore.cpp +++ b/src/chunkserver/datastore/chunkserver_datastore.cpp @@ -282,8 +282,8 @@ CSErrorCode CSDataStore::GetChunkInfo(ChunkID id, CSChunkInfo* chunkInfo) { auto chunkFile = metaCache_.Get(id); if (chunkFile == nullptr) { - LOG(ERROR) << "Get ChunkInfo failed, Chunk not exists." - << "ChunkID = " << id; + LOG(INFO) << "Get ChunkInfo failed, Chunk not exists." + << "ChunkID = " << id; return CSErrorCode::ChunkNotExistError; } chunkFile->GetInfo(chunkInfo); diff --git a/src/chunkserver/op_request.cpp b/src/chunkserver/op_request.cpp index 15213cc072..5f1622a3b9 100755 --- a/src/chunkserver/op_request.cpp +++ b/src/chunkserver/op_request.cpp @@ -73,6 +73,13 @@ int ChunkOpRequest::Propose(const ChunkRequest *request, } task.data = &log; task.done = new ChunkClosure(shared_from_this()); + /** + * 由于apply是异步的,有可能某个节点在term1是leader,apply了一条log, + * 但是中间发生了主从切换,在很短的时间内这个节点又变为term3的leader, + * 之前apply的日志才开始进行处理,这种情况下要实现严格意义上的复制状态 + * 机,需要解决这种ABA问题,可以在apply的时候设置leader当时的term + */ + task.expected_term = node_->LeaderTerm(); node_->Propose(task);