Integração de ODPS e Kettle

Introdução de cena

Os fornecedores tradicionais de gerenciamento de dados (que não usam tecnologia de computação em nuvem) costumam usar Oracle como armazenamento para data warehouses e Kettle como ETL e ferramentas de agendamento de processos. Contando com a estabilidade, alta eficiência e flexibilidade do Kettle da Oracle, a arquitetura tradicional pode lidar com vários cenários complexos. A estrutura de governança de dados é simplesmente esta:

Arquitetura tradicional

Com o desenvolvimento e promoção contínuos da tecnologia de computação em nuvem, as arquiteturas tradicionais estão lentamente desaparecendo do mercado, mas durante o processo de entrega, é inevitável encontrar cenários que integram a computação em nuvem com fornecedores tradicionais. Por exemplo, usamos o produto DataWorks da Alibaba Cloud, que integra o armazenamento de dados em nuvem ODPS e a ferramenta de sincronização offline DataX, a arquitetura geral ficará assim:

Arquitetura convergente

Este artigo apresenta principalmente como garantir a sincronização de trabalhos DataX e trabalhos Kettle nos cenários acima.

Uma introdução

1. Crie um nó virtual ( vn_root) no DataWorks e defina o nó para o estado "pausado" (as instâncias no estado pausado serão convertidas para o estado "falhou" quando o tempo de execução definido chegar) e, em seguida, todos os upstream do A tarefa de integração de dados DataX é configurada como este nó;

2. Use Java para encapsular a API DataWorks, o nome da classe de encapsulamento ResumeTaske a saída como um pacote jar ( active_vn_root.jar), o seguinte processo é implementado no código para ativar a tarefa DataX:

Processo de ativação

3. active_vn_root.jarReinicie o Kettle após colocá-lo no diretório data-integration \ lib

4. Adicione um nó de código java ao processo de negócios original. O código-fonte é o seguinte:

/* 引用 jar 包中的方法 */
import dataworks.ResumeTask;

public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException {
    
    

    Object[] r = getRow();
    if (r == null) {
    
    
        setOutputDone();
        return false;
    }

    /* 只处理第一行 */
    if (first) {
    
    
        first = false;
    } else {
    
    
        setOutputDone();
        return false;
    }

    Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());

    /* 捕获上游信号 */
    String signal = get(Fields.In, "signal").getString(r);

    /* 处理信号 */
    if (signal.compareTo("1") == 0) {
    
    
        logBasic("signal is 1");
        /* 节点号 1234 是固定值,不会变*/
        int ret = ResumeTask.doResumeTask(1234);
        /** ret 返回数字的含义
         *         0 成功;
         *         -1 其他异常(网络异常);
         *         1 查询异常,未查询到相关实例;
         *         2 查询异常,查询到多个相关实例;
         *         3 恢复失败;
         *         4 恢复失败,任务为一次性任务;
         *         5 恢复失败,任务为空跑任务;
         *         6 恢复失败,接口调用返回值异常;
         *         7 实例恢复成功,但重跑失败;
         *         8 实例恢复成功,但重跑失败,任务并非失败任务,不需要重跑
         *         9 实例恢复成功,但重跑失败,接口调用返回值异常;
         */
        logBasic("return code is " + ret);
        if (ret == 0) {
    
    
            logBasic("active root node successfully: 调用成功");
            get(Fields.Out, "result").setValue(outputRow, "success");
        } else {
    
    
            String err_msg = "UNKOWN ERROR";
            switch(ret) {
    
    
                case -1: err_msg="其他异常(网络异常);";break;
                case  1: err_msg="查询异常,未查询到相关实例;";break;
                case  2: err_msg="查询异常,查询到多个相关实例;";break;
                case  3: err_msg="恢复失败;";break;
                case  4: err_msg="恢复失败,任务为一次性任务;";break;
                case  5: err_msg="恢复失败,任务为空跑任务;";break;
                case  6: err_msg="恢复失败,接口调用返回值异常;";break;
                case  7: err_msg="实例恢复成功,但重跑失败;";break;
                case  8: err_msg="实例恢复成功,但重跑失败,任务并非失败任务,不需要重跑;";break;
                case  9: err_msg="实例恢复成功,但重跑失败,接口调用返回值异常;";break;
            }
            logBasic("active root node failed: 调用失败," + err_msg);
            get(Fields.Out, "result").setValue(outputRow, "fail");
        }
    } else {
    
    
        logBasic("signal is not 1, will do nothing:  接收到的信号错误");
        get(Fields.Out, "result").setValue(outputRow, "fail");
    }
    putRow(data.outputRowMeta, outputRow);
    setOutputDone(); 
    return false;
}

5. Como a API DataWorks é uma operação assíncrona (ou seja, retorna após a chamada e não espera que a tarefa seja executada), não há necessidade de se preocupar se a execução do nó bloqueará a execução do processo geral.

Acho que você gosta

Origin blog.csdn.net/ManWZD/article/details/110679589
Recomendado
Clasificación