java - 无法在 Amazon EMR 集群上使用 PIG 0.12.0 和 Hadoop 2.4.0 找到 MySql 驱动程序

标签 java mysql hadoop amazon-web-services apache-pig

我正在使用 SWF 运行创建 EMR 集群的工作流,在该集群上运行 PIG 脚本。我正在尝试使用 PIG 0.12.0 和 Hadoop 2.4.0 运行它,并且在脚本尝试使用 org.apache.pig.piggybank.storage.DBStorage 将脚本存储到 RDS 中的 MySql 数据库时,出现异常被抛出:

2015-05-26 14:36:47,057 [main] ERROR org.apache.pig.piggybank.storage.DBStorage - 
    can't load DB driver:com.mysql.jdbc.Driver
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
  at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:191)
  at org.apache.pig.piggybank.storage.DBStorage.<init>(DBStorage.java:66)

这之前一直在使用 Pig 0.11.1 和 Hadoop 1.0.3。 SWF 工作流和 Activity 是使用 Java AWS SDK 1.9.19 版用 Java 编写的。在更广泛的互联网上搜索信息表明需要修改 PIG_CLASSPATH 以包含 MySql 连接器 JAR - 当前脚本包含

REGISTER $LIB_PATH/mysql-connector-java-5.1.26.jar;

其中 $LIB_PATH 是一个 S3 位置,但有人建议这对 Pig 0.12.0 + Hadoop 2.4.0 来说已经不够了

构造用于启动集群的请求的代码如下所示

public final RunJobFlowRequest constructRequest(final List<String> params) {
    ConductorContext config = ContextHolder.get();

    final JobFlowInstancesConfig instances = new JobFlowInstancesConfig().withInstanceCount(config.getEmrInstanceCount())
            .withMasterInstanceType(config.getEmrMasterType()).withSlaveInstanceType(config.getEmrSlaveType())
            .withKeepJobFlowAliveWhenNoSteps(false).withHadoopVersion(config.getHadoopVersion());

    if (!StringUtils.isBlank(config.getEmrEc2SubnetId())) {
        instances.setEc2SubnetId(config.getEmrEc2SubnetId());
    }

    final BootstrapActionConfig bootStrap = new BootstrapActionConfig().withName("Bootstrap Pig").withScriptBootstrapAction(
            new ScriptBootstrapActionConfig().withPath(config.getEmrBootstrapPath()).withArgs(config.getEmrBootstrapArgs()));

    final StepFactory stepFactory = new StepFactory();
    final List<StepConfig> steps = new LinkedList<>();

    steps.add(new StepConfig().withName("Enable Debugging").withActionOnFailure(ActionOnFailure.TERMINATE_JOB_FLOW)
            .withHadoopJarStep(stepFactory.newEnableDebuggingStep()));

    steps.add(new StepConfig().withName("Install Pig").withActionOnFailure(ActionOnFailure.TERMINATE_JOB_FLOW)
            .withHadoopJarStep(stepFactory.newInstallPigStep(config.getPigVersion())));

    for (final PigScript originalScript : config.getScripts()) {
        ArrayList<String> newParams = new ArrayList<>();

        newParams.addAll(Arrays.asList(originalScript.getScriptParams()));
        newParams.addAll(params);

        final PigScript script = new PigScript(originalScript.getName(), originalScript.getScriptUrl(),
                AWSHelper.burstParameters(newParams.toArray(new String[newParams.size()])));

        steps.add(new StepConfig()
                .withName(script.getName())
                .withActionOnFailure(ActionOnFailure.CONTINUE)
                .withHadoopJarStep(
                        stepFactory.newRunPigScriptStep(script.getScriptUrl(), config.getPigVersion(), script.getScriptParams())));
    }

    final RunJobFlowRequest request = new RunJobFlowRequest().withName(makeRunJobName()).withSteps(steps).withVisibleToAllUsers(true)
            .withBootstrapActions(bootStrap).withLogUri(config.getEmrLogUrl()).withInstances(instances);

    return request;
}

最佳答案

在我的案例中,解决方案是修改引导集群时使用的 shell 脚本,以将合适的 JAR 复制到位

wget http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.34/mysql-connector-java-5.1.34.jar -O $PIG_CLASSPATH/mysql-connector-java-5.1.34.jar

总而言之,对于 Hadoop 2.4.0 和 Pig 0.12.0,在脚本中注册 JAR 已经不够了,JAR 必须在调用 Pig 时可用,方法是确保它在$PIG_CLASSPATH

关于java - 无法在 Amazon EMR 集群上使用 PIG 0.12.0 和 Hadoop 2.4.0 找到 MySql 驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30462789/

相关文章:

php - 使用 PHP 将 MySQL 变量插入 Google map

mysql - 使用 MySQL,我如何知道谁每年至少参加一次事件?

docker - 无法为高可用性存储创建文件系统

hadoop - 替换配置单元中的 NULL

java - 如何在 Web 界面 Android 应用程序中显示桌面站点?

java - 想要通过 ids 列表获取 ArrayList 中的元素

java - 更改 GLSL 版本以与 GL3 兼容

mysql - 使用 left join is null 而不是 where not exists in mysql

maven - Oozie 4.2.0 使用 Java 1.8 使用 Hadoop 2.7 构建错误

java - 如何将对象类列表添加到数组列表?