Como executar o failover de tarefas agendadas?

8

Usando dois servidores Debian, eu preciso configurar um ambiente de failover strong para tarefas agendadas que só podem ser chamadas em um servidor por vez.

Mover um arquivo em /etc/cron.d deve fazer o truque, mas existe uma solução simples de HA para operar tal ação? E se possível, não com batimentos cardíacos;)

    
por Falken 14.08.2009 / 11:40

7 respostas

5

Acho que pulsação / marcapasso seria a melhor solução, já que eles podem cuidar de muitas condições de corrida, esgrima, etc para você, a fim de garantir que o trabalho seja executado apenas em um host de cada vez. É possível projetar algo por conta própria, mas provavelmente não será responsável por todos os cenários que esses pacotes fazem, e você acabará substituindo a maior parte, se não toda a roda.

Se você realmente não se importa com essas coisas e quer uma configuração mais simples. Eu sugiro escalonar os trabalhos do cron nos servidores por alguns minutos. Então, quando o trabalho começa no primário, pode de alguma forma deixar um marcador em qualquer recurso compartilhado em que os trabalhos operam (você não especifica isso, então estou sendo intencionalmente vago). Se for um banco de dados, eles podem atualizar um campo em uma tabela ou, se estiver em um sistema de arquivos compartilhado, bloquear um arquivo.

Quando o trabalho é executado no segundo servidor, ele pode verificar a presença do marcador e abortar, se estiver lá.

    
por 15.08.2009 / 19:33
1

Nós usamos duas abordagens dependendo dos requisitos. Ambos envolvem ter os crons presentes e funcionando a partir de todas as máquinas, mas com um pouco de verificação de sanidade envolvida:

  1. Se as máquinas estiverem em um relacionamento primário e secundário (pode haver mais de um secundário), os scripts serão modificados para verificar se a máquina em que estão sendo executados é um estado primário. Se não, então eles simplesmente saem em silêncio. Não tenho uma configuração HB para entregar no momento, mas acredito que você possa consultar a HB para obter essas informações.

  2. Se todas as máquinas forem primárias elegíveis (como em um cluster), algum bloqueio será usado. Por meio de um banco de dados compartilhado ou arquivo PID. Apenas uma máquina obtém o status de bloqueio e aqueles que não saem silenciosamente.

por 14.08.2009 / 11:47
1

Para encurtar a história, você precisa transformar seus scripts do cron em algum tipo de aplicativo capaz de cluster. Sendo a implementação leve ou pesada como você precisa, eles ainda precisam de uma coisa - poder retomar / reiniciar corretamente a ação (ou recuperar seu estado) após o failover do nó primário. O caso trivial é que eles são programas sem estado (ou programas "stateless enough"), que podem ser simplesmente reiniciados a qualquer momento e funcionarão bem. Este provavelmente não é o seu caso. Observe que, para programas sem estado, você não precisa de failover, pois pode simplesmente executá-los em paralelo em todos os nós.

Em casos normalmente complicados, seus scripts devem estar no armazenamento compartilhado do cluster, devem armazenar seu estado em arquivos, devem alterar o estado armazenado no disco apenas atomicamente e devem poder continuar sua ação a partir de qualquer estado transitório que detectem na inicialização.

    
por 15.08.2009 / 18:00
1

Na verdade, não há solução satisfatória nessa área. Nós tentamos todos eles. soluções de script, cron com heartbeat / pacemaker e muito mais. A única solução, até recentemente, era uma solução de grade. naturalmente, isso não é o que queremos ver como uma solução de grade é um pouco mais que um exagero para o cenário.

É por isso que iniciei o projeto CronBalancer. funciona exatamente como um servidor cron normal, exceto que é distribuído, com balanceamento de carga e HA (quando concluído). Atualmente, os primeiros 2 pontos estão concluídos (beta) e funcionam com um arquivo crontab padrão.

o framework HA está em vigor. tudo o que resta é a sinalização necessária para determinar as ações de failover e recuperação.

link

chuck

    
por 26.03.2011 / 08:38
1

Eu estava usando o Nagios manipulador de eventos como uma solução simples.

No servidor NRPE:

command[check_crond]=/usr/lib64/nagios/plugins/check_procs -c 1: -C crond
command[autostart_crond]=sudo /etc/init.d/crond start
command[stop_crond]=sudo /etc/init.d/crond stop

Não se esqueça de adicionar o usuário nagios ao grupo sudoers:

nagios  ALL=(ALL)   NOPASSWD:/usr/lib64/nagios/plugins/, /etc/init.d/crond

e desative requiretty :

Defaults:nagios !requiretty

No servidor Nagios:

services.cfg

define service{
    use                     generic-service
    host_name               cpc_3.145
    service_description     crond
    check_command           check_nrpe!check_crond
    event_handler           autostart_crond!cpc_2.93
    process_perf_data       0
    contact_groups          admin,admin-sms
}

commands.cfg

define command{
    command_name    autostart_crond
    command_line    $USER1$/eventhandlers/autostart_crond.sh $SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$ $ARG1$
}

autostart_crond.sh

#!/bin/bash

case "$1" in
    OK)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c stop_crond
        ;;
    WARNING)
        ;;
    UNKNOWN)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
    CRITICAL)
        /usr/local/nagios/libexec/check_nrpe -H $4 -c autostart_crond
        ;;
esac

exit 0

mas eu mudei para usar Pacemaker e Corosync já que é a melhor solução para garantir que o recurso seja executado apenas em um nó por vez.

Aqui estão os passos que eu fiz:

Verifique se o script de inicialização é compatível com LSB . No meu CentOS, eu tenho que mudar o status de saída de 1 para 0 (se começar a correr ou parar um parado) para corresponder aos requisitos:

start() {
    echo -n $"Starting $prog: " 
    if [ -e /var/lock/subsys/crond ]; then
        if [ -e /var/run/crond.pid ] && [ -e /proc/'cat /var/run/crond.pid' ]; then
            echo -n $"cannot start crond: crond is already running.";
            failure $"cannot start crond: crond already running.";
            echo
            #return 1
            return 0
        fi
    fi

stop() {
    echo -n $"Stopping $prog: "
    if [ ! -e /var/lock/subsys/crond ]; then
        echo -n $"cannot stop crond: crond is not running."
        failure $"cannot stop crond: crond is not running."
        echo
        #return 1;
        return 0;
    fi

pode ser adicionado ao Pacemaker usando:

# crm configure primitive Crond lsb:crond \
        op monitor interval="60s"

crm configure show

node SVR022-293.localdomain
node SVR233NTC-3145.localdomain
primitive Crond lsb:crond \
        op monitor interval="60s"
property $id="cib-bootstrap-options" \
        dc-version="1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f" \
        cluster-infrastructure="openais" \
        expected-quorum-votes="2" \
        stonith-enabled="false" \
        no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
        resource-stickiness="100"

status do crm

============
Last updated: Fri Jun  7 13:44:03 2013
Stack: openais
Current DC: SVR233NTC-3145.localdomain - partition with quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain SVR233NTC-3145.localdomain ]

 Crond  (lsb:crond):    Started SVR233NTC-3145.localdomain

Testando o failover parando o Pacemaker e o Corosync em 3.145:

[root@3145 corosync]# service pacemaker stop
Signaling Pacemaker Cluster Manager to terminate:          [  OK  ]
Waiting for cluster services to unload:......              [  OK  ]

[root@3145 corosync]# service corosync stop
Signaling Corosync Cluster Engine (corosync) to terminate: [  OK  ]
Waiting for corosync services to unload:.                  [  OK  ]

verifique o status do cluster no 2.93:

============
Last updated: Fri Jun  7 13:47:31 2013
Stack: openais
Current DC: SVR022-293.localdomain - partition WITHOUT quorum
Version: 1.1.5-1.1.el5-01e86afaaa6d4a8c4836f68df80ababd6ca3902f
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ SVR022-293.localdomain ]
OFFLINE: [ SVR233NTC-3145.localdomain ]

Crond   (lsb:crond):    Started SVR022-293.localdomain
    
por 07.06.2013 / 08:42
0

Fazê-lo executar / não executar em uma máquina específica é trivial. Ou tenha um script para colocar uma tarefa cron em /etc/cron.d, como você sugere, ou tenha o script permanentemente em /etc/cron.d, mas faça o próprio script fazer a verificação de failover e decida se será executado.

A parte comum (ausente) em ambos é como o script verifica se o script na outra máquina está sendo executado.

Sem mais informações sobre o que você está tentando fazer, é difícil responder.

    
por 15.08.2009 / 02:46
0

Eu prefiro o Rcron para este problema em particular. Você tem um arquivo de estado, que simplesmente diz "ativo" ou "passivo", e se estiver ativo, seu cron será executado em uma determinada máquina. Se o arquivo de estado estiver definido como passivo, ele não será executado. Simples assim.

Agora, você pode usar o RedHat Cluster Suite ou qualquer outro middleware de clustering para gerenciar arquivos de estado em seu cluster ou pode definir manualmente a ativação em um determinado nó e pronto.

    
por 07.03.2014 / 22:02