Читать несколько файлов с Spark Java из Alluxio медленно
Я установил Alluxio локально с Spark и вставил 1000 файлов в память Alluxio.
Тем не менее чтение файла происходит очень медленно. Время чтения файла из памяти 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 в будущем).
Зачем читать время с помощью этого метода / библиотеки так медленно?
2 ответа
Есть несколько вещей, которые немного выглядят в вашем примере.
Во-первых, информация, которую вы показываете в своих файлах, говорит о том, что файлы очень малы - около 50 КБ каждый, но Alluxio настроен на использование блоков 512 МБ. Это потенциально означает, что вы передаете гораздо больше данных, чем вам действительно нужно. Итак, одна вещь, которую следует учитывать, это то, что, если вы намереваетесь в первую очередь иметь небольшие файлы, вам лучше сконфигурировать для гораздо меньшего размера блока.
Во-вторых, способ, которым вы на самом деле читаете файл в своем тестовом примере, ужасно неэффективен. Вы читаете строку за строкой как строку, используя конкатенацию строк для создания файла, который затем преобразуете обратно в байты. Таким образом, вы переходите от байтов в памяти к строкам, а затем обратно к байтам. Кроме того, используя конкатенацию строк, вы заставляете весь прочитанный файл копировать в память дополнительную строку, которую вы читаете.
Обычно вы читаете файл построчно в StringBuilder
/ писать другому Writer
или вы читаете файл как байты в byte[]
/ писать другому OutputStream
например ByteArrayOutputStream
если вы хотите в конечном итоге получить byte[]
и не знаю размер заранее.
Третье соображение заключается в том, где ваш код работает в вашем кластере. Даже если файлы находятся в памяти, они могут отсутствовать в памяти на каждом узле кластера. Если вы читаете файлы с узла, где они еще не находятся в памяти, они должны быть прочитаны по сети, после чего производительность будет снижена.
Последнее соображение - кеширование файлов ОС. Если вы сгенерировали тестовые файлы, а затем сразу же запустили тест, то эти файлы, вероятно, кэшируются в памяти операционной системой. В этот момент вы получите такую же хорошую, если не лучшую производительность, как Alluxio, потому что кэширование находится на уровне ОС. Если вы действительно хотите провести осмысленное сравнение, вам необходимо убедиться, что вы очищаете кеш файлов ОС, прежде чем запускать какие-либо файловые тесты.
После некоторого теста размер файла является основной проблемой во время чтения. Небольшие файлы могут умножить на 20 и более раз время чтения. На размер блока влияет также время чтения, оно может увеличить время чтения примерно на 1%.