go http实现HDFS操作

ghbin0108 · · 8014 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## HDFS介绍 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。 目前使用golang调用hdfs的方式有以下几种: - 使用go http 调用webHDFS/httpfs接口实现。 - 使用c lib提供的API, 并用cgo进行封装,然后调用实现。 - 使用第三方golang客户端实现。([https://github.com/colinmarc/hdfs](https://github.com/colinmarc/hdfs))。 Hadoop 官方接口地址:[http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/WebHDFS.html](http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/WebHDFS.html) 我们这里仅介绍第一种方式,方便大家熟悉调用流程。github上的第三方client功能较全,但对golang版本有要求(1.10.3及以上),建议低版本慎用。 ### webHDFS/httpfs 官网针对这块接口介绍已经足够详细了,也提供了curl命令调用实例,大家通过go http实现对用的http接口即可。 #### **Create** 在HDFS上创建一个文件,可直接put文件内容。该接口有curl命令实例: ``` curl -i -X PUT -T <LOCAL_FILE> "http://<DATANODE>:<PORT>/webhdfs/v1/<PATH>?op=CREATE..." ``` 实际操作: ```shell curl -i -L -XPUT -T /home/xxx/test.json -H "content-type:application/octet-stream" "http://10.19.241.13:14000/webhdfs/v1/mytest/test.json?op=CREATE&user.name=root" ``` 下面用golang实现,以上传一个本地文件为例: ```go package main import ( "bytes" "errors" "io" "io/ioutil" "net/http" "os" "path" "fmt" ) /* webHDFS方式:此处仅作实例,直接填写的为datanode地址,若改为namenode地址,则需要重定向到datanode 后再调用 httpfs方式:直接填写namenode地址,无需重定向 */ var HDFSURLPrefix = "http://10.19.241.13:14000/webhdfs/v1/mydir" func createFromData(bucket string, fileName string, data []byte) error { url := HDFSURLPrefix + "/" + path.Join(bucket, fileName) + "?op=create&data=true&user.name=root" req, err := http.NewRequest("PUT", url, bytes.NewReader(data)) if err != nil { fmt.Println(fmt.Errorf("url(%v) NewRequest: %v", url, err)) return err } req.Header.Set("Content-Type", "application/octet-stream") rep, err := http.DefaultClient.Do(req) if err != nil { fmt.Println(fmt.Errorf("url(%v) DefaultClient.Do: %v", url, err)) return err } if rep.StatusCode != http.StatusCreated { fmt.Println(fmt.Errorf("url(%v) rep not ok, req(%v)", url, rep)) return err } body, err := ioutil.ReadAll(rep.Body) if err != nil { fmt.Println(fmt.Errorf("url(%v) rep body read failed: %v", url, err)) return err } fmt.Printf("url(%v) get req ok, body(%v)\n", url, string(body)) return nil } func main() { data, err := ioutil.ReadFile("/home/xxx/test.json") if err != nil { fmt.Println(fmt.Errorf("read file failed:%v", err)) return } err = createFromData("xxx", "test.json", data) if err != nil { fmt.Println(fmt.Errorf("create hdfs file failed:%v", err)) return } } ``` ### 注意: 以上代码仅简单的实现了上传一个本地文件到HDFS的功能。针对较大文件,此代码并不实用(单次readAll不合理)。这时候可以使用Append接口对大文件进行分段上传。 另外,需要注意HDFS的namenode和datanode区别,由于hdfs一般部署在集群环境中,直接访问datanode不太现实。webHDFS调用时需要通过namenode重定向到datanode。为避免此情况,建议调整为httpfs方式,直接访问namenode地址。 参考文档: [http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/WebHDFS.html](http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/WebHDFS.html)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

8014 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传