AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 776530
Accepted
user149408
user149408
Asked: 2024-05-16 00:53:32 +0800 CST2024-05-16 00:53:32 +0800 CST 2024-05-16 00:53:32 +0800 CST

Unison via cron, como lidar com um trabalho ainda em execução quando o próximo for iniciado

  • 772

Eu tenho uma configuração na qual sincronizo arquivos entre dois servidores Linux usando Unison por meio de uma conexão SSH. Isso é implementado executando o seguinte comando via cron:

unison -auto -batch PROFILE

As alterações no conjunto de arquivos acontecem quase exclusivamente em um lado (o outro sistema é uma réplica externa). Eles ocorrem principalmente por meio de outra execução de sincronização do Unison (acionada manualmente) com uma máquina cliente e podem ter um intervalo de algumas horas a algumas semanas. Assim, os conflitos entre as duas máquinas não são uma grande preocupação na prática, e um atraso de até 24 horas para que as alterações sejam propagadas para o outro lado é aceitável.

Os motivos pelos quais estou executando o Unison como um cron job em vez de -repeat(presumivelmente como um serviço systemd) são:

  • Tempos de sincronização previsíveis, já que o cron job é agendado em um momento em que não estou esperando nenhuma operação de sincronização manual da terceira máquina (enquanto, digamos, -repeat 86400seria desviado pela duração da operação de sincronização).
  • As alterações acontecem principalmente no servidor A, enquanto o trabalho de sincronização entre servidores é acionado pelo servidor B (será mais fácil em termos de rede se o servidor B iniciar a conexão). Assim, pelo que entendi, -repeat watchnão pegaria a maior parte das alterações e mesmo com -repeat watch+TIME, estaria contando TIMEquase que exclusivamente (corrija-me se perdi alguma coisa).

Quando as mudanças acontecem, elas geralmente são de baixo volume. Ocasionalmente, entretanto, o volume de dados a ser transferido é tal que uma única execução do Unison dura várias vezes enquanto o intervalo entre dois cron jobs do Unison (a largura de banda entre os sistemas é um tanto restrita). Isso significaria que um processo Unison ainda está em execução quando o cron inicia o próximo no mesmo conjunto de arquivos.

Presumo que o Unison tenha mecanismos de bloqueio, que presumivelmente evitam que o “novo” processo mexa com qualquer coisa em que o “antigo” esteja trabalhando (mas corrija-me se estiver torcendo ou esquecendo alguma coisa). Mas estou me perguntando o que o segundo processo Unison faria nesse caso – observei que ele não sai, mas permanece por perto. Isso significa que o segundo processo aguardaria a conclusão do primeiro e só então iniciaria a sincronização (que incluiria apenas os arquivos que foram alterados enquanto a primeira sincronização estava em andamento e, portanto, falharam na sincronização na primeira execução)?

É seguro iniciar um segundo processo Unison enquanto outro ainda está em execução no mesmo perfil? (Se não, qual é a maneira recomendada de evitar duas instâncias simultâneas do Unison se, e somente se, elas correm o risco de interferir uma na outra?)

E quanto à sobrecarga de recursos unison -repeat wait+TIMEversus ocasionalmente ter várias instâncias do Unison na fila, uma em execução e as outras aguardando a conclusão?

linux
  • 4 4 respostas
  • 653 Views

4 respostas

  • Voted
  1. larsks
    2024-05-16T01:25:28+08:002024-05-16T01:25:28+08:00

    Se quiser evitar o lançamento de uma segunda instância do unison quando outro processo já estiver em execução, você pode controlar a inicialização usando um arquivo de bloqueio por meio do flockcomando. Esta é uma solução geral, funciona para "evitar que uma segunda instância seja executada quando outra instância já estiver em execução".

    Se você quiser que a inicialização falhe quando outra instância estiver em execução:

    flock -n /path/to/lockfile unison -auto -batch PROFILE
    

    Se você deseja que a inicialização seja bloqueada até que o processo existente termine:

    flock /path/to/lockfile unison -auto -batch PROFILE
    

    Consulte a flock(1)página de manual para obter mais informações.

    • 11
  2. Mike Pierce
    2024-05-16T07:15:02+08:002024-05-16T07:15:02+08:00

    Unison (versão 2.51.2) cria seus próprios arquivos de bloqueio. Testando agora, executando unison sync duas vezes na linha de comando, a segunda enquanto a primeira ainda estava em execução, recebi este erro (com material ANONIMIZADO):

    Failed: Destination updated during synchronization
    The contents of file FOO/BAR.text have been modified
    Failed [FOO/BAR.text]: Destination updated during synchronization
    The contents of file foo/bar.text have been modified
    UNISON 2.51.2 (OCAML 4.05.0) finished propagating changes at 17:08:02.32 on 15 May 2024
    Saving synchronizer state
    Fatal error: Warning: the archives are locked.  
    If no other instance of unison is running, the locks should be removed.
    The file /HOME/ME/.unison/GIANTLONGHASHGIANTLONGHASHBIGYIKES on host LOCALHOST should be deleted
    The file /WHEREVER/.unison/GIANTLONGHASHGIANTLONGHASHBIGYIKES on host REMOTEHOST should be deleted
    Please delete lock files as appropriate and try again.
    

    Portanto, parece que a segunda instância do unison será encerrada fatalmente se detectar esses arquivos de bloqueio e presumir que outra sincronização unison está em execução no momento.

    • 5
  3. Best Answer
    Bob
    2024-05-17T23:30:22+08:002024-05-17T23:30:22+08:00

    Razões pelas quais estou executando o Unison como um cron job em vez de -repeat (presumivelmente como um serviço systemd)

    Na verdade, eu sugeriria que o systemd é perfeito para quando você deseja "cron, mas instância única". Você não precisa mantê-lo como um serviço de longa duração - você pode usar temporizadores do systemd de maneira semelhante ao cron enquanto aproveita as vantagens do systemd para gerenciar instâncias.

    1. Defina um serviço systemd de Type=exec. Este serviço será considerado ativo até que o processo seja encerrado. Use a mesma linha de comando que você usa atualmente com o cron.
    2. Defina um timer systemd para iniciar o serviço definido anteriormente. Isso pode ser configurado para acontecer em um horário do relógio (calendário) ( OnCalendar=) ou após um período ( OnUnitActiveSec=seria relativo ao último horário de início do serviço, OnUnitInactiveSec=seria relativo ao último horário de término do serviço). Pessoalmente, gosto do calendário porque é mais previsível e não oscila.
    3. Ative e inicie o cronômetro. Não habilite o serviço, você não quer que ele funcione independentemente do cronômetro.
    4. O cronômetro iniciará o serviço dentro do cronograma. O gerenciador de serviços garantirá que apenas uma instância do serviço esteja ativa. Se o serviço ainda estiver em execução na próxima vez que o cronômetro for acionado, ele simplesmente não fará nada.

    Exemplos de arquivos de unidade para executar Unison como SOMEUSER com perfil SOMEPROFILE (exceto seus sufixos .servicee .timer, ambos os arquivos de unidade devem ter o mesmo nome):

    unison.service:

    [Unit]
    Description=Unison SOMEUSER@SOMEPROFILE
    After=network.target
    
    [Service]
    User=SOMEUSER
    # Type=simple may be used on older versions
    Type=exec
    # may be relative to the service's root directory specified by RootDirectory=, or the special value "~"
    WorkingDirectory=~
    # systemd may insist on an absolute path for the executable
    # Run unison with -terse to prevent cluttering the system journal
    ExecStart=/usr/bin/unison -auto -batch -ui text -terse SOMEPROFILE
    Restart=no
    

    unison.timer(dispara diariamente às 13h37; para OnCalendarsintaxe man 5 systemd.time, consulte a seção Eventos do calendário):

    [Unit]
    Description=Daily unison SOMEUSER@SOMEPROFILE
    
    [Timer]
    OnCalendar=*-*-* 13:37
    
    [Install]
    WantedBy=timers.target
    

    Coloque esses dois arquivos de unidade em /etc/systemd/system/e execute:

    sudo systemctl enable unison.timer
    sudo systemctl start unison.timer
    

    Você pode testar a configuração executando sudo systemctl start unison.service– isso requer apenas a unidade de serviço, não a unidade do temporizador. Essa também é uma forma de iniciar a sincronização fora do cronograma. A saída Unison será gravada no diário do sistema como unisonuma tag.

    • 2
  4. Sotto Voce
    2024-05-17T07:55:45+08:002024-05-17T07:55:45+08:00

    Eu também uso flockscripts de shell de tarefas cron para evitar a execução de mais de um por vez. Eu uso uma abordagem diferente da sugerida em uma resposta anterior. Mostrarei o código e descreverei os benefícios/desvantagens depois.

    O snippet de código Bash pode ser usado em outros shells com pequenas alterações:

    script_name='my-cron-command'
    lock_file="/tmp/${script_name}.lock"
    
    # this flock solution uses a subshell
    (
      # get a lock on subshell's file descriptor 300 (see below)
        flock -x -n 300 || {
        echo "${script name}: Warning: cannot get lock on file ${lock_file}.  Exiting..." >&2
        exit 0
      }
    
      # lock was successful, okay to run my command
    
      ### command here ###
    
      # subshell's file descriptor 300 is open on the lockfile
    ) 300>"${lock_file}"
    

    Desvantagens:

    • O script não esperará até que o bloqueio seja liberado por um script anterior.
    • Invoca um processo extra de subshell.

    Benefícios:

    • Um cron job travado não fará com que jobs posteriores se acumulem aguardando o bloqueio, aumentando a lista de processos e consumindo memória RAM.
    • O bloqueio é liberado quando o subshell sai. Não há necessidade de um comando para desbloquear o arquivo e nenhum bloqueio obsoleto deixado para trás por comandos/scripts travados. (um comando travado pode ser encontrado com fuser /path/to/lock.file)
    • Quando o arquivo de bloqueio já está bloqueado, o script pode registrar uma mensagem significativa antes de sair.
    • Não se limitando a bloquear apenas um comando. O script pode realizar outra manipulação de arquivo/variável entre obter o bloqueio e executar o comando.

    O descritor de arquivo 300 não é especial, é apenas um descritor de numeração alta que provavelmente não será usado por outra parte do script.

    Como acontece com tudo o mais, é uma troca entre os comportamentos que você deseja e os que não deseja.

    • 0

relate perguntas

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve