Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
The community reviewed whether to reopen this question 2 years ago and left it closed:
Original close reason(s) were not resolved
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
简介
PHP 具有完整的多线程支持,您可以通过多种方式充分利用它。已经能够在不同的示例中演示这种多线程能力:
快速搜索 将提供额外资源。
类别
1:MySQL 查询
MySQL 是完全多线程的,并且将利用多个 CPU,只要操作系统支持它们,如果正确配置性能,它还可以最大限度地利用系统资源。
my.ini
中影响线程性能的典型设置是:thread_cache_size 以提高性能。通常,如果您有良好的线程实现,这不会提供显着的性能改进。但是,如果您的服务器每秒看到数百个连接,您通常应该将 thread_cache_size 设置得足够高,以便大多数新连接使用缓存线程
如果您使用的是 Solaris 那么你可以使用
thread_concurrency 使应用程序能够向线程系统提供有关应同时运行的所需线程数的提示。
该变量从 MySQL 5.6.1 开始已弃用,并在 MySQL 5.7 中删除。只要您看到它,就应该从 MySQL 配置文件中删除它,除非它们适用于 Solaris 8 或更早版本。
InnoDB::
如果您使用Innodb 有存储引擎,因为它完全支持线程并发。
您还可以查看
innodb_read_io_threads
和innodb_write_io_threads
,其中默认值是4
,根据硬件的不同,它可以增加到64
其他:
其他需要考虑的配置包括
key_buffer_size< /code> 、
table_open_cache
、sort_buffer_size
等,这些都会带来更好的性能PHP:
在纯 PHP 中,您可以创建 MySQL Worker,其中每个查询在单独的 PHP 线程中执行
这是 SQLWorker 的完整工作示例
2:HTML内容解析
如果您已经知道问题,那么通过事件循环、作业队列或使用线程来解决会更容易。
一次处理一个文档可能是一个非常非常缓慢且痛苦的过程。 @ka 曾经使用 ajax 破解了调用多个请求的方法,一些有创造力的人只会使用 pcntl_fork 但如果您使用的是
windows
那么您可以不利用pcntl
由于
pThreads
同时支持 Windows 和 Unix 系统,您就没有这样的限制。就像..一样简单,如果您需要解析 100 个文档?生成 100 个线程...简单HTML 扫描
输出
使用的类
Sink
LinkParser
<尝试
在没有线程的情况下解析具有
105,109
链接的8,714
文件,看看需要多长时间。更好的架构
产生太多线程,这在生产中并不是一件明智的事情。更好的方法是使用 池化。有一个定义 Workers 的池,然后 堆栈 与
任务
性能改进
很好,上面的例子仍然可以改进。您可以使用多个线程来扫描我的系统中的文件,然后将数据堆栈到 Workers 中进行处理,而不是等待系统在单个线程中扫描所有文件
3:搜索索引更新
第一个答案已经基本回答了这个问题,但是提高性能的方法有很多。您是否考虑过基于事件的方法?
介绍活动
@rdlowrey 引用 1:
@rdlowrey 引用2:
为什么不尝试使用
事件驱动
、非阻塞 I/O
方法来解决您的问题。 PHP 有 libevent 来增强您的应用程序。我知道这个问题都是
多线程
,但如果你有时间,你可以看看这个核反应堆由 @igorw 用 PHP 编写最后
考虑
我认为你应该考虑使用
Cache 和
Job Queue
用于某些任务。您可以轻松收到一条消息,说“然后在后台执行所有浪费时间的任务”。请查看缩小大型处理作业以获取类似的信息案例研究。
分析
分析工具?从 Xdebug 到 Yslow 都非常有用。例如。 Xdebug 在处理线程时没有什么用处,因为它不受支持
我没有最喜欢的
Introduction
PHP has full Multi-Threading support which you can take full advantage of in so many ways. Have been able to demonstrate this Multi-Threading ability in different examples:
A quick Search would give additional resources.
Categories
1: MySQL queries
MySQL is fully multi-threaded and will make use of multiple CPUs, provided that the operating system supports them, It would also maximize system resources if properly configured for performance.
A typical setting in the
my.ini
that affect thread performance is :thread_cache_size can be increased to improve performance if you have a lot of new connections. Normally, this does not provide a notable performance improvement if you have a good thread implementation. However, if your server sees hundreds of connections per second you should normally set thread_cache_size high enough so that most new connections use cached threads
If you are using Solaris then you can use
thread_concurrency enables applications to give the threads system a hint about the desired number of threads that should be run at the same time.
This variable is deprecated as of MySQL 5.6.1 and is removed in MySQL 5.7. You should remove this from MySQL configuration files whenever you see it unless they are for Solaris 8 or earlier.
InnoDB: :
You don't have such limitations if you are using Innodb has the storage engine because it full supports thread concurrency
You can also look at
innodb_read_io_threads
andinnodb_write_io_threads
where the default is4
and it can be increased to as high as64
depending on the hardwareOthers:
Other configurations to also look at include
key_buffer_size
,table_open_cache
,sort_buffer_size
etc. which cal all result in better performancePHP:
In pure PHP you can create MySQL Worker where each query are executed in separate PHP threads
Here is a Full Working Example of SQLWorker
2: HTML content parsing
If you already know the problem then it makes it easier to solve via event loops , Job Queue or using Threads.
Working on one document one at a time can be a very, very slow, painful process. @ka once hacked his way out using ajax to calling multiple request, Some Creative minds would just fork the process using pcntl_fork but if you are using
windows
then you can not take advantage ofpcntl
With
pThreads
supporting both windows and Unix systems, You don't have such limitation. Is as easy as .. If you need to parse 100 document? Spawn 100 Threads ... SimpleHTML Scanning
Output
Class Used
Sink
LinkParser
Experiment
Trying parsing
8,714
files that have105,109
links without threads and see how long it would take.Better Architecture
Spawning too many threads which is not a clever thing to do In production. A better approch would be to use Pooling. Have a pool of define Workers then stack with a
Task
Performance Improvement
Fine, the example above can still be improved. Instead of waiting for the system to scan all files in a single thread you can use multiple threads to scan my system for files then stack the data to Workers for processing
3: Search index updating
This has been pretty much answered by the first answer, but there are so many ways for performance improvement. Have you ever considered an Event based approach?
Introducing Event
@rdlowrey Quote 1:
@rdlowrey Quote 2:
Why don't you experiment with
event-driven
,non-blocking I/O
approach to your problem. PHP has libevent to supercharge your application.I know this question is all
Multi-Threading
but if you have some time you can look this Nuclear Reactor written in PHP by @igorwFinally
Consideration
I think you should consider using
Cache
andJob Queue
for some of your tasks. You can easily have a message sayingThen do all the time wasting tasks in the background. Please look at Making a large processing job smaller for a similar case study.
Profiling
Profiling Tool? There is no single profile tool for a web application from Xdebug to Yslow are all very useful. Eg. Xdebug is not useful when it comes to threads because its not supported
I don't have a favorite
PHP 并不完全面向多线程:正如您已经注意到的,每个页面都由一个 PHP 进程提供服务——它一次只做一件事,包括在数据库服务器上执行 SQL 查询时只是“等待”。
不幸的是,对此您无能为力:这就是 PHP 的工作方式。
不过,这里有一些想法:
所以,事实上,您的服务器的 8 个核心最终将被使用;-)
而且,如果您认为生成页面的时间太长,一个可能的解决方案是将计算分为两组:
对于我的第二点中的那种情况,因为你不需要立即完成这些事情......好吧,只是不要立即做;-)
我经常使用的一个解决方案是某种排队机制:
,对于某些批次其他操作,您只希望它们每 X 分钟运行一次 - 而且,在这里,cronjob 也是完美的工具。
PHP is not quite oriented towards multi-threading : as you already noticed, each page is served by one PHP process -- that does one thing at a time, including just "waiting" while an SQL query is executed on the database server.
There is not much you can do about that, unfortunately : it's the way PHP works.
Still, here's a couple of thoughts :
So, in fact, your server's 8 core will end up being used ;-)
And, if you think your pages are taking too long to generate, a possible solution is to separate your calculations in two groups :
For the kind of situations in my second point, as you don't need those things done immediately... Well, just don't do them immediately ;-)
A solution that I often use is some queuing mechanism :
And for some other manipulations, you just want them run every X minutes -- and, here too, a cronjob is the perfect tool.
在访问多核 CPU 方面,横向扩展 Web 服务器并不会让 MySQL 做出一寸的让步。为什么?首先考虑MySQL的两个主要存储引擎
MyISAM
该存储引擎不访问多个核心。它从来没有,也永远不会。它对每个 INSERT、UPDATE 和 DELETE 执行全表锁定。从多个 Web 服务器发送查询来使用 MyISAM 执行任何操作都会遇到瓶颈。
InnoDB
在 MySQL 5.1.38 之前,该存储引擎仅访问了一个CPU。你必须做一些奇怪的事情,比如在一台机器上多次运行MySQL强制核心处理 MySQL 的不同实例。然后,在多个实例之间平衡 Web 服务器的数据库连接负载。这是老派的做法(特别是如果您使用的是 MySQL 5.1.38 之前的 MySQL 版本)。
从 MySQL 5.1.38 开始,安装新的 InnoDB 插件。为了让 InnoDB 访问多个 CPU,您必须调整它的一些功能。我在 DBA StackExchange
2011 年 9 月 20 日
中写过相关内容Sep 12, 2011
: 可以让 MySQL 使用多个核心吗?2011 年 5 月 26 日
:关于单线程与多线程数据库性能这些新功能完全也可在 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)2011 年 10 月 5 日
: 查询在某些较新的 MySQL 版本中运行时间较长2011 年 6 月 19 日
: 如何正确执行 MySQL 烘焙?Scaling out Web Servers is not going to make MySQL budge one inch when it comes to accessing Multicore CPUs. Why? First consider the two main Storage Engines of MySQL
MyISAM
This storage engine does not access multiple cores. It never has and never will. It does full table locking for each INSERT, UPDATE, and DELETE. Sending queries from multiple Web Servers to do anything with a MyISAM just gets bottlenecked.
InnoDB
Prior to MySQL 5.1.38, this storage engine has accessed only one CPU. You had to do strange things like run MySQL multiple times on one machine to coerce the cores to handle different instances of MySQL. Then, have the Web Servers' DB connections load balanced among the multiple instances. That's old school (especially if you are using versions of MySQL before MySQl 5.1.38).
Starting with MySQL 5.1.38, you install the new InnoDB Plugin. It has features that you have to tune for getting InnoDB to access multiple CPUs. I have written about this in the DBA StackExchange
Sep 20, 2011
: Multi cores and MySQL PerformanceSep 12, 2011
: Possible to make MySQL use more than one core?May 26, 2011
: About single threaded versus multithreaded databases performanceThose new features are fully available in MySQL 5.5/5.6 and Percona Server as well.
CAVEAT
If your custom CMS uses FULLTEXT indexing/searching, you should upgrade to MySQL 5.6 because InnoDB now supports FULLTEXT indexing/searching.
Installing to MySQL 5.6 is not going to automatically make the CPUs get going. You will have to tune it because, LEFT UNCONFIGURED, it is possible for older versions of MySQL to outrun and outgun newer versions:
Nov 24, 2011
: Why mysql 5.5 slower than 5.1 (linux,using mysqlslap)Oct 05, 2011
: Query runs a long time in some newer MySQL versionsJun 19, 2011
: How do I properly perform a MySQL bake-off?这可能不是您正在寻找的问题的答案,但您寻求的解决方案涉及线程。线程对于多核编程是必要的,而线程在 PHP 中没有实现。
但是,从某种意义上说,您可以依靠操作系统的多任务处理能力来伪造 PHP 中的线程。我建议快速概述 多线程策略使用 PHP 制定策略来实现您的需求。
死链接:
PHP 中的多线程策略
This might not be an answer to the question you are looking for, but the solution you seek deals with threading. Threading is necessary for multicore-programming, and threading is not implemented in PHP.
But, in a sense, you could fake threading in PHP by relying on the operating system's multitasking abilities. I suggest given a quick overview of Multi-threading strategies in PHP to develop a strategy to achieve what you need.
Dead link:
Multi-threading strategies in PHP
只是让你们知道当您想到:“可怜的 PHP 没有多线程”
好吧... Python 也没有真正的多线程。 NodeJS 也不支持多线程。 Java 具有某种多线程功能,但即使如此,一些代码据我所知会停止整个机器。
但是:除非你对一件事进行大量编程,否则它是无关紧要的。许多请求都会到达您的页面,并且您的所有核心都将被使用,因为每个请求都会使用自己的单线程生成自己的进程。
Just letting you guys know when you think: "poor PHP does not have multithreading"
Well... Python doesn't have real multithreading either. Nor does NodeJS have multi-threading support. Java has some sort of multithreading, but even there, some code halts the whole machine afaik.
But: unless you do heavy programming of one single thing, it's irrelevant. Many requests hit your page and all your cores will be used none the less as each request spawns its own process with its own single thread.