Skip to content

Commit

Permalink
Feature: When the cluster capacity is almost full, make the cluster r…
Browse files Browse the repository at this point in the history
…ead only

Signed-off-by: liuminjian <[email protected]>
  • Loading branch information
liuminjian committed Dec 26, 2023
1 parent b184f47 commit fb3b7a4
Show file tree
Hide file tree
Showing 31 changed files with 366 additions and 102 deletions.
7 changes: 7 additions & 0 deletions conf/chunkserver.conf
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ copyset.sync_chunk_limits=2097152
copyset.sync_threshold=65536
# check syncing interval
copyset.check_syncing_interval_ms=500
# wait for retry time when disk space is insufficient
copyset.wait_for_disk_freed_interval_ms=60000

#
# Clone settings
Expand Down Expand Up @@ -215,6 +217,11 @@ chunkfilepool.allocate_percent=80
chunkfilepool.chunk_file_pool_size=1GB
# The thread num for format chunks
chunkfilepool.thread_num=1
# When the chunkserver disk usage exceeds the percentage, heartbeat sets the disk status
chunkfilepool.disk_usage_percent_limit=95
# Reserve part of the chunk number, and the write operation returns readonly to the client
# when the available value is too small to avoid chunkfilepool and walfilepool not being able to obtain the chunk.
chunkfilepool.chunk_reserved=100

#
# WAL file pool
Expand Down
1 change: 1 addition & 0 deletions proto/chunk.proto
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ enum CHUNK_OP_STATUS {
CHUNK_OP_STATUS_BACKWARD = 10; // 请求的版本落后当前chunk的版本
CHUNK_OP_STATUS_CHUNK_EXIST = 11; // chunk已存在
CHUNK_OP_STATUS_EPOCH_TOO_OLD = 12; // request epoch too old
CHUNK_OP_STATUS_READONLY = 13; // If there is insufficient disk space, set the chunkserver to read-only
};

message ChunkResponse {
Expand Down
7 changes: 6 additions & 1 deletion proto/heartbeat.proto
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@ message CopysetStatistics {
required uint32 writeIOPS = 4;
}

enum ErrorType {
NORMAL = 0;
DISKFULL = 1;
}

message DiskState {
required uint32 errType = 1;
required ErrorType errType = 1;
required string errMsg = 2;
}

Expand Down
1 change: 1 addition & 0 deletions proto/topology.proto
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum ChunkServerStatus {
enum DiskState {
DISKNORMAL = 0;
DISKERROR = 1;
DISKFULL = 2;
}

enum OnlineState {
Expand Down
9 changes: 9 additions & 0 deletions src/chunkserver/chunkserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,12 @@ void ChunkServer::InitCopysetNodeOptions(
LOG_IF(FATAL, !conf->GetUInt32Value("copyset.sync_trigger_seconds",
&copysetNodeOptions->syncTriggerSeconds));
}
LOG_IF(FATAL, !conf->GetUInt32Value(
"copyset.wait_for_disk_freed_interval_ms",
&copysetNodeOptions->waitForDiskFreedIntervalMs));
LOG_IF(FATAL, !conf->GetUInt32Value(
"copyset.chunk_reserved",
&copysetNodeOptions->chunkReserved));
}

void ChunkServer::InitCopyerOptions(
Expand Down Expand Up @@ -781,6 +787,9 @@ void ChunkServer::InitHeartbeatOptions(
&heartbeatOptions->intervalSec));
LOG_IF(FATAL, !conf->GetUInt32Value("mds.heartbeat_timeout",
&heartbeatOptions->timeout));
LOG_IF(FATAL, !conf->GetUInt32Value(
"chunkfilepool.disk_usage_percent_limit",
&heartbeatOptions->chunkserverDiskLimit));
}

void ChunkServer::InitRegisterOptions(
Expand Down
4 changes: 4 additions & 0 deletions src/chunkserver/config_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ struct CopysetNodeOptions {
uint64_t syncThreshold = 64 * 1024;
// check syncing interval
uint32_t checkSyncingIntervalMs = 500u;
// wait for retry time when disk space is insufficient
uint32_t waitForDiskFreedIntervalMs = 60000;
// reserve part of the chunk number
uint32_t chunkReserved = 100;

CopysetNodeOptions();
};
Expand Down
7 changes: 7 additions & 0 deletions src/chunkserver/copyset_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ int CopysetNode::Init(const CopysetNodeOptions &options) {
dsOptions.locationLimit = options.locationLimit;
dsOptions.enableOdsyncWhenOpenChunkFile =
options.enableOdsyncWhenOpenChunkFile;
dsOptions.waitForDiskFreedIntervalMs =
options.waitForDiskFreedIntervalMs;
dsOptions.chunkReserved = options.chunkReserved;
dataStore_ = std::make_shared<CSDataStore>(options.localFileSystem,
options.chunkFilePool,
dsOptions);
Expand Down Expand Up @@ -345,6 +348,10 @@ void CopysetNode::WaitSnapshotDone() {
}
}

bool CopysetNode::ReadOnly() const {
return !dataStore_->EnoughChunk();
}

void CopysetNode::save_snapshot_background(::braft::SnapshotWriter *writer,
::braft::Closure *done) {
brpc::ClosureGuard doneGuard(done);
Expand Down
2 changes: 2 additions & 0 deletions src/chunkserver/copyset_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ class CopysetNode : public braft::StateMachine,

void WaitSnapshotDone();

bool ReadOnly() const;

private:
inline std::string GroupId() {
return ToGroupId(logicPoolId_, copysetId_);
Expand Down
10 changes: 7 additions & 3 deletions src/chunkserver/datastore/chunkserver_chunkfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* File Created: Thursday, 6th September 2018 10:49:53 am
* Author: yangyaokai
*/
#include <errno.h>
#include <fcntl.h>
#include <algorithm>
#include <memory>
Expand Down Expand Up @@ -207,7 +208,8 @@ CSErrorCode CSChunkFile::Open(bool createFile) {
if (rc != 0 && rc != -EEXIST) {
LOG(ERROR) << "Error occured when create file."
<< " filepath = " << chunkFilePath;
return CSErrorCode::InternalError;
return rc == -ENOSPC ? CSErrorCode::NoSpaceError :
CSErrorCode::InternalError;
}
}
int rc = -1;
Expand Down Expand Up @@ -400,7 +402,8 @@ CSErrorCode CSChunkFile::Write(SequenceNum sn,
<< "ChunkID: " << chunkId_
<< ",request sn: " << sn
<< ",chunk sn: " << metaPage_.sn;
return CSErrorCode::InternalError;
return rc == -ENOSPC ? CSErrorCode::NoSpaceError :
CSErrorCode::InternalError;
}
// If it is a clone chunk, the bitmap will be updated
CSErrorCode errorCode = flush();
Expand Down Expand Up @@ -478,7 +481,8 @@ CSErrorCode CSChunkFile::Paste(const char * buf, off_t offset, size_t length) {
<< "ChunkID: " << chunkId_
<< ", offset: " << offset
<< ", length: " << length;
return CSErrorCode::InternalError;
return rc == -ENOSPC ? CSErrorCode::NoSpaceError :
CSErrorCode::InternalError;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/chunkserver/datastore/chunkserver_datastore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ CSDataStore::CSDataStore(std::shared_ptr<LocalFileSystem> lfs,
baseDir_(options.baseDir),
chunkFilePool_(chunkFilePool),
lfs_(lfs),
enableOdsyncWhenOpenChunkFile_(options.enableOdsyncWhenOpenChunkFile) {
enableOdsyncWhenOpenChunkFile_(options.enableOdsyncWhenOpenChunkFile),
waitForDiskFreedIntervalMs_(options.waitForDiskFreedIntervalMs),
chunkReserved_(options.chunkReserved) {
CHECK(!baseDir_.empty()) << "Create datastore failed";
CHECK(lfs_ != nullptr) << "Create datastore failed";
CHECK(chunkFilePool_ != nullptr) << "Create datastore failed";
Expand Down
14 changes: 14 additions & 0 deletions src/chunkserver/datastore/chunkserver_datastore.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct DataStoreOptions {
PageSizeType metaPageSize;
uint32_t locationLimit;
bool enableOdsyncWhenOpenChunkFile;
uint32_t waitForDiskFreedIntervalMs;
uint32_t chunkReserved;
};

/**
Expand Down Expand Up @@ -336,6 +338,14 @@ class CSDataStore {
metaCache_.SetSyncChunkLimits(limit, threshold);
}

void WaitForDiskFreed() {
bthread_usleep(waitForDiskFreedIntervalMs_);
}

bool EnoughChunk() {
return chunkFilePool_->Size() > chunkReserved_;
}

private:
CSErrorCode loadChunkFile(ChunkID id);
CSErrorCode CreateChunkFile(const ChunkOptions & ops,
Expand All @@ -362,6 +372,10 @@ class CSDataStore {
DataStoreMetricPtr metric_;
// enable O_DSYNC When Open ChunkFile
bool enableOdsyncWhenOpenChunkFile_;
// wait for retry time when disk space is insufficient
uint32_t waitForDiskFreedIntervalMs_;
// reserve part of the chunk number
uint32_t chunkReserved_;
};

} // namespace chunkserver
Expand Down
7 changes: 5 additions & 2 deletions src/chunkserver/datastore/chunkserver_snapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Author: yangyaokai
*/

#include <errno.h>
#include <memory>
#include "src/chunkserver/datastore/chunkserver_datastore.h"
#include "src/chunkserver/datastore/chunkserver_snapshot.h"
Expand Down Expand Up @@ -154,7 +155,8 @@ CSErrorCode CSSnapshot::Open(bool createFile) {
if (ret != 0) {
LOG(ERROR) << "Error occured when create snapshot."
<< " filepath = " << snapshotPath;
return CSErrorCode::InternalError;
return ret == -ENOSPC ? CSErrorCode::NoSpaceError :
CSErrorCode::InternalError;
}
}
int rc = lfs_->Open(snapshotPath, O_RDWR|O_NOATIME|O_DSYNC);
Expand Down Expand Up @@ -216,7 +218,8 @@ CSErrorCode CSSnapshot::Write(const char * buf, off_t offset, size_t length) {
LOG(ERROR) << "Write snapshot failed."
<< "ChunkID: " << chunkId_
<< ",snapshot sn: " << metaPage_.sn;
return CSErrorCode::InternalError;
return rc == -ENOSPC ? CSErrorCode::NoSpaceError :
CSErrorCode::InternalError;
}
uint32_t pageBeginIndex = offset / blockSize_;
uint32_t pageEndIndex = (offset + length - 1) / blockSize_;
Expand Down
2 changes: 2 additions & 0 deletions src/chunkserver/datastore/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ enum CSErrorCode {
// The page has not been written, it will appear when the page that has not
// been written is read when the clone chunk is read
PageNerverWrittenError = 13,
// ENOSPC error
NoSpaceError = 14,
};

// Chunk details
Expand Down
Loading

0 comments on commit fb3b7a4

Please sign in to comment.