hadoop 查看文件怎么查看容器containers个数

汉澳sinox快速构建vpn服务器为了让出差的员工电脑登陆...
本教程为 李华明 编著的iOS-Cocos2d游戏开发系列教程:教程涵盖关于i......
专题主要学习DirectX的初级编程入门学习,对Directx11的入门及初学者有......
&面向对象的JavaScript&这一说法多少有些冗余,因为JavaScript 语言本......
Windows7系统专题 无论是升级操作系统、资料备份、加强资料的安全及管......Hadoop2.0介绍_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
Hadoop2.0介绍
最​权​威​的​H​a​d​o​o​p.介​绍​,​讲​述.V​S.之​间​的​不​同​,​由​浅​入​深​的​介​绍​H​a​d​o​o​p.的​新​特​性​。
阅读已结束,如果下载本文需要使用
想免费下载本文?
你可能喜欢转载自: &&/linyc/p/4272060.html
首先用代码来说明NSJSONReadingMutableContainers的作用:
NSString *str = @&{\&name\&:\&kaixuan_166\&}&;
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
// 应用崩溃,不选用NSJSONReadingOptions,则返回的对象是不可变的,NSDictionary
[dict setObject:@&male& forKey:@&sex&];
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
// 没问题,使用NSJSONReadingMutableContainers,则返回的对象是可变的,NSMutableDictionary
[dict setObject:@&male& forKey:@&sex&];
NSLog(@&%@&, dict);
NSJSONReadingMutableContainers:返回可变容器,NSMutableDictionary或NSMutableArray。&
NSJSONReadingMutableLeaves:返回的JSON对象中字符串的值为NSMutableString,目前在iOS 7上测试不好用,应该是个bug,参见:&
NSJSONReadingAllowFragments:允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串。参见:&
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:721051次
积分:11604
积分:11604
排名:第518名
原创:389篇
转载:504篇
评论:49条
(3)(12)(38)(32)(20)(5)(17)(35)(10)(24)(15)(8)(28)(13)(11)(28)(26)(20)(43)(55)(13)(14)(25)(12)(19)(37)(64)(29)(31)(7)(30)(12)(45)(19)(17)(23)(8)(11)(36)1541人阅读
Hadoop 相關的參數非常的多,要怎麼設定才能達到最好的效能是一件令人頭痛的事
本篇是 core-site.xml 的設定及說明
fs.default.name
預設值 : file:///
說明 : 設定 Hadoop namenode 的 hostname 及 port,預設是 Standalone mode,如果是 Pseudo-Distributed mode 要指定為 hdfs://localhost:9000,但是這個缺點是只有在本機才能操作,從其他機器不能連。建議可直接使用 Cluster mode,指定 hdfs://hostname:9000。但是 Hadoop 是依據 hostname 去做 ip binding,所以要注意 /etc/hosts 裡 hostname 不能對應到
127.0.0.1,要對應實際的 ip。
10.1.112.70&&&&&&& hostname
如果發現不能從其他機器連線的話,在 namenode 上用 netstat 看 ip/port mapping 是否正確
tcp&&&&&&& 0&&&&& 0 ::ffff:10.1.112.70:9000&&&& :::*&&&&&&&&&&&&&&&&&&&&&&& LISTEN&&&&& 2691/java
tcp&&&&&&& 0&&&&& 0 ::ffff:10.1.112.70:9000&&&& ::ffff:10.1.112.70:49119&&& ESTABLISHED 2691/java&&&&&&&&&&
tcp&&&&&&& 0&&&&& 0 ::ffff:10.1.112.70:9000&&&& ::ffff:10.1.112.70:49113&&& ESTABLISHED 2691/java
hadoop.tmp.dir
預設值 : /tmp/hadoop-${user.name}
說明 : Hadoop 存放暫存檔案的目錄,會根據 user account 在此目錄下開不同的子目錄。但是放在預設的 /tmp 下可能會有一個問題,一般在 Centos 會 enable tmpwatch,tmpwatch 會定期把 /tmp 下沒用到的檔案砍掉,如果不希望系統做這件事,可以 disable tmpwatch 或把 hadoop.tmp.dir 指到不同的目錄下
fs.checkpoint.dir
預設值 : ${hadoop.tmp.dir}/dfs/namesecondary
說明 : secondary namenode 存放暫存檔案的目錄,如果有多個目錄可用&,“隔開。設定多個目錄的好處是 Hadoop 會把 temp image files 分別寫到指定的多個目錄,以避免其中一份資料壞掉。seconary namenode 相關的設定不一定需要,甚至在 Hadoop cluster 可以不需要起 secondary namenode。但重起 namenode 時也會做 file merge,當檔案很大時,重起的時間會非常的長。為了減少 downtime,建議在
production site 都會啟動 secondary namenode。而且要起在跟 namenode 不同的機器,以保證當 namenode 硬碟壞掉的時候,還可以從 secondary namenode 上把資料備份回來。
fs.checkpoint.period
預設值 : 3600(秒)
說明 : 控制 secondary namenode 的 checkpoint 時間間隔。如果距離上次 checkpoint 的時間大於這個參數設定的值,就會觸發 checkpoint。secondary namenode 會把 namenode 的 fsimage 和 editlog 做 snapshot。如果存取 Hadoop 的次數頻繁或為了減少重起 namenode 的 downtime,可以把這個值設小一點。
fs.checkpoint.size
預設值 : (byte)
說明 : 如果 Hadoop 非常的忙碌,editlog 可能會在短時間內長的很大,fs.checkpoint.period 的設定不見得可以完全預測這個狀況,所以保險的做法會多設定這個值,以保證當檔案大到超過 fs.checkpoint.size 的值也會觸發 checkpoint。
io.file.buffer.size
預設值 : 4096(byte)
說明 : 這是讀寫 sequence file 的 buffer size, 可減少 I/O 次數。在大型的 Hadoop cluster,建議可設定為 65536 到 131072。
ipc.client.connection.maxidletime
預設值 : 10000(毫秒)
說明 : 設定 Hadoop client 連線時最大的閒置時間,預設是 10 秒。如果 Hadoop cluster 的網路連線不穩,可以把這個值設到 60000(60秒)。
ipc.server.tcpnodelay
預設值 : false
說明 : 在 Hadoop server 是否啟動 Nagle’s 演算法。設 true 會 disable 這個演算法,關掉會減少延遲,但是會增加小封包的傳輸。server site 不太需要這定這個值。
ipc.client.tcpnodelay
預設值 : false
說明 : 在 Hadoop client 是否啟動 Nagle’s 演算法。設 true 會 disable 這個演算法,關掉會減少延遲,但是會增加小封包的傳輸。client site 建議把這個值設 true。
hadoop.security.authorization
預設值 : false
說明 : 是不是要開啟 service-level 帳號驗證機制,開啟之後 Hadoop 在執行任何動作之前都會先確認是否有權限。詳細的權限設定會放在 hadoop-policy.xml 裡。例如要讓 fenriswolf 這個 account 及 mapreduce group 可以 submit M/R jobs,要設定 security.job.submission.protocol.acl
&property&
&&&&&&name&security.job.submission.protocol.acl&/name&
&&&&&&value&fenriswolf mapreduce&/value&
&/property&
hadoop.security.authentication
預設值 : simple
說明 : simple 表示沒有 authentication,Hadoop 會用 system account 及 group 來控管權限。另外可以指定為
kerberos,這部分相對比較複雜,要有一個 kerberos server 並產生 account keytab,在執行任何操作前 client 要先用 kinit 指令對 kerberos server 認證,之後的任何操作都是以 kerberos account 來執行。
hadoop.mand
預設值 : N/A
說明 : 如果 hadoop.security.authentication 設為 kerberos 就要多設這個參數指定 Kerberos kinit 指令的路徑。在 CentOS 裝 krb5-workstation package 後預設安裝路徑為 /usr/kerberos/bin/kinit
fs.trash.interval
預設值 : 0(分)
說明 : 清掉垃圾筒的時間。預設是不清, 所以在刪除資料時要自己執行
hadoop fs -rm
-skipTrash
hadoop fs -expunge
來清除垃圾筒的資料,但是強制用 -skipTrash 會造成誤刪的資料救不回來,user 也會常常會忘記做 -expunge 而造成 Hadoop 空間不會釋放。建議可以設為 1440 讓 Hadoop 每天清除垃圾筒。
topology.script.file.name
預設值 : N/A
說明 : 實作 Hadoop Rack Awareness 的機制,指定一個可執行檔,input 會是一組 hostname 或 ip,回傳值是 rack name 清單。不指定的情況下,Hadoop 會預設所有的 node 都在同一個 rack 之下。
以下是一個 python 的範例,不過用 shell script 或其他語言寫也可以
string import
'/dc/rack0';
&&&&'10.1.113.37'
: '/dc/rack1',
&&&&'hadoop-worker01'
: '/dc/rack1',
&&&&'10.1.113.77'
: '/dc/rack1',
&&&&'hadoop-worker02'
: '/dc/rack1',
&&&&'10.1.113.45'
: '/dc/rack2',
&&&&'hadoop-work03'
: '/dc/rack2',
&&&&'10.1.113.48'
: '/dc/rack2',
&&&&'hadoop-work04'
: '/dc/rack2',
len(sys.argv) ==
join([RACK_MAP.get(i, DEFAULT) for
sys.argv[1:]],& &)
如上圖所示,一個非常大的 Hadoop cluster 可能會跨多個 data centers,每個 data center 會有多個 racks,每個 rack 有多個 nodes。假設 Hadoop replication number 設 3,在 Hadoop 做 replication 時會根據這個設定,第一份資料放在 local node,第二份資料放在另一個 rack 的某個 node,第三份資料會放在與第二份同個 rack 但不同的 node 下。當網路設定有問題或斷線時,某一個 rack 可能會全部不見,放在不同的
rack 可以保證仍然能存取到資料。為了增加網路的容錯能力,一般都會設定這個 script。
如果在 cluster 已經有資料的情況下才設定 rack topology,可以用 hadoop balancer 指令讓所有的 blocks 重新分配
topology.script.number.args
預設值 : 100
說明 : 每次傳給 topology.script.file.name script 的參數個數。如果 Hadoop node 個數過多,topology.script.file.name script 會被執行多次,一次傳入 100 個參數
hadoop.native.lib
預設值 : true
說明 : 預設 Hadoop 會去找所有可用的 native libraries 並自動 load 進來使用,例如壓縮類的 libraries 像 GZIP, LZO 等等。會設成 false 的原因通常是為了 debug,Hadoop 會把 native libraries 換成相對應的 java 實作方式來執行,例如 GZIP,以方便使用者檢測 libraries 是否執行錯誤。但是 LZO 這類的 libraries 並沒有 java 實作,所以還是會 call native libraries 來做壓縮,也就沒有
debug 的效果了。詳細的壓縮格式類型會在 mapred-site.xml 的設定時再介紹。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:255146次
积分:3225
积分:3225
排名:第5057名
原创:39篇
转载:197篇
评论:24条
(3)(1)(3)(5)(2)(2)(4)(1)(11)(5)(3)(1)(10)(3)(6)(1)(5)(3)(1)(2)(2)(3)(34)(5)(3)(1)(2)(30)(7)(10)(1)(1)(3)(12)(7)(3)(9)(2)(2)(1)(3)(5)(3)(1)(11)(2)(1)IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
在 Hadoop 中有一个抽象文件系统的概念,它有多个不同的子类实现,由 DistributedFileSystem 类代表的 HDFS 便是其中之一。本文将探讨通过编写 Swift 适配器,将 OpenStack Swift 对象存储作为 Hadoop 的底层存储,为 Hadoop 的存储层增加对 OpenStack Swift 的支持,最终达到功能验证(Functional POC)的目标。本文基于 Hadoop 1.0.4 和 OpenStack Swift 1.7.4。
, Storage Support Specialist,
欧阳帆,IBM 中国系统与科技部的 Storage Support Specialist,他毕业于浙江大学,获得了软件工程硕士学位。他目前的主要工作是参与存储解决方案软件,定制化软件和原型系统的设计、开发和实施工作。除此之外他还是一本 IBM 红皮书的作者之一。
, Advisory IT Architect, IBM
杨奕,IBM 中国系统与技术部的 Advisory IT Architect,他在上海交通大学获得了电子工程硕士学位。他目前的主要工作是为客户设计,定制化,和实施各种高端存储的解决方案。除此之外他还是 CIM 领域的软件专家。你可以通过以下地址联系他:yangyish@。
在 Hadoop 中有一个抽象文件系统的概念,它有多个不同的子类实现,由 DistributedFileSystem 类代表的 HDFS 便是其中之一。在 Hadoop 的 1.x
版本中,HDFS 存在 NameNode 单点故障,并且它是为大文件的流式数据访问而设计的,不适合随机读写大量的小文件。本文将探讨通过使用其他的存储系统,例如 OpenStack Swift 对象存储,作为 Hadoop 的底层存储,为 Hadoop 的存储层增加对 OpenStack Swift 的支持,并给出测试结果,最终达到功能验证(Functional POC)的目标。值得一提的是,为 Hadoop 增加对 OpenStack Swift 的支持并非要取代 HDFS,而是为使用 Hadoop MapReduce 及其相关的工具直接分析存储在 Swift 中的数据提供了方便;本文作为一个阶段性的尝试,目前尚未考虑数据局部性(Data Locality),这部分将作为未来的工作。另外,Hadoop 2.x 提供了高可用 HDFS 的解决办法,不在本文的讨论范围之内。
本文面向的读者为对 Hadoop 和 OpenStack Swift 感兴趣的软件开发者和管理员,并假设读者已经对它们有基本的了解。本文使用的 Hadoop 的版本为
1.0.4,OpenStack Swift 的版本为 1.7.4,Swift Java Client API 的版本为 1.8,用于认证的 Swauth 的版本为
1.0.4。Hadoop 与 OpenStack Swift 对象存储的整合设想以下情形,如果已经在 Swift 中存储了大量数据,但是想要使用 Hadoop 对这些数据进行分析,挖掘出有用的信息。此时可能的做法是,先将 Swift 集群中的数据导出到中间服务器,再将这些数据导入到 HDFS 中,才能通过运行 MapReduce 作业来分析这些数据。如果数据量非常大,那么整个导入数据的过程会很长,并且要使用更多的存储空间。如果能将 Hadoop 和 OpenStack Swift 进行整合,使得 Hadoop 能够直接访问 Swift 对象存储,并能运行 MapReduce 作业来分析存储在 Swift 中的数据,那么将提高效率,减少硬件成本。Hadoop 抽象文件系统 APIorg.apache.hadoop.fs.FileSystem 是 Hadoop
中的一个通用文件系统的抽象基类,它抽象出了文件系统对文件和目录的各种操作,例如:创建、拷贝、移动、重命名、删除文件和目录、读写文件、读写文件元数据等基本的文件系统操作,以及文件系统的一些其他通用操作。FileSystem 抽象类中的主要方法和含义如表 1 所示。表 1. FileSystem 抽象类的主要方法和含义
void initialize(URI, Configuration)
根据配置文件对文件系统进行初始化操作
FSDataInputStream open(Path, int)
打开指定路径的文件,并得到输入流
FSDataOutputStream create(Path, FsPermission, boolean, int, short, long, Progressable)
创建指定路径的文件,并得到输出流
boolean rename(Path, Path)
重命名文件或目录
boolean delete(Path, boolean)
删除文件或目录
boolean mkdirs(Path, FsPermission)
FileStatus getFileStatus(Path)
获得文件或目录的元数据
FileStatus[] listStatus(Path)
获得某个目录下的所有文件或目录的元数据
URI getUri()
获得该文件系统的 URI
Path getWorkingDirectory()
获得当前工作目录
void setWorkingDirectory(Path)
设置当前工作目录
FileSystem 抽象类有多个不同的子类实现,包括:本地文件系统实现、分布式文件系统实现、内存文件系统实现、FTP 文件系统实现、非 Apache 提供的第三方存储系统实现,以及通过 HTTP 和 HTTPS 协议访问分布式文件系统的实现。其中,LocalFileSystem 类代表了进行客户端校验和的本地文件系统,在未对 Hadoop 进行配置时是默认的文件系统。分布式文件系统实现是 DistributedFileSystem 类,即 HDFS,用来存储海量数据,典型的应用是存储大小超过了单台机器的磁盘总容量的大数据集。第三方存储系统实现是由非 Apache 的其他厂商提供的开源实现,如 S3FileSystem 和 NativeS3FileSystem 类,它们是使用 Amazon S3 作为底层存储的文件系统实现。通过阅读 Hadoop 的文件系统相关的源代码和 Javadoc,并借助于工具,可以分析出 FileSystem 抽象类的各个抽象方法的含义和用法,以及 FileSystem API 中各类之间的继承、依赖关系。org.apache.hadoop.fs 包中包括了 Hadoop 文件系统相关的接口和类,如文件输入流 FSDataInputStream 类和输出流 FSDataOutputStream 类,文件元数据 FileStatus 类,所有的输入/输出流类都分别和 FSDataInputStream 类和 FSDataOutputStream 类是组合关系,所有的文件系统子类实现均继承自 FileSystem 抽象类。Hadoop FileSystem API 的类图如图 1 所示。图 1. Hadoop FileSystem API 类图以 S3FileSystem 为例,它使用的底层存储系统是 Amazon S3,继承了 FileSystem 抽象类,是它的一个具体实现,并实现了针对 Amazon S3 的输入/输出流。用户可以在 Hadoop 的配置文件 core-site.xml 中为 fs.default.name 属性指定 Amazon S3 存储系统的 URI,就可以使 Hadoop 得以访问 Amazon S3,并在其上运行 MapReduce 作业。Swift 的 Java 客户端 APISwift 通过 HTTP 协议对外提供存储服务,有一个 REST 风格的 API。Swift 本身是用 Python 语言实现的,但是也提供了多种编程语言的客户端 API,例如:Python、Java、PHP、C#、Ruby 等。这些客户端 API 都通过发起 HTTP 请求和接收 HTTP 响应来与 Swift 集群的代理节点进行交互,Swift 客户端 API 在 REST API 之上提供了更高层次的对容器和对象的操作,使得程序员编写访问 Swift 的程序变得更为方便。Swift 的 Java 客户端 API 名叫 java-cloudfiles,也是一个开源项目。其中的 FilesClient 类提供了对 Swift
对象存储的各种操作,包括:登录 Swift、创建和删除 Account、容器、对象,获得 Account、容器、对象的元数据,以及读写对象的方法。其他相关的类包括:FilesContainer、FilesObject、FilesContainerInfo、FilesObjectMetaData 等,它们分别代表 Swift 中的容器和对象以及对应的元数据,如容器包含的对象个数,对象的大小、修改时间等。版本号为 1.8 的 java-cloudfiles 能够和开源版本的 Swift 兼容。Filesclient 类中主要的方法和含义如表 2 所示。表 2. FilesClient 类中的主要方法和含义
FilesClient(String, String, String, String, int)
构造方法,参数包括代理节点的 URL、account、username、password,timeout
boolean login()
登录 Swift
void createContainer(String)
boolean deleteContainer(String)
boolean containerExists (String)
判断容器是否存在
boolean storeObject(String, byte[], String, String, Map&String,String&)
把字节数组中的值存储到对象中,把元数据存储到扩展属性中
byte[] getObject (String, String)
从 Swift 获取对象内容并存入字节数组
List&FilesContainer& listContainers()
列出某个账户包含的所有容器
List&FilesObject& listObjects(String)
列出某个容器包含的所有对象
FilesContainerInfo getContainerInfo (String)
获取容器的元数据
FilesObjectMetaData getObjectMetaData (String, String)
获取对象的元数据
综上所述,Hadoop FileSystem API 能够接受新的文件系统实现的机制,以及能够用 Java 语言编写应用程序与 Swift 进行交互操作,这两点使得扩展 Hadoop 抽象文件系统是可行的。Swift 适配器的设计由上述内容得知,要扩展 Hadoop 的抽象文件系统,需要做以下两项工作:继承并实现 FileSystem 抽象类,并在实现类中使用 Swift 的 Java 客户端 API 以进行各种文件操作。因此,扩展系统的设计应遵循软件设计模式当中的对象适配器模式(Adapter Pattern)。对象适配器模式的作用是进行接口适配,就是将一个类的接口转换成客户程序希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。在扩展系统中,Swift 适配器调用 Swift 的 Java 客户端 API,实现了对 Swift 对象存储的操作,Hadoop MapReduce API 调用 Hadoop FileSystem API,对于 MapReduce 来说,底层的 HDFS 和 Swift 都是透明的。与 HDFS 相比,Swift 适配器所在的 API 层次结构如图 2 所示。图 2. API 层次结构图Swift 适配器的详细设计如下:SwiftAdapter 是一个适配器类,FilesClient 是一个被适配类,SwiftAdapter 类继承了 FileSystem 抽象类,它和 FilesClient 类是组合关系,包含了 FilesClient 类的一个引用。其中,FilesClient 类是 Swift 的 Java 客户端 API 中的一个类。Swift 输入/输出流如下:SwiftInputStream 是针对 Swift 的输入流,SwiftByteArrayInputStream 是一个包含字节数组缓存的输入流,SwiftInputStream 包含了 SwiftByteArrayInputStream 的一个引用,SwiftOutputStream 是针对 Swift 的输出流,它们继承了相应的文件系统输入/输出流基类或接口,输入流具有 seek 等功能,输出流具有 flush 等功能。Swift 适配器中的类图如图 3 所示,Swift 适配器中类的详细关系如表 3 所示。图 3. Swift 适配器类图表 3. Swift 适配器中类的详细关系
父接口/父类
SwiftAdapter
FileSystem
FilesClient, SwiftInputStream, SwiftOutputStream 等
SwiftInputStream
FSInputStream
FilesClient, SwiftByteArrayInputStream
SwiftByteArrayInputStream
ByteArrayInputStream, Seekable
SwiftByteOutputStream
ByteArrayOutputStream
FilesClient
SwiftFileStatus(SwiftAdapter 的内部类)
FileStatus
Swift 适配器的实现实现细节在与 Swift 进行交互之前需要首先登录 Swift,因此要使用 Swift 中预先创建的某个账户、用户名和密码,实现的细节如下。调用 Swift 的 Java 客户端 API,实现针对 Swift 的输入/输出流。在 Hadoop 中,所有的输入流类都需要继承并实现 FSInputStream 抽象类,重点是实现 read 方法和 seek 方法。read 方法从输入流中读取下一个字节,是输入流类最基本的方法,seek 方法设置输入流的读取位置,如果使用一个字节数组作为缓冲则能实现随机定位到某一字节。SwiftByteArrayInputStream 类继承了 ByteArrayInputStream 类和 Seekable 接口,它使用了一个字节数组作为缓冲。SwiftInputStream 类继承 FSInputStream 抽象类,并包含 SwiftByteArrayInputStream 类的一个引用,它调用 Swift 的 Java 客户端 API,将 Swift 中的对象读入到字节数组的缓冲。通过这样的实现,针对 Swift 的输入流类 SwiftInputStream 就具有了 read 和 seek 这些输入流的基本操作。在 Hadoop 中,输出流类只需要是 OutputStream 抽象类的子类即可,重点是实现 write 方法和 flush 方法,它可以选择是否实现 Syncable 接口的 sync 方法,sync 方法使得缓冲的数据与底层存储设备同步。write 方法向输出流中写入一个字节,是输出流类最基本的方法。SwiftOutputStream 类继承了 OutputStream 抽象类的子类 ByteArrayOutputStream,在 flush 方法中调用 Swift 的 Java 客户端 API,将缓冲中的所有字节存储到 Swift 中的对象。通过这样的实现,针对 Swift 的输出流类 SwiftOutputStream 就具有了 write 和 flush 这些输出流的基本操作。调用 Swift 的 Java 客户端 API,实现 SwiftAdapter 的各种文件操作。实现的操作包括:打开文件并返回输入流,创建文件并返回输出流,删除路径,判断路径是否存在,获得路径的元数据,获得文件系统的 URI,获得工作目录,创建目录等等。目录对应 Swift 中的容器,文件对应 Swift 中的对象。在实现的过程中,有几个问题需要进行特殊处理。首先,由于在 Swift 对象存储中,名称空间是扁平的,没有目录层次结构,所以在路径上需要进行特殊处理,具体的做法是允许文件名称包含斜杠(/)。在一般的 POSIX 兼容的文件系统中,斜杠不能作为文件名的一部分,属于非法字符,而在 Swift 中是允许的。通过这种方式,可以实现虚拟的目录层次结构。此时,根路径作为容器的名称,根目录之后的整个路径都作为对象的名称。其次,由于 Swift 对象存储不是一个真正的文件系统,与一般的文件系统不同,不包含用户、用户组以及其他使用者的可读、可写、可执行的权限信息,所以在权限上需要进行特殊处理,具体的做法是将这些权限信息存储在对象的扩展属性中。FilesClient 类的 storeObject 方法有一个 java.util.Map 类型的参数,可以把用户、用户组以及其他使用者的权限信息作为 java.util.Map 对象中的元素,以代表权限类型的字符串作为键,以权限对应的数字作为值,例如用户、用户组以及其他使用者的权限信息分别为&"Acl-User", "6"&、&"Acl-Group", "4"&、&"Acl-Others", "4"&。把包含权限信息的 java.util.Map 对象作为参数传递给 storeObject 方法,就可以将权限信息存储到扩展属性中了。SwiftAdapter 类中接口转换的对应关系如表 4 所示,分别列出了 SwiftAdapter 类与 FilesClient 类的方法之间的对应关系。表 4. SwiftAdapter 类中接口转换的对应关系
SwiftAdapter 类的方法
FilesClient 类被转换的方法
initialize
调用 FilesClient 类的构造方法,初始化 FilesClient 类的实例
getObject 返回的字节数组作为 SwiftInputStream 中的缓冲存储
storeObject 将 SwiftOutputStream 中缓冲存储中的字节保存到 Swift 的对象中
不支持此操作
deleteObject, storeObject
目录对应 deleteObject 和 deleteContainer,文件对应 deleteObject
createContainer,storeObject
getFileStatus
目录对应 getContainerInfo, 文件对应 getObjectMetaData
initialize
调用 FilesClient 类的构造方法,初始化 FilesClient 类的实例
getObject 返回的字节数组作为 SwiftInputStream 中的缓冲存储
storeObject 将 SwiftOutputStream 中缓冲存储中的字节保存到 Swift 的对象中
编译源代码并打包成 JAR 文件,再将 JAR 文件及其依赖的类库部署到 Hadoop 集群中所有节点的$HADOOP_PREFIX/share/hadoop/lib 目录中。使用 RPM 文件安装的 Hadoop 的类库默认目录是/usr/share/hadoop/lib。这就像将插件安装到 Hadoop 中一样,没有对原有软件进行修改。修改 Hadoop 集群中所有节点的配置文件 core-site.xml,使文件系统的 URI 指向 Swift 的代理节点,并指定 Swift 中的某个 Account、用户名和密码。这些属性会被 Swift 适配器读取。在 Swift 集群中部署多台代理节点,还可以使用专门的负载均衡器(Load Balancer)或轮转 DNS(Round-robin DNS)指向这些代理节点,并在 core-site.xml 中使文件系统的 URI 指向负载均衡器或轮转 DNS。配置文件 core-site.xml 的属性如表 5 所示。表 5. 配置文件 core-site.xml 的属性
fs.default.name
swift://proxy.swiftcluster.net:8080
proxy.swiftcluster.net 是预先设置的轮转 DNS 的域名
fs.swift.impl
swift.SwiftAdapter
完整的类名
fs.swift.account
AUTH_66-407e-b5e3-0bec4fdbfc71
Swift 中的一个 Account 名称
fs.swift.username
Swift 中的一个用户名
fs.swift.password
上述用户名对应的密码
fs.swift.auth.url
http://proxy.swiftcluster.net:8080/auth
认证服务器的 URL,此处使用 Swauth
拓扑结构Hadoop 集群中部署了 1 台 JobTracker 节点,以及多台运行 TaskTracker 的 slave 节点,所有节点均加入了 Swift 适配器 JAR 文件及其依赖的类库。Swift 集群中部署了多个 Proxy 节点和 Storage 节点,并且部署了 1 台轮转 DNS 服务器,它指向这些 Swift 集群中的代理节点。整个扩展系统的拓扑结构如图 4 所示。图 4. 扩展系统拓扑结构图流程在 Swift 适配器中,以初始化文件系统实例、打开文件并读取数据、以及创建文件并写入数据的操作为例,分别叙述它们的流程,并使用 UML 时序图展示出来。Hadoop 的文件系统客户端命令行程序对应的是 org.apache.hadoop.fs.FsShell 类。在使用该命令行程序与文件系统进行交互的时候,Hadoop 首先会根据配置文件中指定的 scheme 寻找对应的文件系统实现类,并进行初始化操作。org.apache.hadoop.fs.FileSystem 类有一个静态内部类 FileSystem.Cache,它使用一个 Java 的 Map 类型缓存了文件系统的实例对象,键是文件系统的 scheme 名称,例如”hdfs”,值是对应的文件系统对象实例,例如 DistributedFileSystem 类的实例。在本文的实现中,Swift 适配器的 scheme 名称是”swift”,对应的文件系统类是 swift.SwiftAdapter,并且在配置文件中设置属性 fs.swift.impl 为 swift.SwiftAdapter。初始化文件系统实例的详细流程如下:如果名称为”swift”的 scheme 存在于该缓存中,则 FileSystem.Cache 直接通过 get 方法返回 swift.SwiftAdapter 的对象实例。否则,FileSystem 类调用静态方法 createFileSystem,接着调用 ReflectionUtils 类的 newInstance 方法,最终调用 Constructor 类的 newInstance 方法,以反射的方式获得 Swift 适配器类的对象实例,最后调用 initialize 方法进行必要的初始化操作。初始化文件系统实例的 UML 时序图如图 5 所示。图 5. 初始化文件系统实例的 UML 时序图打开文件并读取数据的详细流程如下:在打开文件的时候,客户程序调用 SwiftAdapter 类的 open 方法,SwiftAdapter 对象首先初始化 Swift 输入流类 SwiftInputStream 的实例,然后 SwiftInputStream 对象会调用 FilesClient 对象的 getObject 方法向 Swift 集群中的代理服务器发起 HTTP 请求获取 Swift 中的对象,把数据存入 SwiftByteArrayInputStream 对象内部的字节数组缓冲中,之后客户端程序调用 SwiftInputStream 对象的 read 方法读取缓冲存储中的字节,读取数据的操作完成之后再调用 close 方法关闭 Swift 输入流。打开文件并读取数据的 UML 时序图如图 6 所示。图 6. 打开文件并读取数据的 UML 时序图创建文件并写入数据的详细流程如下:在创建文件的时候,客户程序调用 SwiftAdapter 类的 create 方法,SwiftAdapter 对象首先初始化 Swift 输出流类 SwiftOutputStream 的实例,然后客户程序调用 SwiftOutputStream 对象的 write 方法把数据写入到它内部的字节数组缓冲中,直到调用它的 flush 方法或 close 方法,SwiftOutputStream 对象才会调用 FilesClient 对象的 storeObject 方法,向 Swift 集群中的代理服务器发起 HTTP 请求将缓冲存储中的字节写入 Swift 中的对象。创建文件并写入数据的 UML 时序图如图 7 所示。图 7. 创建文件并写入数据的 UML 时序图未来的工作通过 Swift 适配器,将高可用的 Swift 对象存储作为 Hadoop 的底层存储系统,使得 Hadoop 在存储层面具有了高可用性。把 Swift 适配器部署到已有的 Hadoop 集群中是简单快捷的。原本用来分析存储在 HDFS 中的数据的 MapReduce 应用程序,也无需修改即可分析存储在 Swift 中的数据。但是,使用 Swift 适配器将 Hadoop 与 Swift 对象存储整合之后,整个系统的缺点是失去了数据局部性(Data Locality)的优势。在 HDFS 中,NameNode 节点知道每一个文件块存储在哪一个 DataNode 节点上。因此在运行 MapReduce 作业的过程中,用户编写的 MapReduce 应用程序的二进制文件会被 MapReduce 框架调度发送至尽可能离数据最近的节点,最好的情况是在文件块所在的 DataNode 节点上的 TaskTracker 进程启动 Map 任务,此时 Map 任务从本地文件系统读取输入文件,这样可以避免大量的数据在 Hadoop 集群的不同节点之间传输,节省了网络带宽,也能加速 MapReduce 作业在 map 阶段的运行速度。通过 Swift 适配器,将 Swift 对象存储作为 Hadoop 的底层存储系统,对 Hadoop 集群来说,Swift 是一个外部存储系统,TaskTracker 和文件不在同一个节点上,因此在 MapReduce 作业运行的 map 阶段,所有的读取文件操作都通过网络传输数据。Swift 对象存储对于 Hadoop 集群来说是一个黑盒,MapReduce 框架无法知道存储系统的内部细节。本文的目的是为 Hadoop 的存储层增加对 OpenStack Swift 的支持,并非要取代 HDFS。作为一个阶段性的尝试,目前并未考虑和解决数据局部性的问题,这部分将作为未来的工作。测试结果Swift 适配器使得 Swift 对象存储可以作为 Hadoop 的底层存储系统,实现的效果包括两个方面:第一,使用 Hadoop 的文件系统命令行访问 Swift 对象存储。第二,运行 MapReduce 作业分析存储在 Swift 中的数据。使用 Hadoop 的文件系统命令行访问 Swift 对象存储ls 列出某个目录下的文件,在实现时未读取文件的实际修改时间,因此默认为 。如图所示。cat 查看某个文件的内容,如图所示。mkdir 创建目录,如创建成功则无提示信息,否则提示该目录已存在的信息,如图所示。put 将本地文件存入 Swift 对象存储中,如操作成功则无提示信息,如图所示。get 将 Swift 对象存储中的对象存到本地文件中,如操作成功则无提示信息,如图所示。rm, rmr 前者删除文件,后者级联删除目录,操作不论成功与否都有提示信息,如图所示。du 显示某个目录下的目录和文件的大小,即字节长度,如图所示。运行 MapReduce 作业分析存储在 Swift 中的数据首先在 Hadoop 集群中提交一个 MapReduce 作业,然后通过如下 URL 访问 JobTracker 节点的 MapReduce 管理的页面:http://&jobtracker-ip-address&:50030/jobtracker.jsp,点击具体的作业链接进入查看运行结果的页面,从页面上的文件 Scheme(swift://)可以看出 Hadoop 已经在 Swift 对象存储之上运行 MapReduce 作业了,运行结果页面如图 8 所示。图 8. 在 Swift 对象存储之上运行 MapReduce
作业示例图总结本文分析了 Hadoop FileSystem API 和 Swift Java client API,以及 Hadoop 与 OpenStack Swift 整合的可行性,介绍了 Swift 适配器的设计和实现细节,最终将 OpenStack Swift 对象存储作为 Hadoop 的底层存储,使得它们能够协同工作,为 Hadoop 的存储层增加了对 OpenStack Swift 的支持。
参考资料 :这里有介绍 Hadoop 1.0.4 的在线文档和 Javadoc。:这里有介绍 OpenStack Swift 对象存储的在线文档。:这里提供了 OpenStack Swift 的 Java 客户端 API 的文档和源代码。:这里提供了 Swauth 认证服务器的文档和源代码、二进制文件。:本文介绍了软件设计模式中的适配器模式。:这是 Java 代码分析工具 Relo 的网站首页,提供了关于 Relo 的有用信息。 提供了有关云计算的更新资源,包括
云计算 。更新的 ,让您的开发变得轻松, 帮助您成为高效的云开发人员。连接转为云计算设计的 。关于
的活动聚合。加入 。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
IBM PureSystems(TM) 系列解决方案是一个专家集成系统
通过学习路线图系统掌握软件开发技能
软件下载、试用版及云计算
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Cloud computingArticleID=961253ArticleTitle=为 Hadoop 的存储层增加对 OpenStack Swift 的支持publish-date=}

我要回帖

更多关于 hadoop 版本查看 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信