这是我参与「第四届青训营 」笔记创作活动的第5天
此篇笔记是对结营项目-简易分布式系统 所进行的初步设计。
技术选型
- 基础的调用方式
鉴于启动时必须通过命令行的方式来启动,所以应该至少保证一个终端命令的调用方式,对终端命令的配置采用库
github.com/urfave/cli - 通信协议 Client、NN、DN之间都需要通信,使用RPC协议进行各个节点之间的通信。RPC协议选用grpc和protobuf,这套协议使用方式比较简单,并且跨平台的支持也不错。一个简单的grpc使用教程
- 配置方式
通过yaml文件进行配置,并通过yaml的方式存储一些元数据等,基于
gopkg.in/yaml.v3库
整体结构
结合项目要求,整个项目将主要包含Client、Name Node、Data Node三个组件,这三个组件主要包含如下的交互关系:
graph TD
nn[Name Node]
c[Client]
dn[Data Node]
c <-- 元数据读写 --> nn
dn <-- 存储节点维护 --> nn
c <-- 数据读写 --> dn
读数据主要流程如下:
graph TD
nn[Name Node]
c[Client]
dn[Data Node]
c -- 1.读文件请求 --> nn
nn -- 2.返回dn BlockId FileId --> c
c -- 3.请求文件 --> dn
dn -- 4.返回文件内容 --> c
写数据主要流程如下:
graph TD
nn[Name Node]
c[Client]
dn1[Data Node 1]
dn2[Data Node 2]
dn3[Data Node 3]
c -- 1.上传文件请求 --> nn
nn -- 2.返回BlockId和DNList --> c
c -- 3.发送数据 --> dn1
dn1 -- 4.返回BlockId和FileId --> c
dn1 -- 5.a.转发数据进行存储 --> dn2
dn1 -- 5.a.转发数据进行存储 --> dn3
dn2 -- 5.b.返回结果 --> dn1
dn3 -- 5.b.返回结果 --> dn1
dn1 -- 6.上报数据落盘 --> nn
dn2 -- 6.上报数据落盘 --> nn
dn3 -- 6.上报数据落盘 --> nn
主要RPC接口
Client To NameNode
- 文件操作接口(GET\PUT)
- 获取文件接口
- 创建文件接口
- 元数据操作接口
- 重命名元数据
- 获取文件元数据
- 获取目录元数据
- 传输完成
DataNode To NameNode
- 心跳(定时)
- Block Report(定时)
- 注册DataNode
NameNode To DataNode
- 请求DataNode进行Block Report(主动执行)
Client To DataNode
- 从块读数据
- 向块写数据
各模块主要功能及特性
Client
- 能够访问Name Node和Data Node
- 通过终端命令的方式调用各API
- 通过HTTP的方式或RPC的方式进行调用
| API | 功能 | 备注 |
|---|---|---|
| Put | 存数据 | Overwrite、Not Found、Parent Not Found、一致性 |
| Get | 读数据 | 选择哪个读、遇到异常如何切换 |
| Delete | 删数据 | 删除结果是否有意义、删除成功如何定义 |
| Stat | 获取文件信息 | 参考Linux文件系统 |
| Mkdir | 建目录 | |
| Rename | 重命名 | |
| List | ls | 参考ls命令 |
Name Node
- 至少2个Name Node,Active和Standby
- Active挂掉Standby能顶上
- 元数据的存储
- Active和Standby之间的一致性:Raft协议
接口:
- 接收自Client的请求
- 读数据
- 写数据
- 目录操作
- 元信息
- 接收自Data Node的请求
- Data Node登录的请求
- Data Node数据落盘的结果
- 接收自Name Node的请求
- 元数据更新
Data Node
- 至少3个Name Node,1主2从
- DN之间的数据交换
- 单点故障问题
- 存储引擎的组织方式
接口
- 接收自Client的请求
- 读数据
- 写数据的内容
- 接收自Data Node的请求
- 写数据的内容
- 写数据完成的返回
- 接收自Name Node的请求
- 创建块
- 更新块
目录结构
├─client 客户端逻辑实现
│ └─service 客户端RPC服务提供
├─command 命令行解析
├─config 配置文件目录
│ └─items 配置信息实体类
├─datanode DataNode实现逻辑
│ └─service DataNode RPC服务
├─DirTree 存放NameNode目录树
│ ├─dir 存放目录信息
│ └─meta 存放meta信息
├─DNData 存放DataNode数据,目录下按照node名再细分目录
├─log
├─namenode namenode实现逻辑
│ └─service NameNode RPC服务
├─NNData NameNode数据存放,按副本集分类
├─proto rpc协议
├─utils 组件存放,如日志、配置等
└─values 项目所需常量及全局变量定义
调用方式
初步计划是采用命令行的方式启用
启动服务
在配置文件中填写需要的地址等配置信息后,使用配置文件启动datanode服务和namenode服务
./CrazyDFS nn --config ./config/namenode.1.yaml
./CrazyDFS dn --config ./config/datanode.1.yaml
Client操作
首先初始化Client操作环境
./CrazyDFS client --config ./config/client.yaml
然后进行相关api的操作
./CrazyDFS client get /a/b/c.txt ./c.txt
./CrazyDFS client put ./c.txt /a/b/c.txt
./CrazyDFS client rm /a/b/c.txt
./CrazyDFS client ls /a/b