Глобальные переменные в hadoop

моя программа следует итеративному подходу map/reduce. И это должно прекратиться, если будут выполнены определенные условия. В любом случае я могу установить глобальную переменную, которая может быть распределена по всем задачам map/reduce и проверить, достигает ли глобальная переменная условия для завершения.

что-то вроде этого.

While(Condition != true){

            Configuration conf = getConf();
            Job job = new Job(conf, "Dijkstra Graph Search");

            job.setJarByClass(GraphSearch.class);
            job.setMapperClass(DijkstraMap.class);
            job.setReducerClass(DijkstraReduce.class);

            job.setOutputKeyClass(IntWritable.class);
            job.setOutputValueClass(Text.class);

}

где condition-глобальная переменная, которая изменяется во время/после каждого выполнения map / reduce.

4 ответов


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

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

  1. напишите файл в HDFS, который могут читать другие узлы (убедитесь, что файл очищается при выходе из задания, и что спекулятивное выполнение не вызовет странных сбоев).
  2. используйте ZooKeeper для хранения некоторых данных в выделенных узлах дерева ZK.

можно использовать конфигурации.set (имя строки, строковое значение) чтобы установить значение, вы сможете получить доступ к своим картографам / редукторам / etc:

в драйвере:

   conf.set("my.dijkstra.parameter", "value");

и, например, в свой маппер:

public void configure(JobConf job) {
       myParam = job.get("my.dijkstra.parameter");
   }

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

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

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


вот как это работает в Hadoop 2.0

в драйвере:

 conf.set("my.dijkstra.parameter", "value");

и в вашем картографе:

protected void setup(Context context) throws IOException,
            InterruptedException {
        Configuration conf = context.getConfiguration();

        strProp = conf.get("my.dijkstra.parameter");
        // and then you can use it
    }

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