对象存储

基本概念

主流存储类型分为三种:块存储、文件存储以及对象存储

  • NAS(文件存储):Network Attached storage,提供了存储功能和文件系统的网络服务器,客户端可以访问NAS上的文件系统,还可以上传和下载文件,使用协议:SMB、NFS以及AFS等网络文件系统协议,对于客户端来说就是网络上的文件服务器。
  • SAN(块存储):Storage Area Network,和NAS的区别就是SAN只提供了块存储,而把文件系统抽象给客户端来管理,使用协议:Fibre\Channel、iSCSI\ATA over Ethnet和HyperSCSI,对于客户端来说就是一块磁盘,可以对其格式化,创建文件系统并挂载。
  • 对象存储:对象指的是面向对象,集合了块存储和文件存储的优点,拥有访问速度快、容量大等特性。并且容易搭配云计算,是一种新的网络存储架构。

对象存储系统(Object-Based Storage System)是综合了NAS和SAN的优点,同时具有SAN的高速直接访问和NAS的数据共享等优势,提供了高可靠性、跨平台性以及安全的数据共享的存储体系结构。

为了更好的说明三者的差异,我打个比方,假设有三个人想从A地到B地,现在有三种交通方式。甲选择轿车、乙选择公共汽车、丙选择地铁。块存储类似于轿车,速度快,但是容量小(轿车只能乘坐几个人);文件存储类似于公共汽车,速度慢(公共汽车有站点和红绿灯需要考虑),但是容量较大(能多坐不少人);对象存储类似于地铁,速度快,容量大。

不同的数据管理方式

  • NAS,数据是以一个个文件的形式管理的。
  • SAN,数据是以数据块的形式管理的,每个数据块都有自己的地址,没有额外的背景信息。
  • 对象存储,数据是以对象的方式管理,一个对象包括:数据、元数据、全局标识符。
  1. 对象的数据通常是无结构的数据,比如:图片、视频或文档等;对象的元数据则指的是对象的相关描述,比如:图片的大小、文档的拥有者等;对象id则是一个全局的唯一标识符,用来区分对象的。

不同的访问数据方式

  • NAS,通过NFS等网络协议访问某个远程服务器上存储的文件
  • SAN,通过数据块的地址访问SAN上的数据块
  • 对象存储,通过REST网络服务访问对象
  1. 对象存储,访问对象的方式很方便,是通过REST接口对对象进行操作,用HTTP动词(GETPOSTPUTDELETE等)描述操作。除此之外,还有一种访问方式,就是使用各大云商提供的客户端去操作对象。
    比如:Amazons3cmd、阿里云的osscmd/ossutil、腾讯云的coscmd等。

  

对象存储优缺点

先说优点,之前大概也提了下:

  • 可扩展性高:对象存储能够扩展数十乃至数百EB的容量,能够充分利用高密度存储;
  • 效率高:扁平化结构,不受复杂目录系统对性能的影响;
  • 无需迁移:对象存储是一种横向扩展系统,随着容量的增加,数据根据算法自动分布于所有的对象存储节点;
  • 安全性高:对象存储通常凭借HTTP调用对象存储本身提供的认证密钥来提供数据访问;访问方便:不光支持HTTP(S)协议,采用REST的API方式调用和检索数据,同样增加了NFS和SMB支持;成本相对低:与块存储方式相比,对象存储是最具成本效益的数据存储类型,并且与云计算搭配,把对象存储的这一特性发挥的淋漓尽致。

再提缺点:

  • 最终一致性:由于不同节点的位置不同,数据同步时可能会有一定时间的延迟或者错误;
  • 不易做数据库:对象存储比较适合存储那些变动不大甚至不变的文件,而对于像数据库这种需要直接与存储裸盘相互映射的应用,还是块存储更合适。

单体对象存储架构实现

单体对象存储架构

go语言实现

  1. package main
  2.  
  3. import (
  4. "io"
  5. "net/http"
  6. "os"
  7. "log"
  8. "strings"
  9. )
  10.  
  11. func main() {
  12. http.HandleFunc("/objects/",Handler)
  13. println("server...")
  14. log.Fatal(http.ListenAndServe("127.0.0.1:8006", nil))
  15. }
  16.  
  17. func Handler(w http.ResponseWriter, r *http.Request){
  18. println(r)
  19. m := r.Method
  20. if m == http.MethodPut{
  21. Put(w,r)
  22. return
  23. }
  24. if m == http.MethodGet{
  25. Get(w,r)
  26. return
  27. }
  28. w.WriteHeader(http.StatusMethodNotAllowed)
  29.  
  30. }
  31.  
  32. func Put(w http.ResponseWriter,r *http.Request){
  33. //C:\Users\Administrator\go\src\awesomeProject\test_file
  34. f,e := os.Create(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))
  35.  
  36. if e != nil {
  37. log.Println(e)
  38. w.WriteHeader(http.StatusInternalServerError)
  39. return
  40. }
  41. defer f.Close()
  42. io.Copy(f,r.Body)
  43. }
  44.  
  45. func Get(w http.ResponseWriter,r *http.Request){
  46.  
  47. f,e := os.Open(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))
  48.  
  49. if e != nil {
  50. log.Println(e)
  51. w.WriteHeader(http.StatusNotFound)
  52. return
  53. }
  54. defer f.Close()
  55. io.Copy(w,f)
  56. }

  

详解

main函数,注册一个HTTP处理函数并开始监听端口。

http.HandleFunc的作用是注册HTTP处理函数Handler,如果由客户端访问本机的HTTP服务且以“/objects/”开头,那么请求将由Handler负责处理。

http.ListenAndServer正式监听端口,正常情况下会一直监听,非正常情况下,log.Fatal会对于错误并退出程序。

  1. http.HandleFunc("/objects/",Handler)
  2. println("server...")
  3. log.Fatal(http.ListenAndServe("127.0.0.1:8006", nil))
  1.  

Handler函数,HTTP中最重要的请求和响应Response,Request为参数,根据客户端不同的请求方式,执行不同的处理函数:Put函数与Get函数。

  1. func Handler(w http.ResponseWriter, r *http.Request){
  2. println(r)
  3. m := r.Method
  4. if m == http.MethodPut{
  5. Put(w,r)
  6. return
  7. }
  8. if m == http.MethodGet{
  9. Get(w,r)
  10. return
  11. }
  12. w.WriteHeader(http.StatusMethodNotAllowed)
  13.  
  14. }

Put函数,r.URL变量记录HTTP请求的URL,EscapedPath方法用于获取结果转义以后的路径部分,该路径形式是:/objects/<object_name>,然后strings.Split函数功能是分割/objects/<object_name>,分割为"“、”objects"、<object_name>,去数组的第三个元素就是<object_name>,os.Create在本地文件系统的根存储目录创建同名文件f,创建成功将r.Body用io.Copy写入文件f。

  1. func Put(w http.ResponseWriter,r *http.Request){
  2. //C:\Users\Administrator\go\src\awesomeProject\test_file
  3. f,e := os.Create(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))
  4.  
  5. if e != nil {
  6. log.Println(e)
  7. w.WriteHeader(http.StatusInternalServerError)
  8. return
  9. }
  10. defer f.Close()
  11. io.Copy(f,r.Body)
  12. }

  1. Get函数同Put函数类似。
    此文为分布式对象存储-原理、架构及Go语言实现第一章总结

go语言实现分布式对象存储系统之单体对象存储的更多相关文章

  1. 用asp.net core结合fastdfs打造分布式文件存储系统

    最近被安排开发文件存储微服务,要求是能够通过配置来无缝切换我们公司内部研发的文件存储系统,FastDFS,MongDb GridFS,阿里云OSS,腾讯云OSS等.根据任务紧急度暂时先完成了通过配置来 ...

  2. 淘宝分布式文件存储系统:TFS

    TFS ——分布式文件存储系统 TFS(Taobao File System)是淘宝针对海量非结构化数据存储设计的分布式系统,构筑在普通的Linux机器集群上,可为外部提供高可靠和高并发的存储访问. ...

  3. Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量

    1 第一个OC控制台程序 1.1 问题 Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序.其运行于苹果公司的Mac操作系统下. 本案例要求使用集成 ...

  4. 分布式 Key-Value 存储系统:Cassandra 入门

    Apache Cassandra 是一套开源分布式 Key-Value 存储系统.它最初由 Facebook 开发,用于储存特别大的数据. Cassandra 不是一个数据库,它是一个混合型的非关系的 ...

  5. Swift是一个提供RESTful HTTP接口的对象存储系统

    Swift是一个提供RESTful HTTP接口的对象存储系统,最初起源于Rackspace的Cloud Files,目的是为了提供一个和AWS S3竞争的服务. Swift于2010年开源,是Ope ...

  6. 第二十六节:复习Java语言基础-Java的概述,匿名对象,封装,构造函数

    Java基础 Java语言概述 Java语言 语言 描述 javaee 企业版 javase 标准版 javame 小型版 JDK JDK(Java开发工具包) Java语言 语言 Java语言 Ja ...

  7. 一图看懂hadoop分布式文件存储系统HDFS工作原理

    一图看懂hadoop分布式文件存储系统HDFS工作原理

  8. Swift是一个提供RESTful HTTP接口的对象存储系统,目的是为了提供一个和AWS S3竞争的服务

    Swift是一个提供RESTful HTTP接口的对象存储系统,最初起源于Rackspace的Cloud Files,目的是为了提供一个和AWS S3竞争的服务. Swift于2010年开源,是Ope ...

  9. 腾讯重磅开源分布式NoSQL存储系统DCache

    当你在电商平台秒杀商品或者在社交网络刷热门话题的时候,可以很明显感受到当前网络数据流量的恐怖,几十万商品刚开抢,一秒都不到就售罄:哪个大明星出轨的消息一出现,瞬间阅读与转发次数可以达到上亿.作为终端用 ...

随机推荐

  1. MySQL 5.7和8.0性能测试

    目录 背景 前提 环境 测试 双1模式下 0 2 模式下 结论 背景 测试mysql5.7和mysql8.0 分别在读写.只读.只写模式下不同并发时的性能(tps,qps) 前提 测试使用版本为mys ...

  2. 通过VS2017发布.net core程序并使用Web 部署到远程服务器最新教程

    最近一个项目中,为App开发后台接口,技术选型为最新 .net core版本,使用.net core开发web api接口过程中,为了方便app团队成员直接在线调用接口,找了公网上的一台服务器做为ap ...

  3. Openstack中用keypair生成和访问虚机的方法

    Openstack中用keypair生成和访问虚机的方法 标签:task   iso   perm   cte   生成   复制   vol   rsa   sla Openstack中用镜像文件生 ...

  4. [mysql终极优化]之主从复制与读写分离详细设置教程

    读写分离与主从复制是提升mysql性能的重要及必要手段,大中型管理系统或网站必用之. 一.什么是读写分离与主从复制 先看图 如上图所示,当web server1/2/3要写入数据时,则向mysql d ...

  5. 初探java流操作

    在处理集合时,我们通常会迭代遍历它的元素,并从每个元素上执行某项操作.例如,假设我们想要对某本书中的所有长单词进行计数.首先我们要将所有单词放入一个列表中: String contents = new ...

  6. case和decode的用法(行转列)

    创建了一张成绩表,如下图所示: 在oracle中,这两个函数我们都可以使用,代码及结果如下: decode用法: select Name,decode(Subject,'语文',1,'数学',2,'英 ...

  7. C#使用OLEDB方式读取EXCEL,表的结构

    var tables = con.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { }); Ta ...

  8. 模拟器无Back、Menu等键

    问题如图所示: 解决方法: 1. 打开Android Virtual Device (AVD) Manager --> 选择模拟器,并点击edit --> 勾选KeyBoard中的选项,并 ...

  9. UR机器人通信--上位机通信(python)

    一.通信socket socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: socket.socket([family[, type[, proto]]]) ...

  10. 洛谷P1510 题解

    前言: 其实这道题挺水的,但我居然把ta想成了 贪心 啪啪打脸 好了,废话不多说. 思路: step 1:先翻译以下题意,其实就是求出最多消耗多少体力能把东海填满,如果不能填满,就输出"Im ...