jkn*_*rkn 32 php mysql multicore
我维护一个自定义的类似CMS的应用程序.
每当提交文档时,都会执行几项任务,这些任务可以大致分为以下几类:
类别1包括与文档内容相关的各种MySQL表的更新.
类别2包括解析存储在MySQL LONGTEXT字段中的HTML内容以执行一些自动锚标记转换.我怀疑在这项任务中花费了大量的计算时间.
类别3包括仅使用与文档对应的少数字段对基于MySQL的简单搜索索引的更新.
所有这些任务都需要完成才能使文档提交完整.
承载此应用程序的计算机具有双四核Xeon处理器(总共8个核心).但是,每当文档提交时,执行的所有PHP代码都被限制为在其中一个核上运行的单个进程.
我的问题:
您有多少方案(如果有的话)将PHP/MySQL Web应用程序处理负载分散到多个CPU内核中?我理想的解决方案基本上会产生一些进程,让它们在几个内核上并行执行,然后阻塞直到所有进程完成.
相关问题:
您最喜欢的PHP性能分析工具是什么?
Bab*_*aba 57
PHP具有完整的多线程支持,您可以在很多方面充分利用它.已经能够在不同的例子中展示这种多线程能力:
一个快速搜索将提供额外的资源.
MySQL是完全多线程的,并且将使用多个CPU,只要操作系统支持它们,如果正确配置性能,它还将最大化系统资源.
my.ini
影响线程性能的典型设置 是:
thread_cache_size = 8
Run Code Online (Sandbox Code Playgroud)
如果您有许多新连接,可以增加thread_cache_size以提高性能.通常,如果您有一个良好的线程实现,这不会提供显着的性能改进.但是,如果您的服务器每秒看到数百个连接,您通常应该将thread_cache_size设置得足够高,以便大多数新连接使用缓存的线程
如果您使用的是Solaris,则可以使用
thread_concurrency = 8
Run Code Online (Sandbox Code Playgroud)
thread_concurrency 使应用程序能够为线程系统提供有关应该同时运行的所需线程数的提示.
从MySQL 5.6.1开始,该变量已被弃用,并在MySQL 5.7中被删除.除非它们适用于Solaris 8或更早版本,否则无论何时看到它都应从MySQL配置文件中删除它.
InnoDB ::
如果您使用Innodb具有存储引擎,则没有此类限制,因为它完全支持线程并发
innodb_thread_concurrency // Recommended 2 * CPUs + number of disks
Run Code Online (Sandbox Code Playgroud)
您还可以看看innodb_read_io_threads
和innodb_write_io_threads
其中默认的是4
,它可以提高到高达64
取决于硬件
其他:
其他配置也看包括key_buffer_size
,table_open_cache
,sort_buffer_size
等这一切CAL导致更好的性能
PHP:
在windows
您可以创建MySQL的工人,这时每个查询都在单独的PHP线程执行
$sql = new SQLWorker($host, $user, $pass, $db);
$sql->start();
$sql->stack($q1 = new SQLQuery("One long Query"));
$sql->stack($q2 = new SQLQuery("Another long Query"));
$q1->wait();
$q2->wait();
// Do Something Useful
Run Code Online (Sandbox Code Playgroud)
pcntl
如果您已经知道问题,那么通过事件循环,作业队列或使用线程更容易解决.
一次处理一个文档可以是一个pThreads
.@ka曾经使用ajax调用多个请求来破解他的出路,有些创意人员只会使用pcntl_fork来分叉这个过程,但是如果你正在使用Sink
那么你就无法利用LinkParser
通过8,714
支持Windows和Unix系统,您没有这样的限制.就像..如果你需要解析一样容易105,109
?Task
......简单
HTML扫描
// Scan my System
$dir = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$dir = new RecursiveIteratorIterator($dir);
// Allowed Extension
$ext = array(
"html",
"htm"
);
// Threads Array
$ts = array();
// Simple Storage
$s = new Sink();
// Start Timer
$time = microtime(true);
$count = 0;
// Parse All HTML
foreach($dir as $html) {
if ($html->isFile() && in_array($html->getExtension(), $ext)) {
$count ++;
$ts[] = new LinkParser("$html", $s);
}
}
// Wait for all Threads to finish
foreach($ts as $t) {
$t->join();
}
// Put The Output
printf("Total Files:\t\t%s \n", number_format($count, 0));
printf("Total Links:\t\t%s \n", number_format($t = count($s), 0));
printf("Finished:\t\t%0.4f sec \n", $tm = microtime(true) - $time);
printf("AvgSpeed:\t\t%0.4f sec per file\n", $tm / $t);
printf("File P/S:\t\t%d file per sec\n", $count / $tm);
printf("Link P/S:\t\t%d links per sec\n", $t / $tm);
Run Code Online (Sandbox Code Playgroud)
产量
Total Files: 8,714
Total Links: 105,109
Finished: 108.3460 sec
AvgSpeed: 0.0010 sec per file
File P/S: 80 file per sec
Link P/S: 907 links per sec
Run Code Online (Sandbox Code Playgroud)
使用的类
event-driven
class Sink extends Stackable {
public function run() {
}
}
Run Code Online (Sandbox Code Playgroud)
non-blocking I/O
class LinkParser extends Thread {
public function __construct($file, $sink) {
$this->file = $file;
$this->sink = $sink;
$this->start();
}
public function run() {
$dom = new DOMDocument();
@$dom->loadHTML(file_get_contents($this->file));
foreach($dom->getElementsByTagName('a') as $links) {
$this->sink[] = $links->getAttribute('href');
}
}
}
Run Code Online (Sandbox Code Playgroud)
实验
尝试解析Multi-Threading
具有无线程Cache
链接的文件,并查看需要多长时间.
更好的架构
产生太多的线程,这在生产中不是一件聪明的事情.更好的方法是使用Pooling.有一个定义工作池然后与一个堆叠Job Queue
性能改进
上面的例子仍然很好my.ini
.等待系统扫描innodb_read_io_threads
您也可以 innodb_write_io_threads
查找文件,然后将数据堆叠到Workers进行处理
第一个答案几乎已经回答了这个问题,但是有很多方法可以提高性能.你有没有考虑过基于事件的方法?
@rdlowrey引用1:
好好想想这样.想象一下,您需要在Web应用程序中为10,000个同时连接的客户端提供服务.传统的线程每个请求或过程每个请求的服务器是不是一种选择,因为无论你怎么线程轻巧,你仍然无法追究他们10,000同时打开.
@rdlowrey引用2:
另一方面,如果将所有套接字保留在一个进程中并监听这些套接字是否可读或可写,则可以将整个服务器放在单个事件循环中,并且只有在有/可读/写的情况下才对每个套接字进行操作.
你为什么不试验4
,64
解决你的问题.PHP可以解放您的应用程序.
我知道这个问题就是这样,key_buffer_size
但是如果你有一些时间你可以看看这个由@igorw 用PHP编写的核反应堆
我认为你应该冷凝使用table_open_cache
和 sort_buffer_size
你的一些任务.您可以轻松地传达消息
Document uploaded for processing ..... 5% - Done
Run Code Online (Sandbox Code Playgroud)
然后一直在后台浪费任务.请查看为类似案例研究制作较小的大型处理工作.
分析工具?? 从Xdebug到Yslow的Web应用程序没有单一的配置文件工具都非常有用.例如.Xdebug在线程方面没有用处,因为它不受支持
我没有最爱
Pas*_*TIN 37
PHP并不是面向多线程的:正如您已经注意到的,每个页面都由一个PHP进程提供服务 - 它一次完成一件事,包括在数据库服务器上执行SQL查询时"等待".
遗憾的是,你无能为力:这就是PHP的工作方式.
不过,这里有几个问题:
所以,事实上,你的服务器的8核将最终被使用;-)
而且,如果您认为您的页面生成时间太长,可能的解决方案是将您的计算分为两组:
对于我的第二点中的那种情况,因为你不需要立即完成这些事情......好吧,不要立即做到这些;-)
我经常使用的解决方案是一些排队的机制:
对于其他一些操作,你只需要每X分钟运行一次 - 而且,这里也是一个完美的工具.
在访问多核 CPU 方面,横向扩展 Web 服务器并不会让 MySQL 做出一寸的让步。为什么?首先考虑MySQL的两个主要存储引擎
该存储引擎不访问多个核心。它从来没有,也永远不会。它对每个 INSERT、UPDATE 和 DELETE 执行全表锁定。从多个 Web 服务器发送查询来使用 MyISAM 执行任何操作都会遇到瓶颈。
在MySQL 5.1.38之前,该存储引擎仅访问一个CPU。您必须做一些奇怪的事情,例如在一台机器上多次运行 MySQL 来强制内核处理不同的 MySQL 实例。然后,在多个实例之间平衡 Web 服务器的数据库连接负载。这是老派的做法(特别是如果您使用的是 MySQL 5.1.38 之前的 MySQL 版本)。
从 MySQL 5.1.38 开始,安装新的 InnoDB 插件。为了让 InnoDB 访问多个 CPU,您必须调整它的一些功能。我已经在 DBA StackExchange 中写过相关内容
Sep 20, 2011
:多核和 MySQL 性能Sep 12, 2011
:可以让MySQL使用多个核心吗?May 26, 2011
:关于单线程与多线程数据库性能这些新功能在 MySQL 5.5/5.6 和 Percona Server 中也完全可用。
如果您的自定义 CMS 使用全文索引/搜索,您应该升级到 MySQL 5.6,因为 InnoDB 现在支持全文索引/搜索。
安装 MySQL 5.6 不会自动让 CPU 运行。您必须对其进行调整,因为在未配置的情况下,旧版本的 MySQL 可能会超越新版本:
Nov 24, 2011
:为什么mysql 5.5比5.1慢(linux,使用mysqlslap)Oct 05, 2011
:在一些较新的 MySQL 版本中查询运行时间很长Jun 19, 2011
:如何正确执行 MySQL 烘焙? 归档时间: |
|
查看次数: |
56093 次 |
最近记录: |