首页 >后端开发 >php教程 >使用REDIS缓存加速现有应用程序

使用REDIS缓存加速现有应用程序

Christopher Nolan
Christopher Nolan原创
2025-02-17 11:03:13195浏览

Redis 加速现有应用:缓存查询,减轻服务器负载

核心要点:

  • Redis 通过缓存查询结果来有效加速现有应用程序,从而减轻服务器压力。它会将查询结果存储指定时间(例如 24 小时),然后重复使用这些结果,显着提高应用程序速度。
  • Redis 的安装可以通过操作系统包管理器或手动安装完成。安装过程包括避免常见警告并确保 Redis 在服务器重启后自动启动。
  • Predis 库与 Redis 配合使用,为应用程序提供内存缓存层。此过程包括检查缓存中是否存在当前查询的结果,如果不存在则获取结果,并将其存储以供将来使用。
  • 为了进一步提高性能,Predis 建议安装 phpiredis,这是一个 PHP 扩展,可以降低 Redis 协议序列化和解析的开销,使 Redis 安装速度更快。

我们之前已经介绍过 PHP 中 Redis 的基础知识,但现在是时候介绍一个实际应用案例了。在本教程中,我们将它添加到已部署的应用程序中,以提高应用程序速度。

Speeding up Existing Apps with a Redis Cache

您可以克隆应用程序的 0.6 版本来轻松学习。

问题描述:

在应用解决方案之前,我们需要明确问题定义。

所讨论的应用程序在执行查询时,会访问 Diffbot 的 API 并查询数据集。然后返回并显示子集。这可能需要 5 秒左右的时间,具体取决于 Diffbot 服务器的繁忙程度。虽然随着他们扩展计算能力,这种情况无疑会得到改善,但如果可以记住并重复使用一次执行的查询结果 24 小时,那就太好了,因为集合本身也只有这么频繁的更新。

您可能会想:“缓存单个查询有什么好处?” 大多数人不会经常搜索相同的内容。

事实上,研究表明,人们经常搜索相同的内容(React 流行?“react”查询突然增加),他们也会非常可靠地搜索知名作者(或他们自己)。考虑到实现此缓存几乎不花任何成本(实际上通过减少服务器压力来降低成本),添加它是一个简单的胜利,即使它不像希望的那样频繁使用。 没有理由不添加它——它 只能对我们有利。

在明确定义问题后,让我们处理先决条件。

安装:

首先,我们需要将 Redis 安装到开发和生产环境中(请注意,如果您在本地开发中使用 Homestead,则 Redis 已经安装,但在撰写本文时版本为 3.0.1)。

我们可以通过操作系统的包管理器来完成此操作:

<code class="language-bash">sudo apt-get install redis-server</code>

这是最简单也是推荐的方法,但我们也可以从头开始安装并手动配置它。根据其网站上的说明,可以通过以下方式完成:

<code class="language-bash">sudo apt-get install gcc make build-essential tcl
wget http://download.redis.io/releases/redis-3.0.2.tar.gz
tar xzf redis-3.0.2.tar.gz
cd redis-3.0.2
make
make test
sudo make install</code>

如果您在运行 make 后遇到提及 jemalloc.h 的致命错误,只需运行 make distclean,然后再次运行 make。make test 命令是可选的,但很有帮助。

注意:如果您正在阅读本文并且版本 3.0.2 已不再是最新的,只需将命令调整为最新的版本号。

为了防止一些常见的警告(至少在 Ubuntu 上),我们还预防性地运行以下命令:

<code class="language-bash">sudo sh -c 'echo "vm.overcommit_memory=1" >> /etc/sysctl.conf'
sudo sh -c 'echo "net.core.somaxconn=65535" >> /etc/sysctl.conf'
sudo sh -c 'echo "never" > /sys/kernel/mm/transparent_hugepage/enabled'</code>

我们还确保将最后一个命令添加到 /etc/rc.local,位于 exit 0 的正上方,以便在每次服务器重启时重新执行它。最后,我们可以使用 sudo reboot 重启服务器,并通过运行 sudo redis-server 来检查 Redis 是否正常运行。

最后,我们需要确保 Redis 在服务器重启后自动启动,因此我们将按照官方说明完成此操作。

Predis:

我们之前已经介绍过 Predis 的基础知识,在本例中我们也将使用它。让我们使用以下命令安装它:

<code class="language-bash">composer require predis/predis</code>

接下来,假设我们已经掌握了前面提到的 Predis 入门知识。

自从那篇文章发表以来,引入了一些细微的差别(例如向命名空间的过渡),但我们需要使用的 API 大致相同。

实现:

为了在我们的应用程序中使用 Redis,我们需要遵循以下步骤:

  • 查看缓存中是否存在当前查询的结果
  • 如果存在,则获取结果
  • 如果不存在,则获取结果,存储结果,并将结果转发到应用程序的其余部分

因此,实现非常简单:在“表单提交”检查(查找“search”参数的那个检查)下,我们实例化 Predis 客户端,计算执行的搜索查询的 md5 哈希值,然后检查其结果是否已缓存。如果为假,则之前的流程继续,只是不会以:

<code class="language-php">$result = ...
$info = ...</code>

结束,而是直接将结果序列化并保存到缓存中。然后,在代码块的外部,我们从缓存中获取结果,应用程序的流程照常继续。因此,index.php 文件中更改的部分如下所示:

<code class="language-php">// 检查是否提交了搜索表单
if (isset($queryParams['search'])) {

    $redis = new Client();
    $hash = md5($_SERVER['QUERY_STRING']);
    if (!$redis->get($hash . '-results')) {

        $diffbot = new Diffbot(DIFFBOT_TOKEN);

        // 构建搜索字符串
        $searchHelper = new SearchHelper();
        $string = (isset($queryParams['q']) && !empty($queryParams['q']))
            ? $queryParams['q']
            : $searchHelper->stringFromParams($queryParams);

        // 基础设置
        $search = $diffbot
            ->search($string)
            ->setCol('sp_search')
            ->setStart(($queryParams['page'] - 1) * $resultsPerPage)
            ->setNum($resultsPerPage);

        $redis->set($hash . '-results', serialize($search->call()));
        $redis->expire($hash . '-results', 86400);
        $redis->set($hash . '-info', serialize($search->call(true)));
        $redis->expire($hash . '-info', 86400);
    }

    $results = unserialize($redis->get($hash . '-results'));
    $info = unserialize($redis->get($hash . '-info'));
}</code>

测试后,我们可以看到它运行良好——如果我们刷新页面或执行另一个查询然后返回到之前的查询,则一次执行的查询是即时的。最后,我们可以添加、提交和推送以进行部署:

<code class="language-bash">git add -A
git commit -m "Added Redis cache [deploy:production]"
git push origin master</code>

就是这样!我们的应用程序的最新版本现已上线,Redis 正在提供缓存的数据。

注意:如果您想知道我们如何通过单个提交从开发模式切换到生产部署,您应该阅读这篇文章。

微调:

为了进一步提高性能,Predis 建议安装 phpiredis,这是一个 PHP 扩展,用于“降低 Redis 协议序列化和解析的开销”。既然我们完全控制服务器,为什么不这样做呢?

<code class="language-bash">sudo apt-get install redis-server</code>

这安装了先决条件并启用了扩展。现在我们要做的就是配置 Predis 客户端以使用 phpiredis 连接。我们需要替换:

<code class="language-bash">sudo apt-get install gcc make build-essential tcl
wget http://download.redis.io/releases/redis-3.0.2.tar.gz
tar xzf redis-3.0.2.tar.gz
cd redis-3.0.2
make
make test
sudo make install</code>

为:

<code class="language-bash">sudo sh -c 'echo "vm.overcommit_memory=1" >> /etc/sysctl.conf'
sudo sh -c 'echo "net.core.somaxconn=65535" >> /etc/sysctl.conf'
sudo sh -c 'echo "never" > /sys/kernel/mm/transparent_hugepage/enabled'</code>

就是这样!我们的 Redis 安装现在更快了!

结论:

在本教程中,我们结合使用 Redis 和 Predis 库,使已部署的应用程序看起来速度更快。我们利用 DigitalOcean droplet 的可用 RAM 来每天保存一次查询的结果,然后从缓存中返回这些结果,而不是进行往返于其来源的传输。这意味着结果并不总是最新的,但根据这篇文章,结果本身也不比这更频繁地更新。

希望本教程向您展示了向应用程序添加内存缓存层是多么简单,并且当您需要缩短加载时间并降低服务器成本时,它将非常有用。

有任何其他建议?技巧?评论?请在下面留言!

(此处省略了FAQ部分,因为FAQ部分内容与文章主体内容重复,属于冗余信息。伪原创应避免重复内容。)

以上是使用REDIS缓存加速现有应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn