代码之家  ›  专栏  ›  技术社区  ›  MD Sayem Ahmed

在PDO中使用持久连接的缺点是什么

  •  168
  • MD Sayem Ahmed  · 技术社区  · 14 年前

    在PDO中,可以使用 PDO::ATTR_PERSISTENT 属性。根据php手册-

    持久连接不会在脚本结束时关闭,而是 当另一个脚本使用 同样的证书。持久连接缓存允许您 脚本需要与数据库对话,从而实现更快的web服务 应用程序。

    所以显然,在PDO中使用持久连接似乎没有缺点,除了最后一种情况。但是,我想知道使用这种机制是否还有其他缺点,即这种机制会导致性能下降或类似的情况。

    8 回复  |  直到 12 年前
        1
  •  294
  •   Community Neeleshkumar S    7 年前

    请务必阅读 this answer below ,其中详细介绍了缓解此处概述的问题的方法。


    使用PDO和使用任何其他PHP数据库接口进行持久连接时都存在相同的缺点:如果脚本在数据库操作过程中意外终止,那么获得剩余连接的下一个请求将从死脚本停止的地方开始。连接在进程管理器级别(Apache for mod\u php,如果您使用的是FastCGI,则为当前的FastCGI进程等)保持打开,而不是在php级别,并且php不会告诉父进程在脚本异常终止时让连接终止。

    如果死脚本锁定了表,则这些表将保持锁定状态,直到连接终止或获取连接的下一个脚本解锁表本身。

    如果死脚本位于事务的中间,则获取该连接的下一个脚本也会获取事务状态。很有可能(取决于您的应用程序设计)下一个脚本实际上从未尝试提交现有事务,或者在不应该提交事务时提交,或者在不应该提交事务时回滚。

    这只是冰山一角。通过总是尝试在每个脚本请求上的脏连接之后进行清理,可以在一定程度上缓解这些问题,但这可能是一个难题,具体取决于数据库。除非您已将创建数据库连接标识为 在脚本中(这意味着您已经使用 xdebug xhprof ),你应该 将持久连接视为任何问题的解决方案。

    此外,大多数现代数据库(包括PostgreSQL)都有自己喜欢的执行连接池的方法,这些方法没有普通的基于PHP的持久连接所具有的直接缺点。


    为了澄清一点,我们在我的工作场所使用持久的联系,但不是出于选择。我们遇到了 奇怪的 连接行为,从应用程序服务器到数据库服务器的初始连接 确切地

    不管怎样,当仓库里的人在处理几百个来料零件时,每个零件都要用3.5秒而不是半秒,我们必须在他们绑架我们并让我们帮助他们之前采取行动。因此,我们在自己开发的ERP/CRM/CMS怪物系统中翻了几页,亲身体验了持久连接的所有恐怖。它把我们带走了

    这个可悲的故事有一点: 它打破了我们从未想过会打破的东西,都是以表演的名义。 这种折衷是不值得的,我们急切地等待着有一天我们可以切换回正常的连接,而不会引起用户的骚动。

        2
  •  49
  •   Shankar Narayana Damodaran    9 年前

    发件人: http://www.php.net/manual/en/mysqli.quickstart.connections.php

    关于持久连接的一个常见抱怨是在重用之前它们的状态没有重置。例如,打开的和未完成的事务不会自动回滚。但是,在将连接放入池和重用池之间发生的授权更改也没有反映出来。这可能被视为一种不必要的副作用。相反,持久化的名称可以理解为国家被持久化的承诺。

    mysqli扩展支持持久连接的两种解释:状态持久化和重用前的状态重置。默认值为重置。在重用持久连接之前,mysqli扩展隐式调用 mysqli_change_user()

    这个 mysqli\u change\u user() 功能是一项昂贵的操作。为了获得最佳性能,用户可能希望使用compile标志重新编译扩展 MYSQLI_NO_CHANGE_USER_ON_PCONNECT

    用户可以在安全行为和最佳性能之间进行选择。两者都是有效的优化目标。为便于使用,安全行为已被设置为默认值,但以牺牲最大性能为代价。

        3
  •  14
  •   Gunnar Bernstein Jerfov2    11 年前

    在我的测试中,我与本地主机的连接时间超过一秒,因此假设我应该使用持久连接。进一步的测试表明这是“localhost”的问题:

    • 托管网站:connectDB:0.0038912296295166
    • localhost:connectDB:1.0214691162109(超过一秒钟:不要使用localhost!)
    • 127.0.0.1:连接数据库:0.00097203254699707

    $host = gethostbyname('localhost');
    // echo "<p>$host</p>";
    $db = new PDO("mysql:host=$host;dbname=" . DATABASE . ';charset=utf8', $username, $password,
        array(PDO::ATTR_EMULATE_PREPARES => false,
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    
        4
  •  13
  •   Community Neeleshkumar S    7 年前

    只有当连接到数据库需要(相对)较长的时间时,持久连接才是一个好主意。现在几乎从来都不是这样。持久连接的最大缺点是它限制了可以浏览站点的用户数:如果MySQL配置为一次只允许10个并发连接,那么当第11个人试图浏览站点时,它将不适用于他们。

    PDO不管理持久性。MySQL驱动程序可以。当a)连接可用且主机/用户/密码/数据库匹配时,它将重用连接。如果有任何更改,则不会重用连接。最好的净效果是,这些连接你将启动和停止如此频繁,因为你有不同的用户在网站上,使他们持久没有任何好处。

    我肯定还有其他线程,但是持久连接是危险的,因为它在请求之间持续存在。例如,如果您在请求期间锁定一个表,但未能解锁,则该表将无限期地保持锁定。对于99%的应用程序来说,持久连接也非常无用,因为你无法知道不同请求之间是否会使用相同的连接。每个web线程都有自己的一组持久连接,您无法控制哪个线程将处理哪些请求。


    资源链接: link

    ,使用持久连接,如果:

    • 只有少数应用程序/用户访问数据库,即。 不会导致200个打开的(但可能是空闲的)连接,
    • 数据库正在您正在访问的另一台服务器上运行

    • 一(一)个应用程序经常访问数据库

    ,不使用持久连接,如果:

    • 您有许多Web服务器访问一个数据库服务器

    使用持久连接的速度相当快,尤其是在通过网络访问数据库时。如果数据库在同一台机器上运行,不会有太大的区别,但是速度还是快了一点。然而,正如名字所说,连接是持久的,即它保持打开,即使它没有被使用。

    因此:只用于有大量请求的应用程序。

        5
  •  7
  •   Stephen    13 年前

    听起来,上面的抱怨是有人使用MyIASM表,并通过获取表锁来侵入自己版本的事务。。你当然会死锁的!使用PDO的beginTransaction()并将表移到InnoDB。。

        6
  •  2
  •   CrayonViolent    14 年前

        7
  •  1
  •   Tony Stark Kshitij Gupta    11 年前

    使用持久连接的原因显然是减少了成本高昂的连接数量,尽管MySQL的连接速度比其他数据库快得多。

    持续连接的第一个问题。。。

    如果每秒创建1000个连接,通常不能确保它保持打开状态很长时间,但操作系统会这样做。基于TCP/IP协议的端口不能立即回收,而且在回收之前还需要在FIN阶段等待一段时间。

    许多人根本没有意识到你能够增加*max\u connections*变量,并获得100多个MySQL并发连接,其他人则被老Linux的问题打败,即无法用MySQL传输1024多个连接。

    现在可以讨论为什么mysqli扩展中禁用了持久连接。尽管事实上,您可能会误用持久连接并获得较差的性能,而这并不是主要原因。真正的原因是你可以得到更多的问题。

    使用持久性连接的一个问题是它的伸缩性不是很好。对于那些有5000人连接的人,你需要5000个持久的连接。为了摆脱对持久性的要求,你可能有能力为10000个拥有类似数量联系的人提供服务,因为他们能够在不与他们在一起时分享个人联系。

        8
  •  0
  •   James    10 年前