Подтвердить что ты не робот

Можно ли добавить к файлу HDFS несколько клиентов параллельно?

В целом весь вопрос находится в названии. Мне интересно, можно ли добавлять файлы в HDFS с нескольких компьютеров одновременно? Что-то вроде хранения потока событий, постоянно создаваемых несколькими процессами. Заказ не важен.

Я помню, как слышал на одной из технических презентаций Google, что GFS поддерживает такие функции добавления, но попытка ограниченного тестирования с HDFS (либо с обычным файловым append(), либо с SequenceFile), похоже, не работает.

Спасибо,

4b9b3361

Ответ 1

Я не думаю, что это возможно с HDFS. Несмотря на то, что вы не заботитесь о порядке записей, вы заботитесь о порядке байтов в файле. Вы не хотите, чтобы писатель A написал частичную запись, которая затем повреждается писателем B. Это трудная проблема для HDFS для решения самостоятельно, так что это не так.

Создайте файл для каждого автора. Передайте все файлы любому работнику MapReduce, который должен прочитать эти данные. Это намного проще и соответствует дизайну HDFS и Hadoop. Если код, не относящийся к MapReduce, должен читать эти данные в виде одного потока, либо последовательно передавать каждый файл или записывать очень быстрое задание MapReduce для консолидации файлов.

Ответ 2

Google должен иметь более сложную файловую систему, которая поддерживает произвольный доступ намного лучше, чем HDFS. Они используют BigTable гораздо чаще и экстенсивнее, что требует более быстрой модификации блоков и одновременного чтения/записи блока. Но на самом деле вы можете реализовать нечто подобное. Недавно я писал с веб-браузером.

Базиально вы не можете парализовать IO. Таким образом, вы должны использовать очередь и последовательно добавлять в файл последовательности.

private final ConcurrentLinkedQueue<FetchResult> queue = new ConcurrentLinkedQueue<FetchResult>();
private final Configuration conf = new Configuration();
private SequenceFile.Writer writer = null;
public boolean running = true;

public FetchResultPersister() throws IOException {
    FileSystem fs = FileSystem.get(conf);
    Path out = new Path("files/crawl/result.seq");
    fs.delete(out, true);
    writer = new SequenceFile.Writer(fs, conf, out, Text.class, Text.class);
}

public final void add(final FetchResult result) {
    queue.offer(result);
}

@Override
public final void run() {
    long retrieved = 0L;
    while (running) {
        final FetchResult poll = queue.poll();
        if (poll != null) {
            try {
                writer.append(new Text(poll.url), asText(poll.outlinks));
                retrieved++;
                if (retrieved % 100 == 0) {
                    System.out
                            .println("Retrieved " + retrieved + " sites!");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
   // close etc omitted
}

Основная идея заключается в том, что диск IO не блокирует вычисление.

В основном вы используете только ConcurrentLinkedQueue, который синхронизирован, и вы добавляете результаты из разных потоков. Как вы можете видеть, это также работает в потоке, опрос новых результатов для записи в файл последовательности.

Я уверен, что GFS поддерживает эти вещи изначально, HDFS делает (на данный момент) не.

Ответ 3

просто FYI, возможно, он будет полностью поддержан в hadoop 2.6.x, acorrding для элемента JIRA на официальном сайте: https://issues.apache.org/jira/browse/HDFS-7203