Я пытаюсь установить свойство Java System java.util.Arrays.useLegacyMergeSort
в моем редукторе, чтобы заставить систему использовать JDK 6 Внедрение метода Arrayys.sort вместо JDK8.Использование System.setProperty() в Reducer
package scoring.devicestatus;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.log4j.Logger;
import domain.DeviceEvent;
import domain.DeviceStatus;
import domain.EndOfPeriodEvent;
import domain.PiidBoundaryEvent;
import util.DateUtils;
public class DeviceStatusReducer extends Reducer<Text, Text, Text, NullWritable> {
public static final Logger logger = Logger.getLogger(DeviceStatusReducer.class);
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
-->Configuration conf = context.getConfiguration();
. .
.
try{
.
.
writeToContext(key, records, context);
}catch(Throwable t){
logger.error("Error processing VIN: " + key.toString(), t);
throw new RuntimeException(t);
}
}
List<DeviceStatus> reduce(Iterable<Text> values, String endDate) {
List<DeviceEvent> events = createEvents(values, endDate);
.
.
}
List<DeviceEvent> createEvents(Iterable<Text> values, String endDate) {
List<DeviceEvent> events = new ArrayList<DeviceEvent>(10);
for(Text text : values){
List<DeviceEvent> instances = DeviceEvent.getInstance(text);
for(DeviceEvent instance : instances){
if(!Constants.ORPHAN_PIID.equals(instance.getProgramInstanceId())){
events.add(instance);
}
}
}
--> System.out.println("Reducer Class:"+System.getProperty("java.util.Arrays.useLegacyMergeSort")+" "+conf.get("java.util.Arrays.useLegacyMergeSort"));
Collections.sort(events);
return events;
}
public void writeToContext(Text key, List<DeviceStatus> deviceStatuses, Context context) throws IOException, InterruptedException {
String vin = key.toString();
for (DeviceStatus status : deviceStatuses) {
context.write(new Text(status.toCsvString(vin)), NullWritable.get());
}
}
}
package domain;
public abstract class DeviceEvent implements Comparable<DeviceEvent> {
.
.
.
@Override
public int compareTo(DeviceEvent arg0) {
int comparison = getTimeStamp().compareTo(arg0.getTimeStamp());
if(comparison == 0){
comparison = isInstalled() ? 1 : -1;
}
return comparison;
}
.
.
.
}
Я побежал банку через командную строку, используя опцию -D, как
hadoop jar jarname.jar classname -Djava.util.Arrays.useLegacyMergeSort=true args
Редуктор действительно приносит свойство в конфигурации, но моя ошибка все еще не получает исправлено. Когда я печатаю свойство с помощью configuration.get и System.getProperty использованием System.out.println("Reducer Class:" +System.getProperty("java.util.Arrays.useLegacyMergeSort")+ " " +conf.get("java.util.Arrays.useLegacyMergeSort"));
Это выглядит следующим образом:
stdout: Reducer Class:null true Reducer Class:null true Reducer Class:null true Reducer Class:null true Reducer Class:null true Reducer Class:null true
Below is the stack trace: SysLog: 2016-10-05 16:25:21,032 ERROR [main] DeviceStatusReducer: Error processing VIN: 19XXXXXXXXXXX java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:744) at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:481) at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:406) at java.util.ComparableTimSort.sort(ComparableTimSort.java:213) at java.util.Arrays.sort(Arrays.java:1312) at java.util.Arrays.sort(Arrays.java:1506) at java.util.ArrayList.sort(ArrayList.java:1454) at java.util.Collections.sort(Collections.java:141) at DeviceStatusReducer.createEvents(DeviceStatusReducer.java:139) at DeviceStatusReducer.reduce(DeviceStatusReducer.java:43) at DeviceStatusReducer.reduce(DeviceStatusReducer.java:34) at DeviceStatusReducer.reduce(DeviceStatusReducer.java:24) at org.apache.hadoop.mapreduce.Reducer.run(Reducer.java:171) at org.apache.hadoop.mapred.ReduceTask.runNewReducer(ReduceTask.java:627) at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:389) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1657) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Я знаю наверняка, что java.util.Arrays.useLegacyMergeSort
работает, потому что он работал на моем затмении (один JVM), когда я установил в основном классе как System.setProperty("java.util.Arrays.useLegacyMergeSort","true")
, но не работает на кластере Hadoop (несколько JVM). Я также попытался установить это прямо в Reducer как System.setProperty("java.util.Arrays.useLegacyMergeSort","true")
.
Как получить имущество для распространения на всех JVM? Или Как создать свойство конфигурации как свойство System? Благодаря
Попробуйте использовать опцию mapreduce.reduce.java.opts для передачи опции JVM редуктора. – vgunnu
Вроде -D mapreduce.reduce.java.opts = -Djava.util.Arrays.useLegacyMergeSort = true? –