数据存储服务实现-1

本文介绍了基于Go语言构建的分布式对象存储系统,该系统通过HTTP服务存储和检索对象数据,如图片、视频和文本。文章详细讲解了主要由main函数驱动的数据服务实现,使用了urfave/cli库处理命令行输入。在Action回调函数中,系统首先尝试从环境变量读取配置,若非K8s环境,则从命令行参数获取。接着初始化数据并启动服务。源代码可在提供的链接中找到,适合学习Go语言和分布式存储的开发者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开头先给大家链接下我们可以查看目录来浏览分布式对象存储的系列文章。接下来再来回到我们的主题:)

数据存储服务是用来存储对象数据的服务,它是数据最终落盘的服务。我们分布式对象存储系统主要对外暴露的是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,欢迎各位拉取下来阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值