как эффективно кэшировать большой файл на карте Hadoop, уменьшая количество рабочих мест?

Мой рабочий процесс выглядит следующим образом:

Я обрабатываю огромное количество данных. У меня есть MapFile, который нужно кэшировать. Размер этого файла сейчас составляет 1 ГБ, но я ожидаю, что со временем он вырастет.

Содержимое MapFile будет примерно таким:

12345,45464       192.34.23.1
33214,45321       123.45.32.1
  • В map-phase я обрабатываю каждую запись из входных файлов, которые находятся в TextInputFormat. Я разбираю строку (разделенную на токены) и получаю первые два токена, token1 и token2.

Если пары (токен1, токен2) нет в кешированном файле, я делаю вызов API, получаю информацию, сохраняюсь в кеше (если возможно) и продолжаю обработку.

 private Parser parser = new customParser();

protected void map(LongWritable key, Text value, Context context)
        throws IOException, InterruptedException {

      parser.parse(value);
      Pair pair = new Pair();
      pair.setFirst(parser.getFirst());
      pair.setSecond(parser.getSecond());
      IP ip = null;

      //here is the catch
      //check if pair exists in cache
      if cache.contains(pair){
          ip=cache.get(pair);
       }
       else {
          ip=getFromAPI(pair);//This does API call outside network.
          cache.put(pair,ip);
       }
      context.write(pair,ip);
      }
    }

Основные проблемы, которые я вижу здесь, это

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

  2. Как эффективно искать MapFile (кеш), весь mapFile не будет в памяти.

  3. Как написать в этот MapFile, который является моим Cache.

Спасибо


person brain storm    schedule 30.10.2014    source источник
comment
Вероятно, вам следует отказаться от идеи кэширования. Хотя сейчас я не могу предложить альтернативу.   -  person blackSmith    schedule 30.10.2014


Ответы (1)


Насколько я вижу, есть три способа справиться с этим, и лучший из них зависит от того, как будет расти ваш кеш-файл.

  1. #P2# <блочная цитата> #P3#

Последние два варианта больше подходят, если вы не можете безопасно хранить его в памяти по мере роста файла кеша:

  1. В этом ответе Томас Юнгблут предлагает поместить ваш файл кеша в HDFS, увеличение числа репликаций и чтение с помощью FileSystem API. Это по-прежнему приведет к сетевому взаимодействию для нелокальных реплик, но, надеюсь, меньше, чем передача на все узлы в DistributedCache. FileSystem API также позволяет вам добавлять к существующему файлу, позволяя вам обновить файл.

  2. Если ваш кеш-файл будет расти настолько, что у вас могут возникнуть проблемы с сохранением дополнительной репликации, вы можете вместо этого рассмотреть возможность его извлечения как часть первого шага сопоставления.

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

person Alex A.    schedule 02.11.2014
comment
Метод, который вы предлагаете для чтения в файле кеша на этапе сопоставления, является интересной идеей. но обратная сторона здесь в том, что каждый маппер сделает это, а это ненужные накладные расходы. - person brain storm; 04.11.2014
comment
Я нашел третий вариант, который может вам подойти. Отредактировал сообщение, чтобы включить его. - person Alex A.; 04.11.2014