У меня есть куча файлов Hadoop SequenceFiles, которые были написаны с помощью написанного мной подкласса Writable. Назовем его FishWritable.
Этот Writable некоторое время работал хорошо, пока я не решил, что для ясности нужно переименовать пакет. Итак, теперь полное имя FishWritable — com.vertebrates.fishes.FishWritable
вместо com.mammals.fishes.FishWritable
. Это было разумным изменением, учитывая, как развивался объем рассматриваемого пакета.
Затем я обнаруживаю, что ни одно из моих заданий MapReduce не будет выполняться, поскольку они аварийно завершают работу при попытке инициализировать SequenceFileRecordReader:
java.lang.RuntimeException: java.io.IOException: WritableName can't load class: com.mammals.fishes.FishWritable
at org.apache.hadoop.io.SequenceFile$Reader.getKeyClass(SequenceFile.java:1949)
at org.apache.hadoop.io.SequenceFile$Reader.init(SequenceFile.java:1899)
...
Сразу бросается в глаза пара вариантов борьбы с этим. Я могу просто перезапустить все свои предыдущие задания, чтобы восстановить вывод с актуальным именем класса ключа, запуская все зависимые задания последовательно. Очевидно, что это может занять довольно много времени, а иногда даже невозможно.
Другой возможностью может быть написание простого задания, которое считывает файл SequenceFile как текст и заменяет все экземпляры имени класса новым. Это в основном метод № 1 с настройкой, которая делает его менее сложным. Если у меня много больших файлов, это все равно нецелесообразно.
Есть ли лучший способ справиться с рефакторингом полных имен классов, используемых в SequenceFiles? В идеале я ищу способ указать новое имя резервного класса, если указанный не найден, чтобы можно было работать как с датированными, так и с обновленными типами этого SequenceFile.