|
发表于 2014-1-18 01:52:02
|
显示全部楼层
还有人这样说:Hadoop不适合大量小文件存储的证实
今天应邀测试。由于带宽影响,先测试上传小文件的性能。
发现上传一 252 字节的文件,当连接数不到50时,最高每秒能写入约300个文件。
Hadoop默认的块大小为64MB,由于本次测试为小文件。特此将块大小修改为512KB。
测试结果:
当连接数增多时,NameNode性能显著下降。使用iostat可以看到磁盘队列偶尔飙得老高,磁盘使用率接近100%。
随即查看系统资源使用情况:
Hadoop的存储性能
附测试代码如下:
- import java.io.*;
- import java.util.UUID;
- import java.net.URI;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.fs.*;
- import lrapi.lr;
- public class Actions{
- public static FileSystem fs;
- public int init() throws Throwable{
- fs=FileSystem.get(new URI("hdfs://192.168.10.31:9000"),new Configuration());
- return 0;
- }//end of init
- public int action() throws Throwable{
- lr.start_transaction("WirteFile");
- String fileName=UUID.randomUUID().toString().replace("-","");
- String dirName=fileName.substring(0,2);
- writeFile("/test/"+dirName+"/"+fileName
- ,"c:/monitor/clear.bat");
-
- lr.end_transaction("WirteFile",lr.AUTO);
- return 0;
- }//end of action
- public static boolean writeFile(String hdfsPath,String localFile){
- try{
- Filefile=new File(localFile);
- BufferedInputStream inputStream=new BufferedInputStream(new FileInputStream(file));
- Path hdfsPathDir=new Path(hdfsPath);
- if(!fs.exists(hdfsPathDir.getParent()))
- fs.mkdirs(hdfsPathDir.getParent());
- FSDataOutputStream out = fs.create(hdfsPathDir,true);
- int len;
- byte[] data=new byte[2048];
- while((len=inputStream.read(data))!=-1){
- out.write(data,0,len);
- }
- out.flush();
- out.close();
- inputStream.close();
- }catch (Exceptione) {
- e.printStackTrace();
- return false;
- }
- return true;
- }
- public int end() throws Throwable{
- fs.close();
- return 0;
- }//end of end
- }
复制代码
只需附加 commons-logging-1.0.4.jar 、 hadoop-0.20.2-core.jar 资源。
从IO写入次数可看出,写次数非常高。而且写次数速度和每秒上传的速度基本是相当的,并未进行有效的合并写入。也就是说Hadoop对小文件的写入没有作任何优化,至此即可证明Hadoop不适合大量小文件的存储。存储类产品多少都存在小文件的优化问题,小文件需要更新更多的源信息,需要更多的IO操作。
(注:写入Hadoop的文件名为UUID,文件存入在以UUID首两个字母的子文件夹中。避免单文件数量过多时对性能的影响)
|
|