实现模型级缓存 [英] Implementing Model-level caching

查看:170
本文介绍了实现模型级缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在关于MVC的相关问题中发表了一些意见缓存和一些关于实际实现的问题。如何实现一个透明地工作的模型级缓存,而开发人员不需要手动缓存,但仍然保持高效?

I was posting some comments in a related question about MVC caching and some questions about actual implementation came up. How does one implement a Model-level cache that works transparently without the developer needing to manually cache, yet still remains efficient?


我的缓存
的责任牢牢地在
模型内。它不是控制器的
或视图的业务模型是
获取数据。他们关心的是
,当请求数据时,数据是
提供的 - 这是MVC
范例应该如何工作。

I would keep my caching responsibilities firmly within the model. It is none of the controller's or view's business where the model is getting data. All they care about is that when data is requested, data is provided - this is how the MVC paradigm is supposed to work.

(资料来源:发布者Jarrod

我怀疑的原因是因为缓存通常不会做,除非有真正的需要,不应该做例如搜索结果。所以不知何故,模型本身必须知道是否发出给它的SELECT语句值得被缓存。模型不是必须是天文聪明的,和/或存储统计的最常被查询的长期时间,以准确做出决定?

The reason I am skeptical is because caching should usually not be done unless there is a real need, and shouldn't be done for things like search results. So somehow the Model itself has to know whether or not the SELECT statement being issued to it is worthy of being cached. Wouldn't the Model have to be astronomically smart, and/or store statistics of what is being most often queried over a long period of time in order to accurately make a decision? And wouldn't the overhead of all this make the caching useless anyway?

如何从另一个查询中唯一标识一个查询(或者更准确地说,从另一个查询中获得一个结果集)结果集)?

How would you uniquely identify a query from another query (or more accurately, a result set from another result set)? What about if you're using prepared statements, with only the parameters changing according to user input?

另一张海报说:


我建议使用
的md5哈希,你的查询结合一个序列化的
版本的输入参数。

I would suggest using the md5 hash of your query combined with a serialized version of your input arguments.

碰撞的微小机会值得担心吗?

Is the minuscule chance of collision worth worrying about?

概念上,缓存在模型中似乎是一个好主意但是它似乎在实用性和缓存的性质,开发人员应该有直接控制它和显式代码它到控制器逻辑。

Conceptually, caching in the Model seems like a good idea to me, but it seems in practicality and due to the nature of caching the developer should have direct control over it and explicity code it into the controller logic.

更新Bounty

我确实使用了一个非常轻量级的ORM,有点类似于ActiveRecord,问题的连接和子查询没有 n ^ 2 问题。我自己构建它,所以它是灵活的,在关系或列名称方面没有限制,我只是想了解如何实现缓存机制。

I am indeed using an extremely lightweight ORM somewhat similar to ActiveRecord but is capable of doing complex joins and subqueries without the n^2 problem. I built it myself, so it is flexible and isn't restrictive in terms of relations or column names, and I just want to understand how I should implement the caching mechanism.

根据有帮助的人的建议,我会将查询的哈希(可能是md5)连同其参数列表一起使用,并将其用作该特定数据存储的键。我应该在需要它的Model类中单独实现缓存,还是应该是ORM层的一部分?

Following the advice of the helpful people, I would take a hash (probably md5) of the query concatenated with a list of its parameters, and use this as the key for that particular data store. Should I implement the caching individually in the Model classes that require it, or should it be part of the ORM layer?

如何知道何时应该失效?我必须手动解析参数UPDATE / DELETE / INSERT查询和子查找哪些记录被修改?或者更糟糕的是,每当修改数据以跟踪哪些内容已更改,以及哪些内容应该失效时,请执行其他查询?

How do I know when it should be invalidated? Would I have to parse the UPDATE/DELETE/INSERT queries and sub in parameters manually to find out which records are being modified? Or worse, do additional queries whenever data is modified to keep track of which things have changed and what should be invalidated?

我将奖励给可以给我清晰的概念解释(无论这是否真的有必要/有效地透明地完成),如果是这样,有一些模型缓存的实现细节。我使用PHP和MySQL,如果这有助于缩小你的焦点。

I will award the bounty to whoever can give me a clear conceptual explanation (whether or not this is really necessary/efficient to be done transparently), and if so, has some implementation details for the Model caching. I am using PHP and MySQL if that helps to narrow your focus.

推荐答案

微不足道的ORM。有很多原因,这是一个坏东西。请尝试将该模型作为一个Web服务来考虑。

Your post only makes any sense if the model is a trivial ORM. And there are lots of reasons why that's a bad thing. Try thinking about the model as if it were a web service.

缓存模型的责任。


如何从另一个查询(或更准确地说,另一个结果集的结果集)中唯一标识查询?如果你使用准备语句,只有根据用户输入更改参数?

How would you uniquely identify a query from another query (or more accurately, a result set from another result set)? What about if you're using prepared statements, with only the parameters changing according to user input?

但是模型的输入唯一定义其输出。

But the inputs to the model uniquely define its output.

如果您使用相同的模型检索购物篮的内容,并在您的产品目录中进行搜索,那么您的代码。

If you're using the same model to retrieve the contents of a shopping basket and to run a search on your product catalog then there's something wrong with your code.

即使在购物篮的情况下,在缓存具有小于处理交易的时间的数据的数据可能是有价值的,内容,在目录搜索的情况下,缓存几个小时的匹配产品的列表可能对销售没有可测量的影响,但是在减少数据库负载方面折衷。

Even in the case of the shopping basket, there may be merit in caching data with a TTL of less than the time taken to process a transaction which would change its contents, in the case of the catalog search, caching the list of matching products for a few hours will probably have no measurable impact on sales, but trade-off well in reducing database load.

事实上,你正在使用一个平凡的ORM开箱即用,并不排除你将它包装在自己的代码中。

The fact that you are using a trivial ORM out of the box does not exclude you from wrapping it in your own code.


Wouldn't the Model have to be astronomically smart, and/or store statistics

不是。您决定是否要缓存,如果您无法确保缓存一致,请根据请求类型强制实施TTL。

No. You make the determination on whether to cache, and if you can't ensure that the cache is consistent then enforce a TTL based on the type of request.

作为一般经验法则,您应该能够根据之前的SELECT查询来预测适当的TTL,并且这需要在设计时实现 - 但显然结果应该基于查询绑定。

As a general rule of thumb, you should be able to predict appropriate TTLs based on the SELECT query before binding any variables and this needs to be implemented at design time - but obviously the results should be indexed based on the query after binding.


我应该在需要它的Model类中单独实现缓存还是应该是ORM层的一部分? p>

Should I implement the caching individually in the Model classes that require it, or should it be part of the ORM layer?

优先我将实现这个模型类的装饰器 - 这样你可以轻松地将它移植到实现工厂的模型,而不是琐碎的ORM。

For preference I would implement this as a decorator on the model class - that way you can easily port it to models which implement a factory rather than trivial ORM.

C。

这篇关于实现模型级缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆