本文主要包括:
- 对象存储学习笔记
一、对象存储基础概念
- 定义与定位
对象存储是专为海量非结构化数据设计的存储范式,以对象为基本存储单元,通过扁平命名空间和RESTful API实现高效管理。- 核心区别:与块存储(低延迟随机访问)、文件存储(树状目录结构)的差异。
- 核心组件
- 对象(Object):包含数据本体、全局唯一ID(如UUID)和元数据(如创建时间、用户标签)。
- 存储桶(Bucket):逻辑容器,用于组织对象,支持跨地域分布式存储。
- 元数据服务器(MDS):管理对象属性和存储位置,优化检索效率。
二、核心架构与技术
- 分布式存储架构
- 数据分布策略:通过一致性哈希或CRUSH算法将对象均匀分布到集群节点,支持动态扩缩容。
- 冗余与容错:多副本(如3副本)或纠删码(如6+3)技术保障数据可靠性,支持跨区域复制。
- 访问协议与接口
- RESTful API:基于HTTP协议,常用操作包括PUT(上传)、GET(下载)、DELETE(删除),支持JSON/XML格式元数据。
- 典型协议:Amazon S3、OpenStack Swift、Ceph RGW等。
三、关键技术特性
- 数据可靠性与可用性
- 持久性机制:通过多副本同步写入和版本控制(如S3版本管理)实现99.999999999%(11个9)的数据可靠性。
- 一致性模型:最终一致性(跨区域场景)与强一致性(同区域操作)的选择策略。
- 扩展性与性能优化
- 水平扩展:无中心节点设计,支持存储容量从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更多用于自建集群的离线计算。
对象存储学习笔记(优化版)
一、对象存储基础认知
核心特点
- 扁平化结构:无目录层级,通过唯一ID(如
bucket-name/object-key
)直接定位数据,适合海量文件管理。 - 元数据丰富:支持自定义元数据(如用户标签、业务属性),便于分类检索。
- RESTful API:标准化接口(如HTTP PUT/GET/DELETE),与编程语言无缝集成。
- 扁平化结构:无目录层级,通过唯一ID(如
与文件存储、块存储对比
特性 对象存储 文件存储 块存储 访问方式 HTTP/HTTPS协议 POSIX协议(如NFS) 直接读写磁盘扇区 典型场景 图片/视频存储、备份 代码仓库、配置文件 数据库、虚拟机磁盘 扩展性 极易扩展(EB级) 中等(依赖服务器性能) 受限于存储设备
二、技术架构深入解析
数据分布与冗余
- 一致性哈希算法:将对象均匀映射到集群节点,扩容时仅迁移少量数据(如Ceph CRUSH算法)。
- 纠删码(EC):将数据分片并生成校验块(如6+3模式),存储开销仅为1.5倍,显著低于副本机制。
元数据管理优化
- 分布式元数据库:将元数据分散存储到多个节点(如AWS S3的DynamoDB设计),避免NameNode单点瓶颈。
- 小文件合并:通过内部封装(如Hadoop Ozone的“文件到对象”转换)减少元数据压力。
三、与HDFS的深度对比
设计目标差异
- 对象存储:为“存储即服务”设计,强调高可用、易扩展和跨平台访问。
- HDFS:为“计算贴近存储”设计,优化大规模批处理任务的本地化读取。
性能关键指标对比
场景 对象存储 HDFS 小文件写入 高吞吐(支持批量上传) 元数据压力大,性能下降明显 大文件读取 延迟较高(需网络传输) 低延迟(数据本地化) 随机修改 不支持(仅追加写) 支持(但需全量重写)
华为OBS使用案例
OBS集成HDFS
- 将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目录下
- 修改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>
- 命令行验证
其他操作就跟操作hdfs几乎一样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
java操作OBS
- 引Maven依赖
<dependency> <groupId>com.huaweicloud</groupId> <artifactId>esdk-obs-java-bundle</artifactId> <version>3.23.9</version> </dependency>
- 编写java代码
注意: 这里查看有哪些桶需要有对应的权限,公司对桶相关的操作权限没有对研发开放。包括创建、list、删除等操作,所以这里报错: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(); } }
查看桶内所有文件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(); }