用于高频写入的高速缓存/队列

时间:2015-06-17 13:32:26

标签: php sql caching memcached gearman

假设一个(PHP)Web应用程序每分钟有X00,000个请求,并且SQL数据库的条目数大致相同。

每个请求将触发一些(< 5)db读取和一个db写入(主要是更新)。我主要担心写入引起的性能问题,并寻找解决方案来增加每分钟可能的请求。

您会建议哪些解决方案,您将如何实施,以及为什么?

我想到的事情包括要写入的缓存,每隔一些时间间隔与db同步,或者像Gearman这样的队列,或者只是SQL的插入延迟。

但是,由于预期相同的负载是恒定的,因此当服务器负载恒定在> 90%时,插入延迟可能没有多大帮助,所以我正在寻找与单次写入相比显着降低服务器负载的方法。

由于

1 个答案:

答案 0 :(得分:1)

如果您正在更新表,您也在阅读,那么是的,这些更新将减慢读取速度,因为它们将使MySQL查询缓存和可能的表锁定无效。一个常见示例是产品详细信息表,您将更新访问次数。

简单方法不是更新主表,而是使用单独的表来更改值(例如product_views)并更改查询以使用JOIN来获取值。使用这种方法,您的主(和大)表将主要是静态的,不受查询 - 缓存失效和锁定的影响。

更高级的方法是不使用UPDATE,而是使用INSERT。不是在每个页面视图上更新一行,而是将新值插入临时表(例如product_views_temp) - 因此每个视图将为1行。然后安排一个cron作业,例如每5分钟进行一次查询,如SELECT COUNT(*) FROM product_views_temp GROUP BY prod_id,并根据数字更新主表(应该可以在1个查询中)。主要的好处是这些INSERT更快,如果您出于任何原因需要,您可以在主表中获得计数。没有什么缺点,在访问者看到更新的计数之前会有一点延迟。

编辑:如果您能够承受丢失5分钟的计数数据,您可以通过使用MySQL MEMORY storage engine创建临时表来使其超速。它们对INSERT来说非常快(但对于UPDATE来说可能会慢一些)。当服务器崩溃/关闭时,表本身仍然存在,但其内容丢失。

您还可以将MEMORY引擎用于会话数据(如果用户需要在意外的服务器崩溃后再次登录,这并不重要,因为它不会经常发生)。