我有一个非常特殊的问题。 我有一个在Apache2.4下的ubuntu服务器上运行的网站。 该站点是用PHP编写的,并使用MySQL作为数据库。 我已经意识到"文件存储"对于MySQL数据库中的小文件为longblobs。
当我想从MySQL数据库下载blob /文件时,我打开了一个到数据库的PDO连接。
$sql = $pdoData->prepare("SELECT * FROM fileblob WHERE ID = ?");
$sql->execute(array($blobID));
$row = $sql->fetch();
$content = $row['data'];
via" echo $ content"然后我将文件传输到浏览器。 所有这一切都完美无瑕。然而。在下载过程中,整个站点停止响应,每个新请求都会进入超时状态。 下载继续正常。
当下载量达到4MB时,网站会再次开始运行,但速度非常慢。完成后,该网站完全恢复正常。
MySQL数据库使用InnoDB后端,最多有500个并发连接等。
在下载期间,只有6个开放的SQL连接。 磁盘使用率最高约为20%,CPU使用率低于10% Apache也设置为处理1k并发连接(10个线程,最多100个子节点)。服务器通过未计量的1Gbps线路连接。 我想不出任何硬件瓶颈。
我错过了什么? 我很乐意回答任何问题......
答案 0 :(得分:0)
当您使用PHP的默认基于文件的会话机制时,PHP会在访问该特定会话的任何脚本运行时锁定会话数据文件。
因此,当您的下载正在运行时,会话数据文件始终保持打开状态,并且阻止任何其他脚本访问同一会话 - 它们只需等待,直到再次释放文件锁定。
为了帮助防止这种情况,可以使用session_write_close
。它告诉PHP当前脚本是通过操作会话数据来完成的,这样会话内容就可以立即写入数据文件,并释放文件锁,以便其他脚本可以再次访问它。
(您显然需要在此时完成会话数据操作;之后不能在同一个脚本中再次更改会话内容。)