2009-06-25 35 views
2

我有一个坐在“主服务器”上的系统,它定期从MySQL数据库中将相当多的信息块传输到网络中的另一台服务器。将MySQL表传输到另一台服务器的最佳实践?

两台服务器都有一个MySQL服务器和一个Apache正在运行。我想为此提供一个易于使用的解决方案。

目前我正在寻找到:

  • XMLRPC
  • RESTful服务
  • 一个简单的POST来处理脚本
  • 插座传输

我的主应用程序是一个TurboGears应用程序,所以我宁愿“pythonic”又不太难看的解决方案。通过FTP/SCP或其他类似的方法将倾销的表格复制到另一台服务器上可能会很快,但在我眼中,它也非常(快速)脏,我希望有一个更好的解决方案。

任何人都可以很快描述如何做到这一点“最佳实践”的方式?

这不一定涉及数据库。在Server1上转储表并以结构化方式传输原始数据,以便server2可以在不解析太多的情况下处理它,这一点同样出色。但有一个要求:一旦数据到达server2,我希望它被处理,所以当传输完成时必须有某种类型的通知。当然,我可以把我自己的服务器写在第二台机器上的一个套接字上,然后用自己的代码接受这个文件并处理它,等等,但这只是一个非常小的系统,所以我不会希望花半天时间来实现这一点。

感谢,

汤姆

回答

2

服务器1:转换行JSON,调用第二REST式API使用JSON数据

服务器2:侦听上的URI例如POST /数据,将json数据转换回字典或ORM对象,插入到分区中。sqlalchemy/sqlobject和simplejson是您所需要的。

0

假设条件允许这种安全,明智的,你忘了一个传输机制:简单地打开从一台服务器到另一个MySQL连接。

我会先考虑一下在写入服务器上定期运行的脚本,并打开与读取服务器的只读数据库连接(增加一点安全性)并完全连接到它自己的数据库服务器。

你如何继续进行取决于数据(它只是插入处理?你必须镜像删除?多少插入与更新?等),但基本上你可以写一个脚本,从读服务器拉数据并立即将其处理到写入服务器中。

此外,将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或Archive表格,那么我强烈推荐mysqlhotcopy

相关问题