2009-06-25 7 views
2

Je dispose d'un système sur un "serveur maître", qui transfère périodiquement un certain nombre d'informations d'une base de données MySQL à un autre serveur sur le web.Méthode recommandée pour transférer une table MySQL vers un autre serveur?

Les deux serveurs ont un serveur MySQL et un serveur Apache. Je voudrais une solution facile à utiliser pour cela.

Actuellement, je suis à la recherche dans:

  • XMLRPC
  • services RESTful
  • simple POST à ​​un script de traitement
  • transferts socket

L'application sur mon maître une application TurboGears, donc je préférerais "pythonique" aka des solutions moins moche. Copier une table exportée vers un autre serveur via FTP/SCP ou quelque chose comme ça peut être rapide, mais à mes yeux c'est aussi (rapide et) sale, et j'aimerais avoir une meilleure solution.

Quelqu'un peut-il décrire brièvement comment vous feriez de la «meilleure pratique»?

Cela ne doit pas nécessairement impliquer des bases de données. Déposez la table sur Server1 et transférez les données brutes de manière structurée afin que server2 puisse les traiter sans trop analyser. Une exigence cependant: Dès que les données arrivent sur le serveur 2, je veux qu'il soit traité, donc il doit y avoir une sorte de notification quand le transfert est fait. Bien sûr, je pourrais écrire tout mon propre serveur assis sur une socket sur la deuxième machine et accepter le fichier avec son propre code et le traitement et ainsi de suite, mais c'est juste un très petit morceau d'un très gros système, donc je ne vouloir passer une demi-journée à mettre en œuvre cela.

Merci,

Tom

Répondre

2

Server 1: Convertir des lignes à JSON, appeler l'API RESTful de seconde avec des données JSON

Server 2: écoute sur un URI par exemple POST/données, obtenir des données json convertir en dictionnaire ou objets ORM, insérer dans db

sqlalchemy/sqlobject et simplejson est ce que vous avez besoin.

0

En supposant que votre situation le permet sage sécurité, vous avez oublié un mécanisme de transport: la simple ouverture d'une connexion mysql d'un serveur à un autre. Moi, je commencerais par penser à un script qui s'exécute régulièrement sur le serveur d'écriture et ouvre une connexion db en lecture seule au serveur de lecture (Un peu de sécurité supplémentaire) et une connexion complète à son propre serveur de base de données. La marche à suivre dépend des données (est-ce que ce sont des insertions à traiter? Faut-il dupliquer les suppressions? Combien d'insertions vs mises à jour? Etc) mais vous pouvez écrire un script qui extrait les données du serveur de lecture et traité immédiatement dans le serveur d'écriture.

En outre, la réplication du serveur mysql fonctionnerait-elle ou serait-elle trop répandue comme solution?

0

Si vous avez accès au port de données de MySQL et que le trafic réseau constant ne vous dérange pas, vous pouvez utiliser replication.

1

Si la table est petite et que vous pouvez envoyer la table entière et simplement supprimer les anciennes données et ensuite insérer les nouvelles données sur le serveur distant - alors il peut y avoir une solution générique simple: vous pouvez créer une longue chaîne avec des données de table et l'envoyer via webservice. Voici comment cela peut être mis en œuvre.Notez que ceci est loin d'être parfaite solution, juste un exemple comment transférer de petites tables simples entre les sites Web:

function DumpTableIntoString($tableName, $includeFieldsHeader = true) 
{ 
    global $adoConn; 

    $recordSet = $adoConn->Execute("SELECT * FROM $tableName"); 
    if(!$recordSet) return false; 

    $data = ""; 

    if($includeFieldsHeader) 
    { 
    // fetching fields 
    $numFields = $recordSet->FieldCount(); 
    for($i = 0; $i < $numFields; $i++) 
     $data .= $recordSet->FetchField($i)->name . ","; 
    $data = substr($data, 0, -1) . "\n"; 
    } 

    while(!$recordSet->EOF) 
    { 
    $row = $recordSet->GetRowAssoc(); 
    foreach ($row as &$value) 
    { 
     $value = str_replace("\r\n", "", $value); 
     $value = str_replace('"', '\\"', $value); 
     if($value == null) $value = "\\N"; 
     $value = "\"" . $value . "\""; 
    } 
    $data .= join(',', $row); 

    $recordSet->MoveNext(); 

    if(!$recordSet->EOF) 
     $data .= "\n"; 
    } 

    return $data; 
} 

// NOTE: CURRENTLY FUNCTION DOESN'T SUPPORT HANDLING FIELDS HEADER, SO NOW IT JUST SKIPS IT 
// IF NECESSARRY 
function FillTableFromDumpString($tableName, $dumpString, $truncateTable = true, $fieldsHeaderIncluded = true) 
{ 
    global $adoConn; 

    if($truncateTable) 
    if($adoConn->Execute("TRUNCATE TABLE $tableName") === false) 
     return false; 


    $rows = explode("\n", $dumpString); 
    $startRowIndex = $fieldsHeaderIncluded ? 1 : 0; 

    $query = "INSERT INTO $tableName VALUES "; 
    $numRows = count($rows); 

    for($i = $startRowIndex; $i < $numRows; $i++) 
    { 
    $row = explode(",", $rows[$i]); 

    foreach($row as &$value) 
    { 
     if($value == "\"\\N\"") 
     $value = "NULL"; 
    } 

    $query .= "(". implode(",", $row) .")"; 
    if($i != $numRows - 1) 
     $query .= ","; 
    } 

    if($adoConn->Execute($query) === false) 
    { 
    return false; 
    } 

    return true; 
} 

Si vous avez de grandes tables, alors je pense que vous avez besoin d'envoyer seulement de nouvelles données. Demandez à votre serveur distant l'horodatage le plus récent, puis lisez toutes les nouvelles données de votre serveur principal et envoyez les données de manière générique (comme je l'ai montré ci-dessus) ou de manière non générique (dans ce cas, vous devez écrire séparément fonctions pour chaque table).

0

Si vous utilisez des tables MyISAM ou Archive, alors je recommande fortement mysqlhotcopy

Questions connexes