Skip to content

Commit

Permalink
add force operation to delete all zero compaction stat ranges; add aс…
Browse files Browse the repository at this point in the history
…tion to write specified data to compaction map table (#1690)

* add force operation to delete all zero compaction stat ranges; add action to write specified data to compaction map table

* fix-issues

* fix issues

* fix
  • Loading branch information
WilyTiger committed Aug 15, 2024
1 parent 7f55bf2 commit edc5a54
Show file tree
Hide file tree
Showing 24 changed files with 679 additions and 13 deletions.
3 changes: 3 additions & 0 deletions cloud/filestore/config/storage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,7 @@ message TStorageConfig

// Enables ThreeStageWrite for unaligned requests.
optional bool UnalignedThreeStageWriteEnabled = 366;

// Number of ranges with zero compaction stats to delete per tx.
optional uint32 MaxZeroCompactionRangesToDeletePerTx = 367;
}
4 changes: 4 additions & 0 deletions cloud/filestore/libs/storage/api/tablet.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace NCloud::NFileStore::NStorage {
xxx(ConfigureAsFollower, __VA_ARGS__) \
xxx(GetStorageConfig, __VA_ARGS__) \
xxx(GetNodeAttrBatch, __VA_ARGS__) \
xxx(WriteCompactionMap, __VA_ARGS__) \
// FILESTORE_TABLET_REQUESTS

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -93,6 +94,9 @@ struct TEvIndexTablet
EvGetNodeAttrBatchRequest = EvBegin + 31,
EvGetNodeAttrBatchResponse,

EvWriteCompactionMapRequest = EvBegin + 33,
EvWriteCompactionMapResponse,

EvEnd
};

Expand Down
2 changes: 2 additions & 0 deletions cloud/filestore/libs/storage/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ namespace {
xxx(NodeType, TString, {} )\
xxx(BlobCompressionRate, ui32, 0 )\
xxx(BlobCompressionCodec, TString, "lz4" )\
\
xxx(MaxZeroCompactionRangesToDeletePerTx, ui32, 10000 )\
// FILESTORE_STORAGE_CONFIG

#define FILESTORE_DECLARE_CONFIG(name, type, value) \
Expand Down
2 changes: 2 additions & 0 deletions cloud/filestore/libs/storage/core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ class TStorageConfig

ui64 GetTrimBytesItemCount() const;

ui32 GetMaxZeroCompactionRangesToDeletePerTx() const;

void Dump(IOutputStream& out) const;
void DumpHtml(IOutputStream& out) const;
void DumpOverridesHtml(IOutputStream& out) const;
Expand Down
4 changes: 4 additions & 0 deletions cloud/filestore/libs/storage/service/service_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ class TStorageServiceActor final
TRequestInfoPtr requestInfo,
TString input);

NActors::IActorPtr CreateWriteCompactionMapActionActor(
TRequestInfoPtr requestInfo,
TString input);

private:
void RenderSessions(IOutputStream& out);
void RenderLocalFileStores(IOutputStream& out);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ void TStorageServiceActor::HandleExecuteAction(
"getstorageconfig",
&TStorageServiceActor::CreateGetStorageConfigActionActor
},
{
"writecompactionmap",
&TStorageServiceActor::CreateWriteCompactionMapActionActor
},
};

auto it = actions.find(action);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "service_actor.h"

#include <cloud/filestore/libs/storage/api/service.h>
#include <cloud/filestore/libs/storage/api/tablet.h>
#include <cloud/filestore/libs/storage/api/tablet_proxy.h>
#include <cloud/filestore/libs/storage/core/public.h>
#include <cloud/filestore/private/api/protos/tablet.pb.h>

#include <contrib/ydb/library/actors/core/actor_bootstrapped.h>

#include <google/protobuf/util/json_util.h>

namespace NCloud::NFileStore::NStorage {

using namespace NActors;

using namespace NKikimr;

namespace {

////////////////////////////////////////////////////////////////////////////////

class TWriteCompactionMapActionActor final
: public TActorBootstrapped<TWriteCompactionMapActionActor>
{
private:
const TRequestInfoPtr RequestInfo;
const TString Input;

public:
TWriteCompactionMapActionActor(
TRequestInfoPtr requestInfo,
TString input);

void Bootstrap(const TActorContext& ctx);

private:
void ReplyAndDie(
const TActorContext& ctx,
const NProtoPrivate::TWriteCompactionMapResponse& response);
private:
STFUNC(StateWork);

void HandleWriteCompactionMapResponse(
const TEvIndexTablet::TEvWriteCompactionMapResponse::TPtr& ev,
const TActorContext& ctx);
};

////////////////////////////////////////////////////////////////////////////////

TWriteCompactionMapActionActor::TWriteCompactionMapActionActor(
TRequestInfoPtr requestInfo,
TString input)
: RequestInfo(std::move(requestInfo))
, Input(std::move(input))
{}

void TWriteCompactionMapActionActor::Bootstrap(const TActorContext& ctx)
{
NProtoPrivate::TWriteCompactionMapRequest request;
if (!google::protobuf::util::JsonStringToMessage(Input, &request).ok()) {
ReplyAndDie(
ctx,
TErrorResponse(E_ARGUMENT, "Failed to parse input"));
return;
}

if (!request.GetFileSystemId()) {
ReplyAndDie(
ctx,
TErrorResponse(E_ARGUMENT, "FileSystem id should be supplied"));
return;
}

auto requestToTablet =
std::make_unique<TEvIndexTablet::TEvWriteCompactionMapRequest>();

requestToTablet->Record = std::move(request);

NCloud::Send(
ctx,
MakeIndexTabletProxyServiceId(),
std::move(requestToTablet));

Become(&TThis::StateWork);
}

void TWriteCompactionMapActionActor::ReplyAndDie(
const TActorContext& ctx,
const NProtoPrivate::TWriteCompactionMapResponse& response)
{
auto msg = std::make_unique<TEvService::TEvExecuteActionResponse>(
response.GetError());

google::protobuf::util::MessageToJsonString(
response,
msg->Record.MutableOutput());

NCloud::Reply(ctx, *RequestInfo, std::move(msg));
Die(ctx);
}

////////////////////////////////////////////////////////////////////////////////

void TWriteCompactionMapActionActor::HandleWriteCompactionMapResponse(
const TEvIndexTablet::TEvWriteCompactionMapResponse::TPtr& ev,
const TActorContext& ctx)
{
ReplyAndDie(ctx, ev->Get()->Record);
}

////////////////////////////////////////////////////////////////////////////////

STFUNC(TWriteCompactionMapActionActor::StateWork)
{
switch (ev->GetTypeRewrite()) {
HFunc(
TEvIndexTablet::TEvWriteCompactionMapResponse,
HandleWriteCompactionMapResponse);

default:
HandleUnexpectedEvent(ev, TFileStoreComponents::SERVICE);
break;
}
}

} // namespace

IActorPtr TStorageServiceActor::CreateWriteCompactionMapActionActor(
TRequestInfoPtr requestInfo,
TString input)
{
return std::make_unique<TWriteCompactionMapActionActor>(
std::move(requestInfo),
std::move(input));
}

} // namespace NCloud::NFileStore::NStorage
63 changes: 63 additions & 0 deletions cloud/filestore/libs/storage/service/service_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5212,6 +5212,69 @@ Y_UNIT_TEST_SUITE(TStorageServiceTest)
nodeId1,
createHandleResponse->Record.GetNodeAttr().GetId());
}

Y_UNIT_TEST(ShouldWriteCompactionMap)
{
TTestEnv env;
env.CreateSubDomain("nfs");

ui32 nodeIdx = env.CreateNode("nfs");

ui64 tabletId = -1;
ui32 lastCompactionMapRangeId = 0;
env.GetRuntime().SetEventFilter(
[&] (auto& runtime, TAutoPtr<IEventHandle>& event) {
Y_UNUSED(runtime);
switch (event->GetTypeRewrite()) {
case TEvSSProxy::EvDescribeFileStoreResponse: {
using TDesc = TEvSSProxy::TEvDescribeFileStoreResponse;
const auto* msg = event->Get<TDesc>();
const auto& desc =
msg->PathDescription.GetFileStoreDescription();
tabletId = desc.GetIndexTabletId();
break;
}
case TEvIndexTabletPrivate::
EvLoadCompactionMapChunkCompleted: {
lastCompactionMapRangeId = Max(
event
->Get<TEvIndexTabletPrivate::
TEvLoadCompactionMapChunkCompleted>()
->LastRangeId,
lastCompactionMapRangeId);
break;
}
}

return false;
});

TServiceClient service(env.GetRuntime(), nodeIdx);
service.CreateFileStore("test", 1'000);

NProtoPrivate::TWriteCompactionMapRequest request;
request.SetFileSystemId("test");
for (ui32 i = 4; i < 30; ++i) {
NProtoPrivate::TCompactionRangeStats range;
range.SetRangeId(i);
range.SetBlobCount(1);
range.SetDeletionCount(2);
*request.AddRanges() = range;
}

TString buf;
google::protobuf::util::MessageToJsonString(request, &buf);
auto jsonResponse = service.ExecuteAction("writecompactionmap", buf);
NProtoPrivate::TWriteCompactionMapResponse response;
UNIT_ASSERT(google::protobuf::util::JsonStringToMessage(
jsonResponse->Record.GetOutput(),
&response).ok());

TIndexTabletClient tablet(env.GetRuntime(), nodeIdx, tabletId);
tablet.RebootTablet();

UNIT_ASSERT_VALUES_EQUAL(lastCompactionMapRangeId, 29);
}
}

} // namespace NCloud::NFileStore::NStorage
1 change: 1 addition & 0 deletions cloud/filestore/libs/storage/service/ya.make
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SRCS(
service_actor_actions_get_storage_config_fields.cpp
service_actor_actions_get_storage_config.cpp
service_actor_actions_reassign_tablet.cpp
service_actor_actions_write_compaction_map.cpp
service_actor_actions.cpp
service_actor_alterfs.cpp
service_actor_complete.cpp
Expand Down
21 changes: 18 additions & 3 deletions cloud/filestore/libs/storage/tablet/tablet_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,11 @@ void TIndexTabletActor::HandleForcedOperation(
break;
}

case NProtoPrivate::TForcedOperationRequest::E_DELETE_EMPTY_RANGES: {
mode = EMode::DeleteZeroCompactionRanges;
break;
}

default: {
e = MakeError(E_ARGUMENT, "unsupported mode");
}
Expand All @@ -630,9 +635,19 @@ void TIndexTabletActor::HandleForcedOperation(
using TResponse = TEvIndexTablet::TEvForcedOperationResponse;
auto response = std::make_unique<TResponse>(std::move(e));
if (e.GetCode() == S_OK) {
TVector<ui32> ranges = request.GetProcessAllRanges()
? GetAllCompactionRanges()
: GetNonEmptyCompactionRanges();
TVector<ui32> ranges;
if (mode == EMode::DeleteZeroCompactionRanges) {
const auto& zeroRanges = RangesWithEmptyCompactionScore;
ui32 i = 0;
while (i < zeroRanges.size()) {
ranges.push_back(i);
i += Config->GetMaxZeroCompactionRangesToDeletePerTx();
}
} else {
ranges = request.GetProcessAllRanges()
? GetAllCompactionRanges()
: GetNonEmptyCompactionRanges();
}
response->Record.SetRangeCount(ranges.size());
EnqueueForcedRangeOperation(mode, std::move(ranges));
EnqueueForcedRangeOperationIfNeeded(ctx);
Expand Down
2 changes: 2 additions & 0 deletions cloud/filestore/libs/storage/tablet/tablet_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ class TIndexTabletActor final

const NBlockCodecs::ICodec* BlobCodec;

TVector<ui32> RangesWithEmptyCompactionScore;

public:
TIndexTabletActor(
const NActors::TActorId& owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ struct TCleanupRequestConstructor
}
};

struct TDeleteZeroCompactionRangesRequestConstructor
{
std::unique_ptr<TEvIndexTabletPrivate::TEvDeleteZeroCompactionRangesRequest>
operator()(const ui32 range) const
{
return std::make_unique<
TEvIndexTabletPrivate::TEvDeleteZeroCompactionRangesRequest>(range);
}
};

using TForcedCompactionActor = TForcedOperationActor<
TEvIndexTabletPrivate::TEvCompactionResponse,
TCompactionRequestConstructor>;
Expand All @@ -243,6 +253,10 @@ using TForcedCleanupActor = TForcedOperationActor<
TEvIndexTabletPrivate::TEvCleanupResponse,
TCleanupRequestConstructor>;

using TDeleteRangesWithEmptyScoreActor = TForcedOperationActor<
TEvIndexTabletPrivate::TEvDeleteZeroCompactionRangesResponse,
TDeleteZeroCompactionRangesRequestConstructor>;

} // namespace

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -327,6 +341,14 @@ void TIndexTabletActor::HandleForcedRangeOperation(
*GetForcedRangeOperationState(),
std::move(requestInfo));
break;
case TEvIndexTabletPrivate::EForcedRangeOperationMode::DeleteZeroCompactionRanges:
actor = std::make_unique<TDeleteRangesWithEmptyScoreActor>(
ctx.SelfID,
LogTag,
Config->GetCompactionRetryTimeout(),
*GetForcedRangeOperationState(),
std::move(requestInfo));
break;

default:
TABLET_VERIFY_C(false, "unexpected forced compaction mode");
Expand Down
Loading

0 comments on commit edc5a54

Please sign in to comment.