Skip to content
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

【Feature】When the cluster capacity is almost full, make the cluster read only #2868

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
7 changes: 7 additions & 0 deletions conf/chunkserver.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,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 @@ -207,6 +209,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=0

#
# 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reuse DiskState in topology.proto?

NORMAL = 0;
DISKFULL = 1;
}

message DiskState {
required uint32 errType = 1;
required ErrorType errType = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does using ErrorType instead of uint32 satisfy compatibility?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, i have checked them all

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 @@ -503,6 +503,9 @@ void ChunkServer::InitChunkFilePoolOptions(
LOG_IF(FATAL, !conf->GetBoolValue(
"chunkfilepool.enable_get_chunk_from_pool",
&chunkFilePoolOptions->getFileFromPool));
LOG_IF(FATAL, !conf->GetUInt32Value(
"chunkfilepool.chunk_reserved",
&chunkFilePoolOptions->chunkReserved));

if (chunkFilePoolOptions->getFileFromPool == false) {
std::string chunkFilePoolUri;
Expand Down Expand Up @@ -710,6 +713,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 +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
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
10 changes: 9 additions & 1 deletion src/chunkserver/copyset_node.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a LOG(FATAL) in L555, this may happen when all the chunks are used up.

Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,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 +347,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 Expand Up @@ -529,7 +535,9 @@ void CopysetNode::on_leader_start(int64_t term) {
* https://github.com/opencurve/curve/pull/2448
*/
ChunkServerMetric::GetInstance()->IncreaseLeaderCount();
concurrentapply_->Flush();
if (concurrentapply_ != nullptr) {
concurrentapply_->Flush();
}
leaderTerm_.store(term, std::memory_order_release);
LOG(INFO) << "Copyset: " << GroupIdString()
<< ", peer id: " << peerId_.to_string()
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In L202, GetFile will fail if there is no available chunk, and shouldn't this be handled here as well?

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
7 changes: 6 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 Expand Up @@ -428,5 +429,9 @@ ChunkMap CSDataStore::GetChunkMap() {
return metaCache_.GetMap();
}

bool CSDataStore::EnoughChunk() {
return chunkFilePool_->EnoughChunk();
}

} // namespace chunkserver
} // namespace curve
9 changes: 9 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 @@ -328,6 +329,8 @@ class CSDataStore {

virtual ChunkMap GetChunkMap();

virtual bool EnoughChunk();

void SetCacheCondPtr(std::shared_ptr<std::condition_variable> cond) {
metaCache_.SetCondPtr(cond);
}
Expand All @@ -336,6 +339,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 +369,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
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