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 <liuminjian@chinatelecom.cn>
  • Loading branch information
liuminjian committed Dec 22, 2023
1 parent b184f47 commit e4f77ce
Show file tree
Hide file tree
Showing 31 changed files with 359 additions and 103 deletions.
4 changes: 4 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,8 @@ chunkfilepool.allocate_percent=80
chunkfilepool.chunk_file_pool_size=1GB
# The thread num for format chunks
chunkfilepool.thread_num=1
# 当chunkserver磁盘使用率超过百分比,heartbeat设置disk状态
chunkfilepool.diskUsagePercentLimit=95

#
# 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
5 changes: 5 additions & 0 deletions src/chunkserver/chunkserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,9 @@ 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));
}

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

void ChunkServer::InitRegisterOptions(
Expand Down
2 changes: 2 additions & 0 deletions src/chunkserver/config_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ 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;

CopysetNodeOptions();
};
Expand Down
13 changes: 12 additions & 1 deletion src/chunkserver/copyset_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ CopysetNode::CopysetNode(const LogicPoolID &logicPoolId,
lastScanSec_(0),
enableOdsyncWhenOpenChunkFile_(false),
isSyncing_(false),
checkSyncingIntervalMs_(500) {
checkSyncingIntervalMs_(500),
readOnly_(false) {
}

CopysetNode::~CopysetNode() {
Expand Down Expand Up @@ -135,6 +136,8 @@ int CopysetNode::Init(const CopysetNodeOptions &options) {
dsOptions.locationLimit = options.locationLimit;
dsOptions.enableOdsyncWhenOpenChunkFile =
options.enableOdsyncWhenOpenChunkFile;
dsOptions.waitForDiskFreedIntervalMs =
options.waitForDiskFreedIntervalMs;
dataStore_ = std::make_shared<CSDataStore>(options.localFileSystem,
options.chunkFilePool,
dsOptions);
Expand Down Expand Up @@ -345,6 +348,14 @@ void CopysetNode::WaitSnapshotDone() {
}
}

bool CopysetNode::ReadOnly() const {
return readOnly_.load(std::memory_order_acquire);
}

void CopysetNode::SetReadOnly(bool readOnly) {
readOnly_.store(readOnly, std::memory_order_release);
}

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

void WaitSnapshotDone();

bool ReadOnly() const;

void SetReadOnly(bool readOnly);

private:
inline std::string GroupId() {
return ToGroupId(logicPoolId_, copysetId_);
Expand Down Expand Up @@ -545,6 +549,8 @@ class CopysetNode : public braft::StateMachine,
uint32_t checkSyncingIntervalMs_;
// async snapshot future object
std::future<void> snapshotFuture_;
// copyset readonly flag
std::atomic<bool> readOnly_;
};

} // namespace chunkserver
Expand Down
7 changes: 4 additions & 3 deletions src/chunkserver/datastore/chunkserver_chunkfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <fcntl.h>
#include <algorithm>
#include <memory>
#include <errno.h>

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

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

void WaitForDiskFreed() {
bthread_usleep(waitForDiskFreedIntervalMs_);
}

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

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

#include <memory>
#include <errno.h>
#include "src/chunkserver/datastore/chunkserver_datastore.h"
#include "src/chunkserver/datastore/chunkserver_snapshot.h"

Expand Down Expand Up @@ -154,7 +155,7 @@ 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 +217,7 @@ 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

0 comments on commit e4f77ce

Please sign in to comment.