开头先给大家链接下我们可以查看目录来浏览分布式对象存储的系列文章。接下来再来回到我们的主题:)
数据存储服务是用来存储对象数据的服务,它是数据最终落盘的服务。我们分布式对象存储系统主要对外暴露的是HTTP服务。通过HTTP服务传递过来的对象数据(图片、视频、文本等)都是存储在当地服务节点的本地磁盘上的,当然我们服务节点的磁盘可以是NAS盘等,还可以对磁盘做RAID1,RAID5,RAID10等。这不是此篇文章的重点,感兴趣的朋友可以在网上搜索相关的资料进行学习。
本系统主要是采用golang语言,golang语言有着及其强大的功能和极简的api,当然其他语言的开发人员也可以根据该思路自行实现。所有文章我们都会介绍我们golang代码的一些语法和使用,让你可以轻松入门golang语言。
接下来我们来探讨数据服务是如何实现的。
映入我们眼前的是main函数,它是所有系统的入口函数,startdatanode.go代码如下:
package main //main函数必须是在main包下面的,每个单独可运行模块都需要有一个main包
import ( //导入的依赖包,这个没啥说的
"com.mgface.disobj/common"
. "com.mgface.disobj/datanode/command"
"github.com/urfave/cli"
)
const usage = ` //定义常量,请注意这是反单引号,可以支持多行,java13才支持多行字符串,使用的是"""三个双引号。
*
* 数据服务主要提供存储对象数据
*
`
func main() {
//执行的终端命令
cmds := []cli.Command{
StartDNCommand,
}
common.RunFn(usage, cmds)
}
这里提一下cli包,该包主要是处理命令行的输入解析处理的包。main函数里面有一个cli包下面的Command数组,该数据包含了StartDNCommand对象。该对象的类型就是Command类型。
让我们来看看StartDNCommand对象的真面目吧:)
var StartDNCommand = cli.Command{
Name: "start",
Aliases: []string{"st"},
Usage: `示例指令:
startdatanode start -na 127.0.0.1:5000 -mna 127.0.0.1:3001 -sdp C:\\objects
`,
Flags: **startflag**,
Action: func(ctx *cli.Context) error {
var nodeaddr, mna, storedatapath, podnamespace string
//-------解析k8s env
cfg := new(EnvConfig)
env.IgnorePrefix()
err := env.Fill(cfg)
if err != nil {
log.Info("未读取到env环境.")
} else {
nodeaddr, mna, storedatapath, podnamespace = readEnv(cfg)
}
//假如pns为空,说明不是k8s环境
if podnamespace == "" {
nodeaddr, mna, storedatapath = readCli(ctx)
}
//初始化数据
api.Initval(storedatapath, nodeaddr)
//启动服务
server.StartServer(nodeaddr, mna, podnamespace)
return nil
},
}
var **startflag** = []cli.Flag{
cli.StringFlag{
Name: "na", //node address
Usage: "节点地址(node addres)",
Required: false,
},
cli.StringFlag{
Name: "mna", //metanode address
Usage: "元数据服务节点地址(metanode address).只要配置一个可以正常连接上的种子节点即可",
Required: false,
},
cli.StringFlag{
Name: "sdp", //store data path
Usage: "数据存储路径(store data path)",
Required: false,
},
//todo 配置文件要单独处理
cli.StringFlag{
Name: "file",
Usage: "配置文件",
Required: false,
},
}
这里解释下cli.Command里面的参数名称:
参数名 | 参数名解析 |
---|---|
Name | 指令名称,我们这里叫“start” |
Aliases | 指令的别名,一般是简写,这里我们叫“st” |
Usage | 如何使用该指令,我们这里的用法“startdatanode start -na 127.0.0.1:5000 -mna 127.0.0.1:3001 -sdp C:\objects” |
Flags | 指令的参数集合,这里我们有na,nma,sdp,file这些参数 |
Action | 指令执行的回调动作,我们执行该指令之后触发的动作。 |
大家如果不会使用cli.Flag、cli.Command这些结构体不要紧,看看官网如何介绍的。不熟悉如何使用也不打紧,因为学习新语言就是先照着葫芦画瓢,再去研究。
我们重点看下Action的代码:
func(ctx *cli.Context) error {
var nodeaddr, mna, storedatapath, podnamespace string
//-------解析k8s env
cfg := new(EnvConfig)
env.IgnorePrefix()
err := env.Fill(cfg)
if err != nil {
log.Info("未读取到env环境.")
} else {
nodeaddr, mna, storedatapath, podnamespace = readEnv(cfg)
}
//假如pns为空,说明不是k8s环境
if podnamespace == "" {
nodeaddr, mna, storedatapath = readCli(ctx)
}
//初始化数据
api.Initval(storedatapath, nodeaddr)
//启动服务
server.StartServer(nodeaddr, mna, podnamespace)
return nil
},
我们首先读取系统的env变量,看看是否是通过k8s pod设置了这些变量,如果没有podnamespace变量为空的话,说明我们没有用k8s云平台。然后接下来我们就是初始化数据,
启动数据存储服务啦。接下来下一篇文章我们来剖析这些源代码看看是如何实现的。
源代码地址在这里https://gitee.com/wanyuxiang000/distributedObjStorage.git,欢迎各位拉取下来阅读。