 OID CND Asia Slide: CurveFSstorage of Curve file systems ● System operation and maintenance ○ Further improve tools for installation/monitoring/maintenance ○ dashboard ● Cloud Native ○ Using CURVE file system in KubernetesCURVE0 码力 | 24 页 | 3.47 MB | 6 月前3 OID CND Asia Slide: CurveFSstorage of Curve file systems ● System operation and maintenance ○ Further improve tools for installation/monitoring/maintenance ○ dashboard ● Cloud Native ○ Using CURVE file system in KubernetesCURVE0 码力 | 24 页 | 3.47 MB | 6 月前3
 Curve文件系统元数据管理→ hashtable(inode id) fsedge → hashtable (parent inode + name) 全内存 chunk → hashtable(chunk id) log + dump record 差 否 chunk 链式多副本 overwirte有数据不一致风险 chubaofs(cfs) 有元数据服务器 inode → b tree(key ino) dentry 内部结点不保存数据,只有叶子结点保存数据。 https://github.com/begeekmyfriend/bplustree,(MIT),实现了落 盘 BST O(log(n)) O(n) c++ stl 模板© XXX Page 4 of 24 skip list O(log(n)) O(n) level db,https://github.com/google/leveldb/blob/master/db/skip 写WAL,再修改内存结构。那么任何对元数据的增删改查,对应着一条记录,根据记录去修改内存数据。 按照之前的讨论,curve文件系统的元数据管理采取先写log的方式。这里先不考虑log的组成形式。 那么curve文件系统的应该是先写log,log落盘之后,更新内存。 场景三:系统退出的时候,元数据的持久化 如果采用raft的方式对元数据持久化,任务数据的修改都先持久化再修改内存。那么就不存在的系统推出的时候对元数据持久化。0 码力 | 24 页 | 204.67 KB | 6 月前3 Curve文件系统元数据管理→ hashtable(inode id) fsedge → hashtable (parent inode + name) 全内存 chunk → hashtable(chunk id) log + dump record 差 否 chunk 链式多副本 overwirte有数据不一致风险 chubaofs(cfs) 有元数据服务器 inode → b tree(key ino) dentry 内部结点不保存数据,只有叶子结点保存数据。 https://github.com/begeekmyfriend/bplustree,(MIT),实现了落 盘 BST O(log(n)) O(n) c++ stl 模板© XXX Page 4 of 24 skip list O(log(n)) O(n) level db,https://github.com/google/leveldb/blob/master/db/skip 写WAL,再修改内存结构。那么任何对元数据的增删改查,对应着一条记录,根据记录去修改内存数据。 按照之前的讨论,curve文件系统的元数据管理采取先写log的方式。这里先不考虑log的组成形式。 那么curve文件系统的应该是先写log,log落盘之后,更新内存。 场景三:系统退出的时候,元数据的持久化 如果采用raft的方式对元数据持久化,任务数据的修改都先持久化再修改内存。那么就不存在的系统推出的时候对元数据持久化。0 码力 | 24 页 | 204.67 KB | 6 月前3
 CurveBS IO Processing Flow1. A CopySet, as the basic unit of a consistent replication group, contains Consensus Module and Log Module. 2. The State Machine corresponds to the chunk in the CurveBS, and it applies the operations BRaft node.3. The BRaft node persists the log entry locally and replicates it to the followers so that the followers can also persist the log entry. BRaft Log Format: EntryHeader + Entry. 4. When majority nodes, including themselves, successfully persist the log entry, we call it commit5. After commit, apply can be applied. During apply, BRaft will call the function that we pass in0 码力 | 13 页 | 2.03 MB | 6 月前3 CurveBS IO Processing Flow1. A CopySet, as the basic unit of a consistent replication group, contains Consensus Module and Log Module. 2. The State Machine corresponds to the chunk in the CurveBS, and it applies the operations BRaft node.3. The BRaft node persists the log entry locally and replicates it to the followers so that the followers can also persist the log entry. BRaft Log Format: EntryHeader + Entry. 4. When majority nodes, including themselves, successfully persist the log entry, we call it commit5. After commit, apply can be applied. During apply, BRaft will call the function that we pass in0 码力 | 13 页 | 2.03 MB | 6 月前3
 Curve文件系统元数据持久化方案设计© XXX Page 1 of 12 元数据持久化© XXX Page 2 of 12 前言 Raft Log Raft Snapshot 持久化文件 key_value_pairs 其他说明 实现 1、inode、entry 的编码 2、KVStore Q&A 单靠 redis 的 AOF 机制能否保证数据不丢失? redis 的高可用、高可扩方案? redis + muliraft 前言 根据之前讨论的结果,元数据节点的架构如下图所示,这里涉及到两部分需要持久化/编码的内容: Raft Log:记录 operator log Raft Snapshot:将内存中的数据结构以特定格式 dump 到文件进行持久化© XXX Page 3 of 12 Raft Log +------+------------+-----+----------------+---------+----------+ feedAppendOnlyFile(cmd, ...) server.aof_buf = sdscatlen(server.aof_buf, ...) // op log buffer aofRewriteBufferAppend(...) /************************************************/0 码力 | 12 页 | 384.47 KB | 6 月前3 Curve文件系统元数据持久化方案设计© XXX Page 1 of 12 元数据持久化© XXX Page 2 of 12 前言 Raft Log Raft Snapshot 持久化文件 key_value_pairs 其他说明 实现 1、inode、entry 的编码 2、KVStore Q&A 单靠 redis 的 AOF 机制能否保证数据不丢失? redis 的高可用、高可扩方案? redis + muliraft 前言 根据之前讨论的结果,元数据节点的架构如下图所示,这里涉及到两部分需要持久化/编码的内容: Raft Log:记录 operator log Raft Snapshot:将内存中的数据结构以特定格式 dump 到文件进行持久化© XXX Page 3 of 12 Raft Log +------+------------+-----+----------------+---------+----------+ feedAppendOnlyFile(cmd, ...) server.aof_buf = sdscatlen(server.aof_buf, ...) // op log buffer aofRewriteBufferAppend(...) /************************************************/0 码力 | 12 页 | 384.47 KB | 6 月前3
 CurveFS S3本地缓存盘方案= 1024*4; LOG(INFO) << "whs start write."; for(int i = 0; i < 100000; i++) { char str[5]; sprintf(str, " %d" , i); Write(str, buf, length); } LOG(INFO) << "whs write."; 如上,写10万个4k文件,最终耗时5秒左右,如下: hzwuhongsong@pubbeta1-nostest2:/mnt$ sudo cat /data/log/curve/libcurve-cb6f5cfd.log.INFO.20210825-171813.1930722 | grep whs | egrep "start|end" I 2021-08-25T17:18:130 码力 | 9 页 | 150.46 KB | 6 月前3 CurveFS S3本地缓存盘方案= 1024*4; LOG(INFO) << "whs start write."; for(int i = 0; i < 100000; i++) { char str[5]; sprintf(str, " %d" , i); Write(str, buf, length); } LOG(INFO) << "whs write."; 如上,写10万个4k文件,最终耗时5秒左右,如下: hzwuhongsong@pubbeta1-nostest2:/mnt$ sudo cat /data/log/curve/libcurve-cb6f5cfd.log.INFO.20210825-171813.1930722 | grep whs | egrep "start|end" I 2021-08-25T17:18:130 码力 | 9 页 | 150.46 KB | 6 月前3
 Raft在Curve存储中的工程实践ChunkServer。 2. ChunkServer 收到请求,将请求封装成一个 log entry,提交给 raft。 3. raft模块在本地持久化 entry 的同时发送 entry 给其 他副本(ChunkServer)。 4. 本地持久化 log entry 成功,且另一个副本也写入 log entry 成功则 commit。 5. commit 后执行 apply,apply 03 raft在Curve中的应用 05 Q&A 04 Curve对raft的优化Curve对RAFT的优化 优化点一:轻量级快照 问题背景: raft的快照需要定期打快照,用来清理log。对于Curve块存储场景,系统状态就是Chunk当前的数据。 如果把所有chunk 拷贝一遍打快照,会出现两个问题: 1. 每次快照,空间上要多出1倍,空间浪费严重。 2. Curve块存储快照间隔默认300 码力 | 29 页 | 2.20 MB | 6 月前3 Raft在Curve存储中的工程实践ChunkServer。 2. ChunkServer 收到请求,将请求封装成一个 log entry,提交给 raft。 3. raft模块在本地持久化 entry 的同时发送 entry 给其 他副本(ChunkServer)。 4. 本地持久化 log entry 成功,且另一个副本也写入 log entry 成功则 commit。 5. commit 后执行 apply,apply 03 raft在Curve中的应用 05 Q&A 04 Curve对raft的优化Curve对RAFT的优化 优化点一:轻量级快照 问题背景: raft的快照需要定期打快照,用来清理log。对于Curve块存储场景,系统状态就是Chunk当前的数据。 如果把所有chunk 拷贝一遍打快照,会出现两个问题: 1. 每次快照,空间上要多出1倍,空间浪费严重。 2. Curve块存储快照间隔默认300 码力 | 29 页 | 2.20 MB | 6 月前3
 Curve元数据节点高可用= leaderElection->CampaginLeader() || false == leaderElection->LeaderKeyExist()) { LOG(INFO) << leaderElectionOp.leaderUniqueName << " campaign for leader agin"; } le Key()) errCode := GetErrCode(EtcdGet, err) if errCode != C.OK { log.Printf("Observe can not get leader key: %v, startTime:" + " %v, spent: %v", election return C.ObserverLeaderInternal } else if len(resp.Kvs) == 0 { log.Printf("Observe find leader key%v not exist", election.Key()) return0 码力 | 30 页 | 2.42 MB | 6 月前3 Curve元数据节点高可用= leaderElection->CampaginLeader() || false == leaderElection->LeaderKeyExist()) { LOG(INFO) << leaderElectionOp.leaderUniqueName << " campaign for leader agin"; } le Key()) errCode := GetErrCode(EtcdGet, err) if errCode != C.OK { log.Printf("Observe can not get leader key: %v, startTime:" + " %v, spent: %v", election return C.ObserverLeaderInternal } else if len(resp.Kvs) == 0 { log.Printf("Observe find leader key%v not exist", election.Key()) return0 码力 | 30 页 | 2.42 MB | 6 月前3
 curvefs client删除文件和目录功能设计ret = dentryManager_->GetDentry(parent, name, &dentry); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "dentryManager_ GetDentry fail, ret = " << ret << ", parent = " << parent ret = dentryManager_->DeleteDentry(parent, name); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "dentryManager_ DeleteDentry fail, ret = " << ret << ", parent = " << parent ret = inodeManager_->DeleteInode(dentry.inodeid()); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "inodeManager_ DeleteInode fail, ret = " << ret << ", parent = " << parent0 码力 | 15 页 | 325.42 KB | 6 月前3 curvefs client删除文件和目录功能设计ret = dentryManager_->GetDentry(parent, name, &dentry); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "dentryManager_ GetDentry fail, ret = " << ret << ", parent = " << parent ret = dentryManager_->DeleteDentry(parent, name); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "dentryManager_ DeleteDentry fail, ret = " << ret << ", parent = " << parent ret = inodeManager_->DeleteInode(dentry.inodeid()); if (ret != CURVEFS_ERROR::OK) { LOG(ERROR) << "inodeManager_ DeleteInode fail, ret = " << ret << ", parent = " << parent0 码力 | 15 页 | 325.42 KB | 6 月前3
 Curve Cloud Nativelifecycle, storage lifecycle(backup, failure, recovery) DEEP INSIGHTS Plan to Support metrics, alerts, log processing and workload analysis AUTO PILOT Plan to Support horizontal/vertical scaling, auto config0 码力 | 9 页 | 2.85 MB | 6 月前3 Curve Cloud Nativelifecycle, storage lifecycle(backup, failure, recovery) DEEP INSIGHTS Plan to Support metrics, alerts, log processing and workload analysis AUTO PILOT Plan to Support horizontal/vertical scaling, auto config0 码力 | 9 页 | 2.85 MB | 6 月前3
 Curve核心组件之chunkserver写请求: 1. Client发送写请求给Leader ChunkServer 2. 请求封装,提交给Raft node 3. 本地持久化entry的同时发送给其他peer 4. 本地持久化log entry成功,并且有一个peer也落 盘成功,则commit 5. Commit后apply,此时把写请求写到chunkChunkServer核心模块-CopysetNode 坏盘(CS1对应的盘)后的迁移流程0 码力 | 29 页 | 1.61 MB | 6 月前3 Curve核心组件之chunkserver写请求: 1. Client发送写请求给Leader ChunkServer 2. 请求封装,提交给Raft node 3. 本地持久化entry的同时发送给其他peer 4. 本地持久化log entry成功,并且有一个peer也落 盘成功,则commit 5. Commit后apply,此时把写请求写到chunkChunkServer核心模块-CopysetNode 坏盘(CS1对应的盘)后的迁移流程0 码力 | 29 页 | 1.61 MB | 6 月前3
共 11 条
- 1
- 2













