使用Redis缓存SQL结果

时间:2015-07-20 22:07:21

标签: mysql database caching redis

我有一个基于SQL的应用程序,我喜欢使用Redis缓存结果。您可以将应用程序视为具有多个SQL表的通讯簿。该应用程序执行以下任务:

40%的时间:

  • 创建新记录/更新现有记录
  • 批量更新多条记录
  • 查看现有记录

60%的时间:

  • 根据用户的标准搜索记录

这是我目前的做法:

  • 系统在创建或更新记录时缓存记录。
  • 当用户执行搜索时,系统将缓存查询结果。

最重要的是,我有一个Redis查找表(Redis Set),它存储MySQL记录ID和Redis缓存键。这样我就可以删除Redis缓存,如果MySQL记录已被更改(例如,批量更新)。

如果在系统缓存搜索结果后创建新记录怎么办?如果新记录与搜索条件匹配,系统将始终返回旧缓存(不包括新记录),直到删除缓存(在缓存中的现有记录更新之前不会发生)。 / p>

搜索由用户驱动,搜索条件的组合是无数的。在创建新记录时,无法评估应删除哪个缓存。

到目前为止,唯一的解决方案是在创建记录时删除MySQL表的所有缓存。然而,这不是一个好的选择,因为每天都会创建大量记录。

在这种情况下,在MySQL之上实现Redis的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

这对于PHP和MySQL来说是一个令人惊讶的事情(我不确定其他语言) - 将内容缓存到memcached或Redis实际上更快。快多了。基本上,如果你只是构建你的应用程序并查询MySQL - 你可以从中获得更多。

现在为"为什么"一部分。

InnoDB,默认引擎,是一个极好的引擎。具体来说,它的内存管理(分配和不分配)优于任何内存存储解决方案。这是一个事实,你可以查一下或接受我的话 - 它至少会表现得和Redis一样好。

现在你的应用程序会发生什么 - 你查询MySQL并将结果缓存到redis中。但是,MySQL也足够智能以保持缓存结果。您刚才所做的是创建连接到Redis所需的附加文件描述符。您还使用了一些存储(RAM)来缓存MySQL已经缓存的结果。

这是另一个有趣的部分 - 提供PHP脚本的首选方法是使用php-fpm - 它比任何mod_*废话要快得多。在核心方面,php-fpm是一个产生子进程的监督进程。在脚本提供后,它们不会关闭,这意味着它们会缓存与MySQL的连接 - 连接一次,多次使用。基本上,如果您使用php-fpm提供脚本,他们将重用已建立的与MySQL的连接,这意味着您不会为每个请求打开和关闭连接 - 这非常有利于资源,它可以让您拥有闪电快速连接到MySQL。 MySQL,具有内存效率并具有缓存结果比Redis快得多。

现在所有这些对您来说意味着什么 - 通过正确的设置,您可以使用简单,简单,不涉及Redis的小代码,并消除缓存失效时可能遇到的所有问题什么不是,你不会浪费你的记忆两次包含相同的数据。

您需要的成分:

  • php-fpm
  • 基于
  • MySQLInnoDB的表格,最重要的是 - 足够的内存和调整innodb_buffer_pool_size变量。那个控制InnoDB允许为其目的分配多少RAM - 越大越好。

你从游戏中删除了Redis,你保持代码简单易维护,你没有复制数据,你没有在游戏中引入额外的系统,你让软件得到了解决方案意在照顾数据做它的工作。即使您从头开始编译所有软件,也可以通过相当便宜的折衷来获得最大的实用性 - 它不会花费超过一个小时的时间来启动并运行。

或者,您可以忽略我写的内容并使用Redis寻找解决方案。

答案 1 :(得分:0)

我们遇到了同样的问题,我们选择了您正在考虑的相同事情:删除受该表影响的所有查询缓存。它不像你说的那样理想,但幸运的是我们的写作"是不是高达40%,所以到目前为止还不错。 这是基于查询的缓存的本质。作为替代方案,您可以添加基于实体的缓存。不是仅缓存搜索结果,而是缓存整个表并在内存中进行搜索。我们使用C#LINQ,所以我们可以在内存中进行相当常见的查询,但如果搜索太复杂,那么你就不走运了。