Bir ağ kümesinde tekrarlanan komutlar için SSH Bash komut dosyası


1

100 makineden oluşan bir ağ kümesine, bir yazılım parçasına ve yazılım için farklı parametrelerin büyük bir listesine sahibim.

Hesaplamayı hızlandırmak için kümeyi kullanmak istiyorum, böylece her makinenin yazılımı listeden farklı bir parametre seti ile çalıştırması gerekiyordu. Bir makine hesaplamalarını tamamladığında bir sonraki parametre grubunu almalı ve tüm parametreler kullanılana kadar yazılımı tekrar çalıştırmalıdır.

Bunu bir bash betiğinde ssh ile yapmanın bir yolu var mı? Sanırım pssh gitmenin yolu, ama nasıl yapılacağını çözemedim.


1
openmpiveya openmpkümelerde dağıtılmış algoritmalar geliştirmek için kullanılır. OpenMPI'nin farklı diller için bağları var ama bash için bazılarının olacağını sanmıyorum, çünkü genellikle paralel ortamda yüksek performansa ihtiyacınız var. Temel iletişim orada SSH kullanılarak yapılır. Kütüphane olmadan kendi başınıza yapmayı kesinlikle tavsiye etmiyorum.
Jakuje

Sanırım openmpi benim senaryomda fazla yüklenecekti. Aslında, algoritma hiç dağıtılmamıştır. Sadece bu farklı parametre setleriyle çalıştırılması gerekiyor, ancak bireysel çalıştırmalar birbirinden bağımsız. Bu yüzden şöyle hayal ediyorum: Yazılımı tüm makinelerde çalıştırın, hangi makinelerin geri döndüğünü takip edin ve ardından anında yeni parametreleri besleyin.
Briensturm

Bu konuda @ Jakuje ile birlikteyim. İş yükünün makineler arasında nasıl dağıtılması gerektiğini uygulamaya çalışıyorsunuz. Akademik nedenleriniz ya da sorunların olmadığı sürece, bunu kendi başınıza yapmak iyi bir fikir değildir. A) zaten farklı çerçevelerde (Ømq, GridEngine ...) ve b) yapılıyorsa, muhtemelen yaparak kısalmış olursunuz. bu kendi başınıza, zaten mevcut bir araçla sona erer.
Felipe Lema

benim basit algoritmam: önce, bir samba / nfs paylaşımını ayarlamak, böylece tüm düğümlerin ondan kaçabileceğini, ardından paylaşılan dizindeki dosyaları ayırmak için gerekli parametreleri yazdığımı. Her düğüm gerekli parametreleri almak için bir dosyayı çeker, programı çalıştırır ve karşılık gelen dosyayı tekrar hareket ettirir. Program bittiğinde, paylaşılan dizinde başka dosya kalmayıncaya kadar yeni bir dosya çekin.
Chris.C,

Yanıtlar:


2

Yerel CPU çekirdeğini tüketen benzer bir şey yapan bir bash betiği yazdım. Bir çekirdek serbest kaldığında, hesaplamalar bitene kadar yeni bir hesaplama yapar. Ayrıca, ssh ile bash komut dosyası yazmakta biraz deneyimim var (bu güvenlik riskinden memnunsanız şifreli bir ssh anahtarı gerektirir). Bu bağlam dışı kişisel bir örnektir, ancak fikir, işlem süresine göre dinamik olarak döngü yapan ve parametreleri değiştiren bir bash betiği olmasıdır. $ CORES değişkeni, sizin durumunuzda, mevcut sunucularla doldurulmalı ve daha sonra hangisini arayacağınızı bilmek için onları izlemenin bir yolunu bulmalıyız.

    Loop () {
      # looping function over all runs with the same header, multi-threaded per core.
      CMDINIT="$CMD"
      for i in "$TREEIN"/"$NAME"*.root  # loop over all the existing raw runs of that name
      do
        # name of the output file and path, eg Tree/30s_production/30s_production-1001.root
        OUTPUT=`echo $i | sed "s#$TREEIN/##" |sed "s#$NAME#$TREEOUT/$NAME/$NAME-#"  `
        INFILE=`echo $i | sed 's$.*/$$'` # name of the input file name, eg 30s_production1001.root
        if [ ! -e  $OUTPUT ];then # only run if the output file does not exist (won't overwrite existing data)
          if [ ! $Cflag ];then # only call the program if we aren't cleaning 
            echo "Outputting to $OUTPUT..."
            RUNNO=`echo $INFILE | sed "s/$NAME//" | sed 's/\..*//'` # get the run number
            # there is a way to do this using the Run function?  Seems trickier with backgrounding, getting PID, and so on
            CMD="$CMDINIT -R $RUNNO"
            printf "Executing run with the command:\n\t$CMD\n"
            $CMD & PIDS="$PIDS $!" # call run on the run number in background w/o renice
            #$CMD & PIDS="$PIDS $!" && sudo renice -n 0 -p $! # call run on the run number in background, renice to -10
            while [ `jobs | wc -l` -eq $CORES ] # only run one run command per core
            do
                    jobs > /dev/null # without this the while loop doesn't seem to refresh?
                    sleep 1 # keep waiting until run is not running on a core
            done
          fi
        else # the output file exists -- should never happen as we check NeedClean first, but anyway, safer
          echo "$OUTPUT exists, please run clean!"
          exit 1
        fi
      done
    }

Burada iki "zeki" bölüm var (ya da eğer istersen 'hack'). Birincisi, sayısını kontrol eden jobsve bir şey özgür olana kadar bekleyen süre döngüdür . (Benim mevcut do döngümüm bir parametreye dayanıyor, ancak bu ayarlaması kolay.) Bunlarjobsbash betiğinin içindekilerdir ve bu, bir işin tamamlanması koşuluyla tekrar döngü oluşturmaya nasıl ulaştığını; Bunun işin yerel mi yoksa uzak mı olduğu ile aynı olacağını aklınızda bulundurun: SSH komutunu çağırmak için bir komut yerel bir işle aynı olacaktır (ancak tüm sonuçları tüm sunuculardan toplamamız gerekebilir veya tüm Sunucular gerektiğinde verileri yerel olarak, vs. Benim için bir diğer kritik husus da $ CMD'nin ne zaman çağrılacağı, aynı zamanda işlem numarasını $ PIDS adlı bir sayaçta nasıl kullandığıdır. Bu, erken basmaya karar verirseniz, yerel bash betiğindeki bir control_c tuzağının, 100 sunucunuzun hepsinde ortaya çıkarılan süreçleri de içeren tüm alt işlemleri öldürebilmesini sağlar; Bunu izlememenin sonucu, hayal edebileceğiniz kadar korkunç!

Ana betiği kontrol etmek istiyorsanız, işte burada: https://github.com/goatface/crabat/blob/master/crabat

$ CMD değişkeninin tanımını, düzeninde bir şey olması için değiştirmemiz gerekir.

CMD=ssh '$USER@$HOST' /path/to/executable

Bundan sonra, farklı parametreleri kontrol etmek için dinamik olarak çalıştırılabilir bayraklara yapıştırmalıyız (bunları bir metin dosyasında scp ile her sunucuya da itebiliriz, ama sonunda bunları yine de izlemeliyiz ve fark benim için önemli değil) ). Benim durumum parametrelerin çoğunu bir kez ayarlar, ancak bunu her sunucu açıldığında arayamazsak hiçbir neden yoktur. Bayrakları kullandığım yere benziyor, ancak bu, metin dosyalarının parametreli olarak ayarlanması için çok önemlidir. Her alan için awk alanında bir sayım değişkenini, tükenene kadar, sırasıyla, artırın ve bir sonraki sayma değişkeni parametrelerin tüm permütasyonları boyunca sırayla artırıldığında her seferinde Döngü işlevinde sıfırlayın.

    SetFlags () {
      # base command
      CMD="./run"
      # add options based on final flags
      [ $Rflag ] && CMD="$CMD -R $Rval"
      [ $Bflag ] && CMD="$CMD -B"
      [ $Hflag ] && CMD="$CMD -H $Hval"
      [ $Iflag ] && CMD="$CMD -I $Ival"
      [ $rflag ] && CMD="$CMD -r"
      [ $dflag ] && CMD="$CMD -d"
      [ $sflag ] && CMD="$CMD -s"
      [ $xflag ] && CMD="$CMD -x"
      [ $pflag ] && CMD="$CMD -p"
      [ $tflag ] && CMD="$CMD -t"
    }

Cevaplar üzerine e-postalar almayı başarabildim, çünkü bunu ilginç bir soru olarak görüyorum, ancak ana bilgisayarları serbest bırakırken izlemeyi düşünmek için daha fazla zamana ihtiyacım var. Üzgünüm, henüz tüm soruyu cevaplamadım!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.