APC缓存一致性问题
我已经将对象缓存内置到了 ORM 层中。基本上,SQL 查询的哈希值用作键,值包含数据库结果集中的对象集合。然而,如果结果集中的对象之一被更新,则这会产生问题,缓存的结果集不包含更新的对象。不存在写入一致性。我将如何实现写一致性?
谢谢
更新:目前我有一个 ObjectWatcher 类来处理缓存的对象及其键。对象使用可检索的键进行缓存,因此对于 Person 类来说,它是 Person.101。 SQL 查询经过哈希处理,键映射到一个 Dependency 对象,该对象内有一个依赖对象列表。因此,SELECT * FROM person
可能会从 APC 返回一个 Dependency 对象,该对象映射到 Person.101 和 Person.102,结果集合是从此 Dependency 对象构建的。这对于更新单个对象来说效果很好。因此,如果我更新 Person.101 并将新更新的对象放入 APC 中并覆盖旧的对象,则当运行较旧的查询时,更新的对象将放入该结果集中,这可能是不正确的。我需要一种方法,不仅可以清除内存中的对象,还可以清除所有保存对更新对象的引用的依赖项对象。在APC中,有没有办法搜索包含的键或包含或过滤键和值的值?
I have built into our ORM layer object caching. Basically a hash of the SQL query is used as the key and the value contains the collection of objects from the DB resultset. However this creates a problem if one of the objects in the resultset is updated the cached resultset does not include the updated object. There is no write consistency. How would I implement write consistency?
Thanks
UPDATE: Currently I have an ObjectWatcher class that handles what objects are cached and their keys. Objects are cached with retrievable keys so for Person class it's Person.101 for example. The SQL query is hashed and the key maps to a Dependency object which within it has a list of the dependent objects. So SELECT * FROM person
might return a Dependency object from APC which maps to Person.101 and Person.102 the resulting collection is built from this Dependency object. This works fine for the update of a single object. So If I update Person.101 and put the newly update object into APC overwriting the stale one, when a older query is run that updated object will get put into that result set, which could be incorrect. I need a way to clean not only the object from memory but all the Dependency object which hold a reference to the updated object. In APC is there a way to search for keys containing or values containing or filter keys and values?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此问题与APC无关。
您需要管理数据如何存储在 APC(或任何其他存储)中。如果您想在 APC 中更新键的值,当对象将被更改时 - 这是可能的,只有当对象知道键(查询的哈希值)并且该对象应该能够从另一个对象收集所有数据时,通过以下方式获取那个查询。这一切听起来都是荒谬的想法。
任何模型都应该按照单一职责原则进行设计,因此如果您想缓存整个对象(这也不是一个好主意),请为每个对象创建唯一的键。
此外,对象不应该关心它们将如何存储(缓存)以及在哪里。因此,您还需要一个对象来管理对象缓存。
我建议不要缓存整个对象,而只缓存数据库中的记录值,这需要很多时间才能从数据库中获取它们。
但是如果你仍然想使用 SQL 查询的哈希值作为键,那么你可以使用 tags 并写入 "这些标签中对象的名称”。
例如,如果结果集中有对象“Person”、“Employer”和“Customer”,则键将具有标签“person”、“employer”和“customer”。并且,当对象 Customer 发生更改时,您可以从缓存中删除所有标有“customer”标签的键。
但是,无论如何,这不是 Customer 对象的责任,所有这些事情都应该由另一个对象管理。
问题已被编辑,所以我也会编辑我的答案:)
标签不是 APC 的一部分,而是包装器的一部分。标签是非常有用的东西,对于您的情况来说非常方便。
可以是这个引用。您不需要按标签搜索键,您只需删除与该标签关联的所有键(以保持数据真实),并且此包装器具有现有的方法来执行此操作。
在示例中:
让我们查询
SELECT * FROM people WHERE email <> ''
- 此查询的缓存结果将由标签“person”标记。因此,当我们更新任何 Person 对象时,我们将删除所有标有“person”标签的键,因此我们的查询结果
SELECT * FROM Persons WHERE email <> ''
将被删除,并且在下一个请求中我们的脚本将生成新的(实际)值。This question is not related to APC.
You need to manage, how data will be stored in APC (or any other storage). If you want to update value of key in APC, when object will be changed - it can be possible, only when Object will know the key (hash of query) and this object should be able to collect all data from another objects, fetched by that query. All it sounds like absurd idea.
Any model should be designed with Single Responsibility principle, so if you want to cache whole objects (it's not very good idea too), then create unique keys for each object.
Also, objects shouldn't care about how they will be stored (cached), and where. So you need one more object, which will manage objects caching.
And I recommend to cache not whole objects, but only values of records in DB, which are takes to many time to fetch them from DB.
But if you still want to use hash of SQL query as a key, then you can use tags and write "names" of objects in these tags.
For example, if in result-set you have objects Person, Employer and Customer, then key will have tags "person", "employer" and "customer". And, when object Customer will be changed, you can delete from cache all keys, which marked with tag "customer".
But, anyway, it's not a responsibility of Customer object, all this things should be managed by another object.
Question was edited, so I'll edit my answer too :)
Tags is not the part of APC, is the part of wrapper. Tags is very useful thing and very handy for your case.
Tags can be this reference. You don't need to search keys by tag, you need just to remove all keys associated with that tag (to keep data actual), and this wrapper has existing method to do it.
In examples:
Let we have query
SELECT * FROM persons WHERE email <> ''
- cached result of this query will be marked by the tag "person".So, when we will update any Person object, we will remove all keys, which are marked with tag "person", so our result for query
SELECT * FROM persons WHERE email <> ''
will be removed, and in next request our script will generate new (actual) value.