2009-06-25 3 views
2

У меня есть система, сидящая на «Мастер-сервере», которая периодически переносит довольно много фрагментов информации из БД MySQL на другой сервер в Интернете.Лучшая практика для переноса таблицы MySQL на другой сервер?

Оба сервера имеют сервер MySQL и Apache. Я хотел бы простое в использовании решение для этого.

В настоящее время я ищу в:

  • XMLRPC
  • успокоительных Услуги
  • простой POST в сценарий обработки
  • сокет передает

приложение на мой хозяин приложение TurboGears, поэтому я бы предпочел «pythonic» или менее уродливые решения. Копирование сбрасываемой таблицы на другой сервер через FTP/SCP или что-то в этом роде может быть быстрым, но в моих глазах это также очень (быстро и) грязно, и мне бы хотелось, чтобы у вас было более приятное решение.

Может ли кто-нибудь коротко описать, как вы будете делать это «наилучшим образом»?

Это необязательно должно включать базы данных. Сбрасывание таблицы на Server1 и передача необработанных данных структурированным способом, так что server2 может обрабатывать его без синтаксического анализа слишком хорошо. Одно требование: как только данные поступают на server2, я хочу, чтобы он обрабатывался, поэтому при передаче происходит какое-то уведомление. Конечно, я мог бы просто написать весь свой сервер, сидящий на сокете на втором компьютере, и принять файл с собственным кодом и обработать его и т. Д., Но это всего лишь очень маленький кусок очень большой системы, поэтому я не могу хотите потратить полдня на это.

Спасибо,

Том

ответ

2

Сервер 1: Преобразование строки в JSON, вызовите RESTful API из вторых с данными JSON

Сервер 2: прослушивает URI, например, POST/data, get json data конвертировать обратно в словарь или объекты ORM, вставить в db

sqlalchemy/sqlobject и simplejson - это то, что вам нужно.

0

Если предположить, что ситуация позволяет это с точки зрения безопасности, вы забыли один транспортный механизм: просто открыть соединение MySQL с одного сервера на другой.

Я начал бы думать о одном скрипте, который регулярно запускался на сервере записи и открывал только чтение db-соединения на сервере чтения (бит дополнительной безопасности) и полное соединение с его собственным сервером базы данных.

Как вы продолжаете, зависит от данных (это просто вставки, с которыми нужно иметь дело? Вам нужно зеркалировать удаление? Сколько вставок и обновлений? И т. Д.), Но в основном вы можете написать скрипт, который вытащил данные с сервера чтения и немедленно обработал его на сервере записи.

Кроме того, будет ли работать репликация сервера mysql или будет ли она перевернута как решение?

0

Если у вас есть доступ к порту данных MySQL и не против постоянного сетевого трафика, вы можете использовать replication.

1

Если таблица небольшая, и вы можете отправить всю таблицу и просто удалить старые данные, а затем вставить новые данные на удаленный сервер - тогда может быть простое общее решение: вы можете создать длинную строку с данными таблицы и отправить его через webservice. Вот как это можно реализовать.Отметим, что это далеко не идеальное решение, просто пример того, как я передавать небольшие простые таблицы между сайтов:

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; 
} 

Если у вас есть большие таблицы, то я думаю, что вам нужно отправить только новые данные. Запросите свой удаленный сервер на самую последнюю временную метку, а затем прочитайте все новые данные с вашего основного сервера и отправьте данные в общем виде (как показано выше) или в не общий (в этом случае вам нужно написать отдельный функции для каждой таблицы).

0

Если вы используете таблицы MyISAM или Архив, тогда я бы очень рекомендовал mysqlhotcopy