Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP/MySQL应用程序中充分利用多核CPU?_Php_Mysql_Multicore - Fatal编程技术网

如何在PHP/MySQL应用程序中充分利用多核CPU?

如何在PHP/MySQL应用程序中充分利用多核CPU?,php,mysql,multicore,Php,Mysql,Multicore,我维护一个定制的类似CMS的应用程序 每当提交文档时,都会执行若干任务,这些任务大致可分为以下几类: MySQL查询 HTML内容解析 搜索索引更新 类别1包括与文档内容相关的各种MySQL表的更新 类别2包括对MySQL LONGTEXT字段中存储的HTML内容进行解析,以执行一些自动锚定标记转换。我怀疑这项任务花费了大量的计算时间 类别3包括对一个简单的基于MySQL的搜索索引的更新,它只使用与文档相对应的几个字段 所有这些任务都需要完成,才能将文件提交视为完成 承载此应用程序的机器具有双四

我维护一个定制的类似CMS的应用程序

每当提交文档时,都会执行若干任务,这些任务大致可分为以下几类:

  • MySQL查询
  • HTML内容解析
  • 搜索索引更新
  • 类别1包括与文档内容相关的各种MySQL表的更新

    类别2包括对MySQL LONGTEXT字段中存储的HTML内容进行解析,以执行一些自动锚定标记转换。我怀疑这项任务花费了大量的计算时间

    类别3包括对一个简单的基于MySQL的搜索索引的更新,它只使用与文档相对应的几个字段

    所有这些任务都需要完成,才能将文件提交视为完成

    承载此应用程序的机器具有双四核Xeon处理器(共8核)。然而,每当文档提交时,所有执行的PHP代码都被限制在一个内核上运行的单个进程中

    我的问题:

    您使用了哪些方案(如果有的话)将PHP/MySQL web应用程序的处理负载分配到多个CPU核中?我的理想解决方案基本上是生成几个进程,让它们在几个内核上并行执行,然后阻塞,直到所有进程都完成

    相关问题:


    您最喜欢的PHP性能评测工具是什么

    这可能不是您要寻找的问题的答案,但您寻求的解决方案涉及线程。线程是多核编程所必需的,而线程不是在PHP中实现的

    但是,从某种意义上说,您可以通过依赖操作系统的多任务处理能力来伪造PHP中的线程。我建议快速概述一下,制定一个战略,以实现您的需求

    死链接:

    PHP并不完全面向多线程:正如您已经注意到的,每个页面都由一个PHP进程提供服务——一次只做一件事,包括在数据库服务器上执行SQL查询时“等待”

    不幸的是,您对此无能为力:这就是PHP的工作方式


    不过,这里有一些想法:

    • 首先,您的服务器上一次可能有多个用户,这意味着您将同时提供多个页面,这反过来意味着您将同时运行多个PHP进程和SQL查询。。。这意味着将使用服务器的多个核心。
      • 每个PHP进程将在一个内核上运行,以响应一个用户的请求,但Apache有几个并行运行的子进程(每个请求一个,最多几十个或几百个,取决于您的配置)
      • MySQL服务器是多线程的,这意味着它可以使用多个不同的内核来响应多个并发请求——即使每个请求不能由多个内核提供服务
    因此,实际上,服务器的8核最终将被使用;-)


    而且,如果您认为生成页面花费的时间太长,一个可能的解决方案是将计算分为两组:

    • 一方面,生成页面所必须做的事情:对于这些,您所能做的并不多
    • 另一方面,有时必须运行的东西,但不一定是立即运行的
      • 例如,我在考虑一些统计计算:你希望它们是最新的,但如果它们落后几分钟,通常是可以的
      • 电子邮件发送也一样:无论如何,用户在接收/阅读邮件之前需要几分钟,因此无需立即发送邮件
    对于我第二点提到的那种情况,因为你不需要立即完成这些事情。。。好吧,只是不要马上做;-)
    我经常使用的解决方案是某种排队机制:

    • web应用程序将内容存储在“待办事项列表”中
    • 而且“待办事项列表”由一些通过cronjob频繁运行的批处理取消排队
    对于其他一些操作,您只希望它们每X分钟运行一次——在这里,cronjob也是一个完美的工具。

    简介 PHP提供了全面的支持,您可以通过多种方式充分利用它。我们已经能够在不同的示例中演示这种多线程能力:

    A将提供额外资源

    类别 1:MySQL查询 并且将使用多个CPU,只要操作系统支持它们,如果为性能正确配置,它还将最大限度地利用系统资源

    my.ini
    中影响线程性能的典型设置是:

    thread_cache_size = 8
    
    如果您有很多新连接,可以通过增加来提高性能。通常,如果您有一个好的线程实现,这不会提供显著的性能改进。但是,如果服务器每秒看到数百个连接,通常应将线程缓存大小设置得足够高,以便大多数新连接使用缓存线程

    如果您正在使用,那么您可以使用

    thread_concurrency = 8 
    
    使应用程序能够向线程系统提示应同时运行的所需线程数

    此变量在MySQL 5.6.1中已弃用,并在MySQL 5.7中删除。您应该在看到MySQL配置文件时将其从中删除,除非它们适用于Solaris 8或更早版本

    InnoDB::

    如果您使用的是has存储引擎,则不会有这样的限制,因为它完全支持线程并发

    innodb_thread_concurrency //  Recommended 2 * CPUs + number of disks
    
    您还可以查看
    innodb_read_io_threads
    innodb_write_io_threads
    ,其中默认值为
    4
    ,并且可以将其增加到高达
    64$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
    
    // 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);
    
    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
    
    class Sink extends Stackable {
        public function run() {
        }
    }
    
    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');
            }
        }
    }
    
    Document uploaded for processing ..... 5% - Done