-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 2854: add spliting read request in mirrror partition by device borders #2943
base: main
Are you sure you want to change the base?
Conversation
Hi! Thank you for contributing! |
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor.h
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor_readblocks.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor_readblocks.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor_readblocks.cpp
Outdated
Show resolved
Hide resolved
for (size_t i = 0; i < blockRangeSplittedByDeviceBorders.size(); ++i) { | ||
TSgList newSglist; | ||
auto rangeSizeLeft = blockRangeSplittedByDeviceBorders[i].Size() * | ||
originalRequest.BlockSize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@komarevtsev-d стоит может брать BlockSize из конфига, а не реквеста?
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.h
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.h
Outdated
Show resolved
Hide resolved
84313a7
to
c3e105e
Compare
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_ut.cpp
Outdated
Show resolved
Hide resolved
|
||
message TDeviceCoordinate { | ||
uint64 ReplicaIndex = 1; | ||
uint64 DeviceIndex = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Сделай комент какой-нибудь что за индексы.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
порядковый номер реплики, порядковый номер девайса?
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor_readblocks.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_state.cpp
Outdated
Show resolved
Hide resolved
auto splittedRequest = SplitRequest<TMethod>( | ||
record, | ||
blockRangeSplittedByDeviceBorders, | ||
actorIdsForRequests); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Есть предложение: чтобы тут не наводить шаблонизацию, можно забить и делать запрос ReadBlocks всегда, в независимости какой запрос пришел реально.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут и так есть шаблонизация в методе ReadBlocks и TRequestActor, плюс, если из любого запроса делать readblocks, то, учитывая, что методы ReadBlocks и RequestActor и так шаблонные, придется все равно же в зависимости от метода выполнять различную логику — для локального метода прикапывать буферы в акторе и отдельный метод, который их заполнит, только, как мне кажется, это будет выглядеть даже хуже. Как будто лучше, когда у нас актор TSplittedActor с одинаковой логикой для всех методов и всего 2 шаблонные функции SplitRequest/UnifyResponses, которые уже в зависимости от метода по-своему распиливают реквесты/объединяют респонсы.
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.cpp
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.cpp
Outdated
Show resolved
Hide resolved
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_split_request_helpers.cpp
Outdated
Show resolved
Hide resolved
474253d
to
702ca6d
Compare
cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_actor_readblocks.cpp
Outdated
Show resolved
Hide resolved
9bf5226
to
bf4182b
Compare
template <typename TMethod> | ||
std::optional<TSplittedRequest<TMethod>> SplitRequest( | ||
const TRequestRecordType<TMethod>& originalRequest, | ||
std::span<const TBlockRange64> blockRangeSplittedByDeviceBorders) | ||
{ | ||
if constexpr (std::is_same_v<TMethod, TEvService::TReadBlocksMethod>) { | ||
return SplitRequestRead( | ||
originalRequest, | ||
blockRangeSplittedByDeviceBorders); | ||
} else if constexpr ( | ||
std::is_same_v<TMethod, TEvService::TReadBlocksLocalMethod>) | ||
{ | ||
return SplitRequestReadLocal( | ||
originalRequest, | ||
blockRangeSplittedByDeviceBorders); | ||
} else { | ||
return {}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Достаточно двух функций, перегрузка всё сделает:
auto SplitReadBlocksRequest(
const NProto::TReadBlocksRequest& request,
std::span<TBlockRange64> ranges)
-> TSplittedRequest<TEvService::TReadBlocksMethod>;
auto SplitReadBlocksRequest(
const NProto::TReadBlocksLocalRequest& request,
std::span<TBlockRange64> ranges)
-> TSplittedRequest<TEvService::TReadBlocksLocalMethod>;
, Requests(std::move(requests)) | ||
, ParentActorId(parentActorId) | ||
, BlockSize(blockSize) | ||
, RequestIdentityKey(requestIdentityKey) | ||
{} | ||
|
||
void Bootstrap(const NActors::TActorContext& ctx) | ||
{ | ||
Responses.resize(Requests.size()); | ||
for (size_t i = 0; i < Requests.size(); ++i) { | ||
Responses[i].BlocksCountRequested = | ||
Requests[i].BlockRangeForRequest.Size(); | ||
auto req = std::make_unique<typename TMethod::TRequest>(); | ||
req->Record = std::move(Requests[i].Request); | ||
NCloud::Send( | ||
ctx, | ||
ParentActorId, | ||
std::move(req), | ||
RequestInfo->Cookie + i + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Почему так?
TRequestsInProgress<ui64, TBlockRange64> ReadRequestsInProgress{ | ||
EAllowedRequests::ReadOnly}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это изменение само по себе не достойно отдельного PR?
@@ -472,31 +478,85 @@ void TMirrorPartitionActor::ReadBlocks( | |||
const auto replicaIndex = record.GetHeaders().GetReplicaIndex(); | |||
auto [replicaActorIds, error] = | |||
SelectReplicasToReadFrom(replicaIndex, blockRange, TMethod::Name); | |||
if (!HasError(error)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше оставить старый порядок:
if (HasError(error)) { ... распиливаем запрос ... }
... обычный запрос ...
ui32 PendingRequests = 0; | ||
TVector<TUnifyResponsesContext<TMethod>> Responses; | ||
|
||
using TResponseProto = typename TMethod::TResponse::ProtoRecordType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TRequestRecordType ?
private: | ||
STFUNC(StateWork) | ||
{ | ||
TRequestScope timer(*RequestInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Зачем тут таймер?
namespace NCloud::NBlockStore::NStorage::NSplitRequest { | ||
|
||
template <typename TMethod> | ||
class TSplittedRequestActor final |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TSplitReadBlocksActor
return; | ||
} | ||
|
||
auto blockRangeSplittedByDeviceBorders = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blockRangeSplitByDeviceBorders
} | ||
} | ||
|
||
auto splittedRequest = SplitRequest<TMethod>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
splitRequests
if (blocks.BuffersSize() == 0) { | ||
for (size_t i = 0; i < blocksCountRequested; ++i) { | ||
result.MutableBlocks()->AddBuffers(TString(blockSize, '\0')); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Это когда в одном из ответов allZeros, поэтому прихрдится добавлять на место этого запроса нули в итоговом ответе?
Нужно описание, что происходит в этом PR |
#2854
Пришлось в тесте TMirrorPartitionTest::ShouldTryToSplitReadRequest
и в лоад тестах
nbs/cloud/blockstore/tests/loadtest/local-mirror/test.py
Lines 87 to 103 in 9686d14
Перебрать разные топологии свежих девайсов из-за изменений в ReplicasInfo, которые происходят при налитии свежих девайсов в этой функции
nbs/cloud/blockstore/libs/storage/partition_nonrepl/part_mirror_state.cpp
Line 129 in 8dd2375