【问题标题】:MongoDB as MySQL cacheMongoDB 作为 MySQL 缓存
【发布时间】:2012-12-23 05:25:56
【问题描述】:

我刚刚有了这个想法,并认为这是解决这个问题的好方法,但我问这种方法是否有一些缺点。我有一个经常查询数据库的网页,每个页面加载多达 3-5 个查询。每个查询都进行十几个(字面意思)连接,然后每个查询结果都用于另一个查询以构造 PHP 对象。不用说,即使在云上加载时间也很荒谬,但它现在就是这样工作的。

我考虑将已经构建的对象存储为 JSON 或 MongoDB - BSON 格式。使用MongoDB作为这种类型的缓存引擎会是一个很好的解决方案吗?这是我认为它将如何工作的示例:

  1. 当用户打开页面时,如果 Mongo 中没有具有正确 ID 的数据,则会触发对 MySQL 的查询,每个返回的数据都被转换为正确构造的对象。该对象被发送到视图并转换为 JSON 并保存在 Mongo 中。
  2. 如果Mongo中有对应ID的数据,正在发送到PHP进行转换。
  3. 当 MySQL 中的某些数据发生更改(管理员编辑/删除内容)时,会触发删除函数,该函数也会删除 MongoDB 中已编辑/删除的对象。

使用 MongoDB 是不是一个好方法?这种方法的缺点是什么?使用 Redis 完成这项任务会更好吗?我还需要 NoSQL 用于项目的其他元素,这就是为什么我正在考虑使用这两个元素之一而不是 memcache。

MongoDB as a cache for frequent joins and queries from MySQL 有一些信息,但完全不相关。

【问题讨论】:

  • 您是否考虑过优化您的 mysql 数据库架构,以便不再需要数十个连接来构建页面?使用您拥有的技术并在 mysql 中构建缓存有什么问题?添加的技术越多,故障点就越多,维护应用程序所需的专业知识就越多。
  • @Philipp 是的,你说得对,使用的技术越多,管理层就越难,但这不是一个简单的数据库前端项目,它是几年前制作的需要优化的系统它的网页端。架构被尽可能地去规范化,以减少连接的存在,但这太复杂了

标签: php mysql mongodb caching redis


【解决方案1】:

我认为您最好使用 memcached 或 Redis 来缓存查询结果。 MongoDB 与其说是缓存,不如说是一个完整的数据库。虽然 memcached 和 Redis 都针对缓存进行了优化。

但是,您可以将缓存实现为两级缓存。例如,Memcached 不保证数据将保留在缓存中。 (它可能会在存储已满时使数据过期)。这使得实现标签系统变得困难(例如,您为 MySQL 表添加标签,然后您可以触发与该表关联的所有查询结果的过期)。一个常见的解决方案是使用 memcached 进行缓存,使用第二个更慢但更可靠的缓存,虽然它应该比 MySQL 更快。 MongoDB 可能是一个很好的候选者(只要您可以保持对 MongoDB 的查询简单)。

【讨论】:

  • 是的,我完全忘了提,预计数据库中会有 50-100k 个对象,每个对象大约 5-100kB。因此,不能只使用 RAM 作为缓存,因为它的容量很小。
  • 那我肯定觉得用两级缓存就好了。一些实现提供了使用优先级缓存对象的可能性。这尤其适用于存储已满时的过期,以及哪些对象存储在较快的缓存中,哪些对象存储在较慢的缓存中。
  • 明白,很高兴您提出了两级缓存,它可能会解决我遇到的所有问题。用作较慢缓存的系统怎么样? MongoDB 还是 Redis?正如我所看到的,由于它的灵活性,它一直是 Mongo。
  • Afaik,您可以同时使用两者(尽管我不是 Redis 专家)。我认为 Redis 会更快,所以在这种情况下,我会使用 Redis。
  • Redis 在内存中保留所有内容的副本。我会添加主缓存层并再次测量性能。您可能会发现二级缓存是不必要的。
【解决方案2】:

你可以使用 Memcached 或 Redis 来缓存对象。 Mongodb 也可以用作缓存。我使用 mongodb 来缓存聚合结果,因为它具有广泛的查询优势以及与 Memcached 不同的优势。

例如,在一个标记应用程序中,如果我必须显示与每个标记对应的页数,它会扫描整个表以查找 group by 查询。所以我有一个cronjob,它通过查询计算该组并将聚合结果缓存在 Mongo 中。这对我在生产中非常有效。您也可以对无数其他复杂的计算执行此操作。

mongodb capped collectionsTTL collections 也非常适合缓存。

【讨论】:

  • 请解释为什么你会使用 cronjob 而不是在上次更新后的特定时间后简单地运行更新?在只有部分数据被查询而另一部分空闲的情况下,它会更轻。例如,对于网上商店,我不需要像在情人节之前缓存香水和其他类似的东西一样多地缓存 PC 产品。
  • 是的,如果您不需要 cronjobs,请避免使用它们。它们很昂贵。我只是举了一个例子,我在生产中使用的方式。甚至 stackexchange 也有用于聚合和用户排名的 cronjobs ;)
  • 是的,对于页面的某些部分,它们是可行的方法,例如首页元素。
  • 对于记录到期,在 mongo 中你有 TTL 索引。查看答案中的链接:)
  • 是的,我也考虑过使用它们,谢谢你的链接!
猜你喜欢
  • 2014-08-16
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
  • 2014-07-16
  • 2013-04-22
  • 1970-01-01
相关资源
最近更新 更多