0%

对象存储学习笔记

本文主要包括:

  • 对象存储学习笔记

一、对象存储基础概念

  1. 定义与定位
    对象存储是专为海量非结构化数据设计的存储范式,以对象为基本存储单元,通过扁平命名空间和RESTful API实现高效管理。
    • 核心区别:与块存储(低延迟随机访问)、文件存储(树状目录结构)的差异。
  2. 核心组件
    • 对象(Object):包含数据本体、全局唯一ID(如UUID)和元数据(如创建时间、用户标签)。
    • 存储桶(Bucket):逻辑容器,用于组织对象,支持跨地域分布式存储。
    • 元数据服务器(MDS):管理对象属性和存储位置,优化检索效率。

二、核心架构与技术

  1. 分布式存储架构
    • 数据分布策略:通过一致性哈希或CRUSH算法将对象均匀分布到集群节点,支持动态扩缩容。
    • 冗余与容错:多副本(如3副本)或纠删码(如6+3)技术保障数据可靠性,支持跨区域复制。
  2. 访问协议与接口
    • RESTful API:基于HTTP协议,常用操作包括PUT(上传)、GET(下载)、DELETE(删除),支持JSON/XML格式元数据。
    • 典型协议:Amazon S3、OpenStack Swift、Ceph RGW等。

三、关键技术特性

  1. 数据可靠性与可用性
    • 持久性机制:通过多副本同步写入和版本控制(如S3版本管理)实现99.999999999%(11个9)的数据可靠性。
    • 一致性模型:最终一致性(跨区域场景)与强一致性(同区域操作)的选择策略。
  2. 扩展性与性能优化
    • 水平扩展:无中心节点设计,支持存储容量从TB到EB级无缝扩展。
    • 高并发处理:分布式架构支持数万级QPS并发访问,适合视频流、大数据分析等场景。

四、与HDFS的核心区别

维度 对象存储 HDFS
数据模型 以“对象”为基本单元,包含数据、元数据和唯一ID,无目录层级。 以“文件+目录”为结构,支持树状层级命名空间。
访问接口 基于RESTful API(如S3协议),支持HTTP/HTTPS协议直接访问。 基于HDFS API和命令行(如hdfs dfs),需通过Hadoop生态访问。
元数据管理 元数据分布式存储,支持海量小文件,无单点瓶颈。 依赖NameNode集中管理元数据,小文件场景下元数据膨胀易导致性能下降。
存储效率 支持纠删码(EC)技术,存储开销可低至1.2倍(如10+2模式),适合冷数据归档。 默认3副本存储,存储开销3倍,小文件场景下冗余效率更低。
扩展性 支持水平扩展,可通过增加节点无缝扩容,适合超大规模数据(如EB级)。 扩展性受限于NameNode内存,大规模集群需复杂高可用方案。
典型场景 海量小文件存储、实时数据访问、云原生数据湖。 大文件批量处理、离线数据分析(如MapReduce/Spark作业)。

补充说明

  • 对象存储更适合“一次写入、多次读取”的场景,而HDFS在需要频繁修改数据的场景中表现更优。
  • 云厂商对象存储(如AWS S3、阿里云OSS)已深度集成计算框架(如Spark),可直接作为数据湖底座,而HDFS更多用于自建集群的离线计算。

对象存储学习笔记(优化版)

一、对象存储基础认知

  1. 核心特点

    • 扁平化结构:无目录层级,通过唯一ID(如bucket-name/object-key)直接定位数据,适合海量文件管理。
    • 元数据丰富:支持自定义元数据(如用户标签、业务属性),便于分类检索。
    • RESTful API:标准化接口(如HTTP PUT/GET/DELETE),与编程语言无缝集成。
  2. 与文件存储、块存储对比

    特性 对象存储 文件存储 块存储
    访问方式 HTTP/HTTPS协议 POSIX协议(如NFS) 直接读写磁盘扇区
    典型场景 图片/视频存储、备份 代码仓库、配置文件 数据库、虚拟机磁盘
    扩展性 极易扩展(EB级) 中等(依赖服务器性能) 受限于存储设备

二、技术架构深入解析

  1. 数据分布与冗余

    • 一致性哈希算法:将对象均匀映射到集群节点,扩容时仅迁移少量数据(如Ceph CRUSH算法)。
    • 纠删码(EC):将数据分片并生成校验块(如6+3模式),存储开销仅为1.5倍,显著低于副本机制。
  2. 元数据管理优化

    • 分布式元数据库:将元数据分散存储到多个节点(如AWS S3的DynamoDB设计),避免NameNode单点瓶颈。
    • 小文件合并:通过内部封装(如Hadoop Ozone的“文件到对象”转换)减少元数据压力。

三、与HDFS的深度对比

  1. 设计目标差异

    • 对象存储:为“存储即服务”设计,强调高可用、易扩展和跨平台访问。
    • HDFS:为“计算贴近存储”设计,优化大规模批处理任务的本地化读取。
  2. 性能关键指标对比

    场景 对象存储 HDFS
    小文件写入 高吞吐(支持批量上传) 元数据压力大,性能下降明显
    大文件读取 延迟较高(需网络传输) 低延迟(数据本地化)
    随机修改 不支持(仅追加写) 支持(但需全量重写)

华为OBS使用案例

OBS集成HDFS

  1. 将hadoop-huaweicloud-x.x.x-hw-y.jar拷贝到/opt/hadoop-3.1.1/share/hadoop/tools/lib和/opt/hadoop-3.1.1/share/hadoop/common/lib目录下
  2. 修改core-site.xml
    <property>
       <name>fs.obs.impl</name>
       <value>org.apache.hadoop.fs.obs.OBSFileSystem</value>
    </property>
    <property>
        <name>fs.AbstractFileSystem.obs.impl</name>
        <value>org.apache.hadoop.fs.obs.OBS</value>
    </property>
    <property>
          <name>fs.obs.access.key</name>
        <value>xxx</value>
        <description>HuaweiCloud Access Key Id</description>
    </property>
    <property>
        <name>fs.obs.secret.key</name>
        <value>xxx</value>
        <description>HuaweiCloud Secret Access Key</description>
    </property>
    <property>
        <name>fs.obs.endpoint</name>
        <value>xxx</value>
        <description>HuaweiCloud Endpoint</description>
    </property>
  3. 命令行验证
    hadoop fs -ls obs://ddp-data-test/
    hdfs dfs -put hdfs_results.json obs://ddp-data-test/
    hadoop fs -rm -r -skipTrash obs://ddp-data-test/hdfs_results.json
    其他操作就跟操作hdfs几乎一样

java操作OBS

  1. 引Maven依赖
    <dependency>
        <groupId>com.huaweicloud</groupId>
        <artifactId>esdk-obs-java-bundle</artifactId>
        <version>3.23.9</version>
    </dependency>
  2. 编写java代码
    public class OBSTest {
        private static final String endPoint = "https://obs.cn-east-3.myhuaweicloud.com";
        private static final String sk = "4wWNf8m6LcBd7jIogzdqflnJuhSDYkJCMpqZiT4N";
        private static final String ak = "HPUAM0ZGYOUITOSPWCLY";
        private static ObsClient obsClient;
        private static String bucketName = "digiwinbigdadta";
        public static void main(String[] args) throws IOException {
            ObsConfiguration config = new ObsConfiguration();
            config.setSocketTimeout(30000);
            config.setConnectionTimeout(10000);
            config.setEndPoint(endPoint);
    
    
            obsClient = new ObsClient(ak, sk, config);
            obsClient = new ObsClient(ak, sk, config);
            ListBucketsRequest request = new ListBucketsRequest();
            request.setQueryLocation(true); // 可选:是否查询桶的区域位置
    
            List<ObsBucket> obsBuckets = obsClient.listBuckets(request);
    
            // 打印桶信息
            for (ObsBucket bucket : obsBuckets) {
                System.out.println("Bucket名称: " + bucket.getBucketName());
                System.out.println("桶类型: " + bucket.getBucketType());
                System.out.println("存储类别: " + bucket.getStorageClass());
                System.out.println("创建时间: " + bucket.getCreationDate());
                System.out.println("----------------------");
            }
    
            // 关闭客户端
            obsClient.close();
        }
    }
    注意: 这里查看有哪些桶需要有对应的权限,公司对桶相关的操作权限没有对研发开放。包括创建、list、删除等操作,所以这里报错:
    Error message:Request Error.OBS service Error Message. -- ResponseCode: 403, ResponseStatus: Forbidden,
    查看桶内所有文件
    obsClient = new ObsClient(ak, sk, config);
    obsClient = new ObsClient(ak, sk, config);
    obsClient.listObjects(new ListObjectsRequest(bucketName));
    ObjectListing objectListing;
    
    System.out.println("List objects using default parameters:\n");
    objectListing = obsClient.listObjects(bucketName);
    for (ObsObject object : objectListing.getObjects()) {
        System.out.println("\t" + object.getObjectKey() + " etag[" + object.getMetadata().getEtag() + "]");
    }
    查看指定路径下文件/文件夹,类似hdfs dfs -ls obs://ddp-data-test/
    String path = ""; // 留空表示当前路径,或设置为具体路径(如"subdir/")
    // 构造ListObjects请求
    ListObjectsRequest request = new ListObjectsRequest();
    request.setBucketName(bucketName);
    request.setDelimiter("/"); // 关键:仅列举当前层级的文件夹
    request.setPrefix(path);   // 可选:限制路径(如"subdir/")
    try {
        // 执行请求
        ObjectListing objectListing = obsClient.listObjects(request);
        // 打印当前层级的文件夹路径
        System.out.println("Folders:");
        for (String prefix : objectListing.getCommonPrefixes()) {
            System.out.println(prefix); // 输出类似 "subdir1/"、"subdir2/"
        }
        // 打印当前层级的文件
        System.out.println("\nFiles:");
        for (ObsObject obj : objectListing.getObjects()) {
            System.out.println(obj.getObjectKey()); // 输出文件名(不含路径)
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 关闭客户端
        obsClient.close();
    }