2020-09-21 10:05:48
1. mongos节点 收到用户 insert 请求
mongos 收到一个 insert 请求后,会经过如下流程处理将请求发送给 shard 节点:
ServiceEntryPointMongos::handleRequest() --> Strategy::clientCommand() --> runCommand() --> execCommandClient() --> ClusterWriteCmd::InvocationBase::run() --> ClusterWriteCmd::InvocationBase::runImpl() --> ClusterWriter::write() --> BatchWriteExec::executeBatch() --> MultiStatementTransactionRequestsSender()
在 ClusterWriter::write()
中会准备一个 ChunkManagerTargeter
来维保存目标 namespace 在 CatalogCache
中的路由信息,方便后续请求处理。
主要代码逻辑在 BatchWriteExec::executeBatch()
中,主要是封装 BatchWriteOp
的几个核心方法来完成具体的请求处理工作:
首先,根据请求的目标shard、order 等参数来将请求分成多个批次。
Status targetStatus = batchOp.targetBatch(targeter, recordTargetErrors, &childBatches);
然后逐批构造请求,并将请求通过 MultiStatementTransactionRequestsSender
依次发送到shard,并等待接收结果。
const auto request = [&] { const auto shardBatchRequest(batchOp.buildBatchRequest(*nextBatch));
...
MultiStatementTransactionRequestsSender ars(
opCtx,
Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(),
clientRequest.getNS().db().toString(),
requests,
kPrimaryOnlyReadPreference,
isRetryableWrite ? Shard::RetryPolicy::kIdempotent : Shard::RetryPolicy::kNoRetry);
在请求构造(BatchWriteOp::buildBatchRequest()
)的的时候,设置请求的 shardVersion
。这里实际是为请求设置了一个 shardVersion
字段,设置的值则为