0

我已经使用 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 逐个分区读取文件)。

为什么使用这种方法/库读取时间这么慢?

4

2 回答 2

2

在您的示例中,有几件事看起来有点不对劲。

首先,您在文件上显示的信息表明这些文件非常小,每个大约 50 kB,但是您将 Alluxio 配置为使用 512 MB 块。这可能意味着您传输的数据比实际需要的要多得多。所以要考虑的一件事是,如果您打算主要拥有小文件,那么最好配置一个更小的块大小。

其次,您在测试用例中实际读取文件的方式非常低效。您正在逐行读取字符串,使用字符串连接来构建文件,然后将其转换回字节。所以你要从内存中的字节到字符串,然后再回到字节。另外,通过使用字符串连接,您可以强制将到目前为止读取的整个文件复制到您读取的内存技术附加行中。

通常,您要么将文件逐行读入StringBuilder/ 写入另一个Writer文件,要么将文件作为字节读入byte[]/ 写入另一个文件,OutputStream例如ByteArrayOutputStream,如果你想最终获得 abyte[]并且事先不知道大小。

第三个考虑因素是您的代码在集群中运行的位置。即使文件在内存中,它们也可能不在集群中每个节点的内存中。如果您从尚未在内存中的节点读取文件,则必须通过网络读取它们,此时性能将降低。

最后的考虑是操作系统文件缓存。如果您生成了测试文件然后立即运行测试,那么这些文件可能会被操作系统缓存在内存中。在这一点上,你将获得与 Alluxio 一样好的性能,因为缓存是在操作系统级别的。如果您真的想进行有意义的比较,那么您需要确保在运行任何基于文件的测试之前刷新您的操作系统文件缓存。

于 2016-08-17T09:18:33.213 回答
0

经过一些测试,文件的大小是读取时间的主要问题。小文件可以乘以 20 甚至更多的读取时间。块的大小也会影响读取时间,它可以增加大约 1% 的读取时间。

于 2016-08-23T07:37:07.983 回答