从 Alluxio 使用 Spark java 读取多个文件很慢
Read multiple files with Spark java from Alluxio is slow
我已经用Spark在本地安装了Alluxio,我已经在Alluxio的内存中插入了1000个文件。
不过读取文件很慢。
从 Alluxio 内存读取文件的时间等于从磁盘读取文件的时间。
我不明白为什么。
File Name Size Block Size In-Memory Persistence State Pin Creation Time Modification Time
file1 54.73KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:278 08-16-2016 12:52:31:372
file2 54.73KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:377 08-16-2016 12:52:31:384
file3 54.72KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:386 08-16-2016 12:52:31:393
file4 54.71KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:394 08-16-2016 12:52:31:400
file5 54.72KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:401 08-16-2016 12:52:31:407
...
我用文件 API 读取数据:
FileSystem fs = FileSystem.Factory.get();
AlluxioURI path = new AlluxioURI(/partition0);
List<URIStatus> status = fs.listStatus(path);
for (int i=0; i<status.size(); i++)
{
path = new AlluxioURI(status.get(i).getPath());
if(fs.exists(path)==true)
{
FileInStream in = fs.openFile(path);
String file = "";
InputStreamReader ipsr = new InputStreamReader(in);
BufferedReader br=new BufferedReader(ipsr);
String line;
line=br.readLine();
while (line != null){
//System.out.println(line);
file = file + line;
line=br.readLine();
}
byte[] cfv = file.getBytes();
br.close();
// Close file relinquishing the lock
in.close();
}
}
我暂时不用Spark,因为测试读取1000个文件的分区很慢...(以后想用Spark按分区读取文件)
为什么用这个 method/library 读取时间这么慢?
您的示例中有几处看起来有点不对劲。
首先,您在文件中显示的信息表明这些文件非常小,每个大约 50 kB,但您将 Alluxio 配置为使用 512 MB 块。这可能意味着您正在 运行 提供比实际需要更多的数据。所以要考虑的一件事是,如果你打算主要有小文件,你最好配置一个小得多的块大小。
其次,您在测试用例中实际读取文件的方式非常低效。您正在逐行读取字符串,使用字符串连接来构建文件,然后将其转换回字节。所以你要从内存中的字节到字符串,然后再回到字节。另外,通过使用字符串连接,您可以强制将到目前为止读取的整个文件复制到您读取的内存技术附加行中。
通常,您要么将文件逐行读入 StringBuilder
/ 写入另一个 Writer
,要么将文件作为字节读入 byte[]
/ 写入另一个OutputStream
例如ByteArrayOutputStream
如果你想最终得到一个 byte[]
并且事先不知道尺寸。
第三个考虑因素是代码在集群中的运行位置。即使文件在内存中,它们也可能不在集群中每个节点的内存中。如果您从尚未在内存中的节点读取文件,则必须通过网络读取它们,此时性能会降低。
最后考虑的是OS文件缓存。如果您生成了测试文件,然后立即 运行 您的测试,那么这些文件可能会被 OS 缓存在内存中。在这一点上,你将获得与 Alluxio 一样好的性能,甚至更好,因为缓存处于 OS 级别。如果您真的想进行有意义的比较,那么您需要确保在 运行 任何基于文件的测试之前刷新 OS 文件缓存。
经过一些测试,文件大小是读取时间的主要问题。小文件会使阅读时间增加 20 倍甚至更多。
块的大小也会影响读取时间,它可以增加大约 1% 的读取时间。
我已经用Spark在本地安装了Alluxio,我已经在Alluxio的内存中插入了1000个文件。
不过读取文件很慢。
从 Alluxio 内存读取文件的时间等于从磁盘读取文件的时间。
我不明白为什么。
File Name Size Block Size In-Memory Persistence State Pin Creation Time Modification Time
file1 54.73KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:278 08-16-2016 12:52:31:372
file2 54.73KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:377 08-16-2016 12:52:31:384
file3 54.72KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:386 08-16-2016 12:52:31:393
file4 54.71KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:394 08-16-2016 12:52:31:400
file5 54.72KB 512.00MB 100% NOT_PERSISTED NO 08-16-2016 12:52:31:401 08-16-2016 12:52:31:407
...
我用文件 API 读取数据:
FileSystem fs = FileSystem.Factory.get();
AlluxioURI path = new AlluxioURI(/partition0);
List<URIStatus> status = fs.listStatus(path);
for (int i=0; i<status.size(); i++)
{
path = new AlluxioURI(status.get(i).getPath());
if(fs.exists(path)==true)
{
FileInStream in = fs.openFile(path);
String file = "";
InputStreamReader ipsr = new InputStreamReader(in);
BufferedReader br=new BufferedReader(ipsr);
String line;
line=br.readLine();
while (line != null){
//System.out.println(line);
file = file + line;
line=br.readLine();
}
byte[] cfv = file.getBytes();
br.close();
// Close file relinquishing the lock
in.close();
}
}
我暂时不用Spark,因为测试读取1000个文件的分区很慢...(以后想用Spark按分区读取文件)
为什么用这个 method/library 读取时间这么慢?
您的示例中有几处看起来有点不对劲。
首先,您在文件中显示的信息表明这些文件非常小,每个大约 50 kB,但您将 Alluxio 配置为使用 512 MB 块。这可能意味着您正在 运行 提供比实际需要更多的数据。所以要考虑的一件事是,如果你打算主要有小文件,你最好配置一个小得多的块大小。
其次,您在测试用例中实际读取文件的方式非常低效。您正在逐行读取字符串,使用字符串连接来构建文件,然后将其转换回字节。所以你要从内存中的字节到字符串,然后再回到字节。另外,通过使用字符串连接,您可以强制将到目前为止读取的整个文件复制到您读取的内存技术附加行中。
通常,您要么将文件逐行读入 StringBuilder
/ 写入另一个 Writer
,要么将文件作为字节读入 byte[]
/ 写入另一个OutputStream
例如ByteArrayOutputStream
如果你想最终得到一个 byte[]
并且事先不知道尺寸。
第三个考虑因素是代码在集群中的运行位置。即使文件在内存中,它们也可能不在集群中每个节点的内存中。如果您从尚未在内存中的节点读取文件,则必须通过网络读取它们,此时性能会降低。
最后考虑的是OS文件缓存。如果您生成了测试文件,然后立即 运行 您的测试,那么这些文件可能会被 OS 缓存在内存中。在这一点上,你将获得与 Alluxio 一样好的性能,甚至更好,因为缓存处于 OS 级别。如果您真的想进行有意义的比较,那么您需要确保在 运行 任何基于文件的测试之前刷新 OS 文件缓存。
经过一些测试,文件大小是读取时间的主要问题。小文件会使阅读时间增加 20 倍甚至更多。 块的大小也会影响读取时间,它可以增加大约 1% 的读取时间。