PHP APC 缓存还是不缓存?
我真的没有任何缓存经验,所以这似乎是一个愚蠢的问题,但是你如何知道何时缓存数据?我什至找不到一个谈论这一问题的网站,但这可能只是我的搜索技巧,或者可能有太多变量需要考虑?
我很可能会使用 APC。有谁有任何示例说明缓存所需的最少数据量是多少?例如,假设您有一个包含 100 个项目的数组,并且对其使用 foreach 循环并执行一些简单的数组操作,是否应该缓存结果?如果有 1000 个项目、10000 个项目等怎么样?
您应该缓存数据库查询的结果吗?您应该缓存什么样的查询?我假设一个简单的选择,也许还有几个到 mysql 数据库的连接语句不需要缓存,或者是吗?假设mysql查询缓存开启,是不是就意味着不需要在应用层进行缓存,还是应该做呢?
如果实例化一个对象,是否应该缓存它?如何判断是否应该缓存?因此,关于缓存内容的一般指南会很好,示例也会非常有帮助,谢谢。
I don't really have any experience with caching at all, so this may seem like a stupid question, but how do you know when to cache your data? I wasn't even able to find one site that talked about this, but it may just be my searching skills or maybe too many variables to consider?
I will most likely be using APC. Does anyone have any examples of what would be the least amount of data you would need in order to cache it? For example, let's say you have an array with 100 items and you use a foreach loop on it and perform some simple array manipulation, should you cache the result? How about if it had a 1000 items, 10000 items, etc.?
Should you be caching the results of your database query? What kind of queries should you be caching? I assume a simple select and maybe a couple joins statement to a mysql db doesn't need caching, or does it? Assuming the mysql query cache is turned on, does that mean you don't need to cache in the application layer, or should you still do it?
If you instantiate an object, should you cache it? How to determine whether it should be cached or not? So a general guide on what to cache would be nice, examples would also be really helpful, thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您查看从 APC/memcache/WinCache/redis/etc 中的数据库读取的缓存数据时,您应该意识到,当数据库更新时,它不会被更新,除非您显式地编写代码来保留数据库并缓存同步。因此,当数据库中的数据不经常更改,但也需要更复杂和/或昂贵的查询来从数据库检索该数据时,缓存是最有效的(否则,当您需要它)...如此昂贵的连接查询在运行时返回相同的数据记录是主要候选者。
并且始终测试从数据库读取查询是否比从缓存读取查询更快。正确的数据库索引可以极大地缩短数据库访问时间,特别是当大多数数据库也维护自己的内部缓存时,因此不要使用 APC 或等效项来缓存数据,除非数据库开销证明它是合理的。
您还需要了解缓存中的空间使用情况。大多数缓存都是固定大小的,您不想过度填充它们......所以不要使用它们来存储大量数据。使用 APC 提供的 apc.php 脚本来监视缓存使用情况(但要确保访问您网站的任何人和每个人都不能公开访问该脚本......安全性差)。
当在缓存中保存对象时,该对象在存储时将被序列化(),而在检索时将被反序列化(),因此存在开销。具有资源属性的对象将失去该资源;所以不要存储您的数据库访问对象。
明智的做法是仅使用缓存来存储许多/所有用户访问的信息,而不是特定于用户的数据。对于用户会话信息,请坚持使用普通的 PHP 会话。
When you're looking at caching data that has been read from the database in APC/memcache/WinCache/redis/etc, you should be aware that it will not be updated when the database is updated unless you explicitly code to keep the database and cache in synch. Therefore, caching is most effective when the data from the database doesn't change often, but also requires a more complex and/or expensive query to retrieve that data from the database (otherwise, you may as well read it from the database when you need it)... so expensive join queries that return the same data records whenever they're run are prime candidates.
And always test to see if queries are faster read from the database than from cache. Correct database indexing can vastly improve database access times, especially as most databases maintain their own internal cache as well, so don't use APC or equivalent to cache data unless the database overheads justify it.
You also need to be aware of space usage in the cache. Most caches are a fixed size and you don't want to overfill them... so don't use them to store large volumes of data. Use the apc.php script available with APC to monitor cache usage (though make sure that it's not publicly accessible to anybody and everybody that accesses your site.... bad security).
When holding objects in cache, the object will be serialized() when it's stored, and unserialized() when it's retrieved, so there is an overhead. Objects with resource attributes will lose that resource; so don't store your database access objects.
It's sensible only to use cache to store information that is accessed by many/all users, rather than user-specific data. For user session information, stick with normal PHP sessions.
简单的答案是,当速度变慢时,您可以缓存数据。显然,对于任何中型到大型应用程序,您需要做更多的规划,而不仅仅是观望方法。但对于绝大多数网站来说,要问自己的问题是“您对加载时间感到满意吗”。当然,如果您像我一样对加载时间很着迷,那么无论如何您都会想要尝试使其更快。
接下来,您必须确定导致速度缓慢的具体原因。您假设您的应用程序代码是源代码,但是否存在其他外部因素(例如页面文件大小较大、请求过多、没有 gzip 等)值得检查。使用类似 http://tools.pingdom.com/ 或像 yslow 这样的扩展作为开始。 (快速提示确保 keepalive 和 gzip 正常工作)。
假设问题是应用程序代码的执行持续时间,您将需要使用 xdebug (http://www.xdebug.org/) 等工具来分析代码,并使用 kcachegrind 或 wincachegrind 查看输出。这会让您知道代码的哪些部分需要很长时间才能运行。从那里您将决定缓存什么以及如何缓存它(或改进代码逻辑)。
问题所在以及相关的解决方案有很多可能性,因此不值得我猜测。因此,一旦确定问题,您可能想要发布与解决该特定问题相关的新问题。我想说的是,如果使用不当,mysql查询缓存可能会适得其反。另外,我通常会避免使用 APC 用户缓存,而倾向于使用 memcached。
The simple answer is that you cache data when things get slow. Obviously for any medium to large sized application, you need to do much more planning than just a wait and see approach. But for the vast majority of websites out there, the question to ask yourself is "Are you happy with the load time". Of course if you are obsessive about load time, like myself, you are going to want to try to make it even faster regardless.
Next, you have to identify what specifically is the cause of the slowness. You assumed that your application code was the source but its worth examining if there are other external factors such as large page file size, excessive requests, no gzip, etc. Use a site like http://tools.pingdom.com/ or an extension like yslow as a start for that. (quick tip make sure keepalives and gzip are working).
Assuming the problem is the duration of execution of your application code, you are going to want to profile your code with something like xdebug (http://www.xdebug.org/) and view the output with kcachegrind or wincachegrind. That will let you know what parts of your code are taking long to run. From there you will make decisions on what to cache and how to cache it (or make improvements in the logic of your code).
There are so many possibilities for what the problem could be and the associated solutions, that it is not worth me guessing. So, once you identify the problem you may want to post a new question related to solving that specific problem. I will say that if not used properly, the mysql query cache can be counter productive. Also, I generally avoid the APC user cache in favor of memcached.