1

我需要在 Web 应用程序上实现消息传递系统。它由 PHP 和 MySQL 提供支持,允许注册用户互相发送消息。

所以我担心的是:在我让网站运行两年后,它会获得成千上万的用户和几十个朋友,他们每个人都会在这段时间里互相发送数百万条消息,之后会发生什么?

IT 行业的“大佬”是如何处理这些问题的,例如 Facebook?当然,他们的消息不能全部放入一个表(MySQL 或其他)......但即使在(一个)存档表中传输旧消息也不会永远有效。

我绝不会建立一个可以与 Facebook 相媲美的网站,但我仍然想要一个在一两年后不会出错的解决方案。

4

3 回答 3

3

“大男孩”使用分片。在最基本的层面上,这会将以字母“A”开头的用户放在数据库服务器“A”上,“B”放在“B”上,等等。但要明确的是,“大男孩”有数十亿消息,而不是数百万。MySQL 应该可以处理数亿条记录。如果设计不当,您的查询可能会变慢。

我曾经创建了一个基于 MySQL 的消息传递系统,每月处理大约 5000 万条消息。我们只保持了过去 3 个月的“活跃”,任何较旧的东西都在一个访问速度较慢的存档区域中。

老实说,如果你能设计一个 2 年后不需要保姆的系统,那你就太棒了!

于 2012-12-16T19:44:18.783 回答
1

搜索 SQL BIGINT 的最大值。几年前,当我在 32 位机器上编写这个脚本时,它曾经溢出。现在问题少了很多!

http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html

http://www.laprbass.com/RAY_integer_overflow.php

<?php // RAY_integer_overflow.php
error_reporting(E_ALL);
echo "<pre>\n";

// CONNECTION AND SELECTION VARIABLES FOR THE DATABASE
$db_host = "localhost"; // PROBABLY THIS IS OK
$db_name = "??";        // GET THESE FROM YOUR HOSTING COMPANY
$db_user = "??";
$db_word = "??";

// OPEN A CONNECTION TO THE DATA BASE SERVER
// MAN PAGE: http://us2.php.net/manual/en/function.mysql-connect.php
if (!$dbcx = mysql_connect("$db_host", "$db_user", "$db_word"))
{
   $errmsg = mysql_errno() . ' ' . mysql_error();
   echo "<br/>NO DB CONNECTION: ";
   echo "<br/> $errmsg <br/>";
}

// SELECT THE MYSQL DATA BASE
// MAN PAGE: http://us2.php.net/manual/en/function.mysql-select-db.php
if (!$db_sel = mysql_select_db($db_name, $dbcx))
{
   $errmsg = mysql_errno() . ' ' . mysql_error();
   echo "<br/>NO DB SELECTION: ";
   echo "<br/> $errmsg <br/>";
   die('NO DATA BASE');
}

// CREATE A TABLE AND ALTER IT TO A HIGH INDEX NUMBER
$sql = "CREATE TEMPORARY TABLE noise ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ) ENGINE=MEMORY";
if (!$res = mysql_query($sql)) die(mysql_error());

$sql = "ALTER TABLE noise AUTO_INCREMENT = 2147483646";
if (!$res = mysql_query($sql)) die(mysql_error());


// INSERT DATA TO ADD TO THE AUTO_INCREMENT INDEX
$kount = 0;
while ($kount < 15)
{
   $sql = "INSERT INTO noise () VALUES ()";
   if (!$res = mysql_query($sql)) die(mysql_error());
   $nid = mysql_insert_id($dbcx);
   var_dump($nid);
   $kount++;
}

根据我的粗略计算,如果您以每秒 1,000 条的速度聚合消息,并且您使用 UNSIGNED BIGINT 作为 AUTO_INCREMENT 键,那么您将在大约 570,000,000 年内遇到溢出。因此,或多或少地,如果您以每秒 1,000,000,000 条的速度收集消息,那么您将在更短的时间内遇到问题——也许从现在起大约 570 年。但好消息是,如果你以每秒 100,000 条的速度收集消息,VC 社区就会向你砸钱!

于 2012-12-16T19:36:04.840 回答
-1

在第一步中对表进行分区(根据您的设计,根据日期、用户 ID、区域或任何其他基础)。我相信您可以长期使用此解决方案。下一步将分片您的消息系统。即使在此更改之后,您也可以像facebook一样选择 HBase 。

于 2012-12-16T19:37:36.537 回答