Synchronizacja MongoDB przez ssh

W przeciwieństwie do Mysql, znalazłem to dość trudne próby synchronizacji plików MongoDB -
Nie można ich przekierować z powrotem, ponieważ nie wysyłają danych do stdout
(Jeśli dobrze rozumiem).

Więc staram się znaleźć inny sposób, który nie obejmuje dwóch połączeń ssh.
Co trzeba zrobić to:

  • Zaloguj się do serwera ssh
  • Eksportuj wszystkie pliki MongoDB
  • skompresuj je do gzip
  • wyślij je z powrotem do lokalnej maszyny
  • ekstrakt i import

Kluczową rzeczą tutaj jest nie pozostawianie po sobie śladu -
Nie chcę, aby skompresowane pliki pozostały w zdalnej maszynie,
co zwykle wymagałoby ode mnie kolejnego logowania ssh.
Więc coś w stylu "Przenieś pliki do archiwum" jest idealnym rozwiązaniem,
jeśli można to później bezproblemowo przesłać z powrotem do lokalnej maszyny.

Zdaję sobie sprawę, że MongoDB ma metodę łączenia się z serwerem za pomocą mongodump, ale port jest zamknięty, więc potrzebuję metoda SSH. Wszelkie inne pomysły będą mile widziane, BTW.

Edit-11.06.14

Ponieważ te pytania wydają się być dość popularne, chciałbym podzielić się skryptem, który ewoluował z odpowiedzi na te pytania i innych zasobów w ciągu ostatniego roku(kredyt jest tam, gdzie kredyt jest należny).
Skrypt zasadniczo zarządza synchronizacją z / do zdalnego serwera, dla każdego typu db możliwe (prawdopodobnie. postgres, mysql i mongo na razie).
Ma kilka założeń, takich jak korzeń użytkownik nie ma hasła do db, ale można je zmienić w zależności od potrzeb.

Skrypt można znaleźć tutaj: https://github.com/iwfmp/zsh/blob/master/scripts/db/db-sync

Author: CrimsonKing, 2013-05-18

3 answers

Możesz to osiągnąć poprzez tunelowanie SSH, ustawiając zdalną instancję MongoDB tak, aby działała na jednym z lokalnych portów. Domyślnie MongoDB działa na 27017, więc w poniższym przykładzie wybrałem mapowanie zdalnej instancji MongoDB na lokalny port 27018.

Jeśli próbujesz skopiować bazę danych z SERVER1 do LOCALHOST, możesz uruchomić tę komendę na swoim LOCALHOST:

ssh -L27018:localhost:27017 SERVER1

Jeśli nie masz konta w usłudze SERVER1, możesz użyć swojego aliasu ssh lub SERVER1.]}

To otwiera połączenie SSH z SERVER1, ale także mapuje port 27018 na LOCALHOST do zdalnego portu 27017 na SERVER1. Nie zamykaj tego połączenia SSH, a teraz spróbuj połączyć się z MongoDB na komputerze localhost z portem 27018, w następujący sposób:]}

mongo --port 27018

Zauważysz, że są to teraz dane na serwerze 1, z wyjątkiem tego, że uzyskujesz do nich dostęp z lokalnego komputera.

Po prostu uruchamiam MongoDB normalnie:

mongo (lub mongo --port 27107)

Będzie Twoją lokalną maszyną.

Teraz, skoro technicznie masz (na swoim LOCALHOST, gdzie prowadziłeś tunel SSH):

  • MongoDB (LOCALHOST) on 27017
  • MongoDB (SERVER1) on 27018

Możesz po prostu użyć funkcji db.copyDatabase() wewnątrz MongoDB (LOCALHOST) do kopiowania danych.

Z LOCALHOST na porcie 27017 (uruchomienie na żywo spowoduje upuszczenie danych)

// Use the right DB
use DATABASENAME; 
// Drop the Existing Data on LOCALHOST
db.dropDatabase();
// Copies the entire database from 27018
db.copyDatabase("DATABASENAME", "DATABASENAME", "localhost:27018");

Powinieneś być w stanie zawinąć to wszystko w skrypt powłoki, który może wykonać wszystkie te polecenia dla Ciebie. Sam mam jeden, ale w rzeczywistości ma kilka dodatkowych kroków, które prawdopodobnie sprawią, że będzie nieco bardziej mylące:)

Robienie tego i używanie natywnego db MongoDB.funkcja copyDatabase() zapobiegnie konieczności zrzutu / zip / restore. Oczywiście, jeśli nadal chcesz iść tą trasą, nie byłoby zbyt trudno uruchomić mongodump, wyeksportować dane, tar/gzip je, a następnie użyć scp TARGETSERVER:/path/to/file /local/path/to/file, aby pociągnąć je w dół i uruchomić mongorestore na nim.

Po prostu wygląda na więcej pracy!

Edit - Oto plik SH i JS, które idą razem, aby skrypt powłoki można uruchomić to z. uruchom je na swoim LOCALHOST, nie uruchamiaj ich na żywo, bo to zrobi db.dropDatabase na żywo. Umieść te dwa pliki w tym samym folderze i zastąp YOURSERVERNAME w pull-db.sh aliasem domain/ip/ssh, a następnie w pull-db.js Zmień DBNAMEHERE na dowolną nazwę bazy danych.

Zwykle tworzę w moich projektach folder o nazwie scripts i używając Textmate, mam aby nacisnąć ⌘+R, mając pull-db.sh otwarte do edycji w celu jej wykonania.

Pull-db.sh

ssh -L27018:localhost:27017 YOURSERVERNAME '
    echo "Connected on Remote End, sleeping for 10"; 
    sleep 10; 
    exit' &
echo "Waiting 5 sec on local";
sleep 5;
echo "Connecting to Mongo and piping in script";
cat pull-db.js | mongo

Pull-db.js

use DBNAMEHERE;
db.dropDatabase();
use DBNAMEHERE;
db.copyDatabase("DBNAMEHERE","DBNAMEHERE","localhost:27018");

Dodałem trochę dodatkowego kodu do skryptu powłoki, aby sprawdzić, co robi (tak jakby). Timery uśpienia w skrypcie mają tylko dać czas połączeniom SSH na połączenie przed uruchomieniem następnej linii. W zasadzie, oto co się dzieje:

  1. pierwsza linia kodu tworzy tunel na Twojej maszynie i wysyła ECHO, SLEEP, a następnie zakończ zdalną sesję SSH.
  2. następnie czeka 5 sekund, co pozwala na połączenie sesji SSH w kroku 1.
  3. / Align = "left" / plik js do lokalnej powłoki mongo. (Krok # 1 należy wykonać w ciągu 5 sek...)
  4. pull-db.js powinien teraz działać w mongo, a terminal SSH w Kroku # 1 prawdopodobnie działał przez 10 sekund po otwarciu połączenia, A wyjście jest wysyłane do jego sesji. Polecenie jest wydawane, jednak sesja SSH będzie w rzeczywistości pozostań otwarty aż do zakończenia czynności z kroku # 3.
  5. jak tylko twój pull-db.skrypt js kończy pobieranie wszystkich danych ze zdalnego serwera, polecenie EXIT wydane w Kroku # 1 na zdalnym serwerze jest w końcu dozwolone, aby zamknąć połączenie, odłączając 27108 na Twoim localhost.

Powinieneś teraz mieć wszystkie dane ze zdalnej bazy danych w swoim localhost.

 50
Author: Jesta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 11:20:40

Aby uzupełnić Jesta great answer, jeśli chcesz zrobić odwrotną (skopiować z lokalnej bazy danych do odległej bazy danych), musisz powiązać port w drugą stronę, za pomocą polecenia-R zamiast polecenia-L:

W tym celu należy skontaktować się z Działem obsługi klienta.]}

I teraz, będąc zalogowanym na zdalnym serwerze, możesz skopiować db z lokalnej bazy danych:

Mongo

> db.copyDatabase ('test','test','localhost:27018')

 2
Author: JulienFr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-08 12:13:06

Naprawdę nie lubię, aby jedna baza danych łączyła się z drugą - IMHO łamie to separację środowisk i komplikuje automatyzację takich skryptów.

Moim rozwiązaniem jest użycie Mongo dump / restore, które używają "dump katalogów" i używać tar do przesyłania strumieniowego plików. Trywialna implementacja (do kopiowania z jednego pilota na drugi) może wyglądać tak:

ssh remote1 'mongodump > /dev/null && tar -zc dump && rm -rf dump' | \
  ssh remote2 'tar -zx && mongorestore dump && rm -rf dump'

Uwagi:

  1. , że zarówno mongodump jak i mongorestore mają bardzo obszerne wyjście, ale mongodump's będzie zarówno bałagan z tar streaming, jak i najwyraźniej mongodump będzie rzeczywiście odmówić pracy, jeśli uruchomisz bez pseudo-terminala i bez przekierowania wyjścia.
  2. mongodump ma opcję zrzutu do stdout, ale nie mogłem dowiedzieć się, jakiego formatu używa i nie rozumiałem, jak uzyskać mongorestore, aby to załadować.
 1
Author: Guss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-17 17:51:11