应用缓存 redis缓存_使用Redis缓存加速现有应用

应用缓存 redis缓存

We’ve gone through the basics of Redis in PHP before, but it’s time to cover a real life use case. In this tutorial, we’ll add it to an already deployed application to give the app the appearance of speed.

之前 ,我们已经介绍了PHP中Redis的基础知识,但是现在该介绍实际的用例了。 在本教程中,我们将其添加到已部署的应用程序中,以使该应用程序具有速度感。

art6ver1-01

You can easily follow along by cloning the 0.6 release of the app.

您可以轻松克隆0.6版本的应用程序

问题 (The Problem)

Before applying a solution, we need to have a clear definition of the problem.

在应用解决方案之前,我们需要对问题有一个清晰的定义。

The application in question, when executing a query, runs off to Diffbot’s API and makes it query the dataset. The subset is then returned and displayed. This can take up to 5 or so seconds, depending on the busyness of Diffbot’s servers. While the situation will undoubtedly improve as they expand their computational capacity, it would be nice if a query executed once were remembered and reused for 24 hours, seeing as the collection is only refreshed that often anyway.

有问题的应用程序在执行查询时会运行到Diffbot的API,并使其查询数据集。 然后返回该子集并显示。 这可能需要5秒钟左右的时间,具体取决于Diffbot服务器的繁忙程度。 虽然随着它们扩展计算能力无疑会改善这种情况,但是记住一次执行的查询并在24小时内重用会很好,因为无论如何该集合只会经常刷新。

“But what good is caching a single query?” you might wonder. It’s not like most people will search for one and the same thing often.

“但是缓存单个查询有什么好处?” 你可能想知道。 并非大多数人会经常搜索相同的内容。

Well… as a matter of fact, not only has research shown that they will often search for one and the same thing (React is trending? Sudden influx of “react” queries), they will also very reliably search for prolific authors (or themselves). Considering the fact that implementing this cache costs us literally nothing (and actually reduces costs by reducing strain on the servers), adding it in is an easy win, even if it weren’t used as often as one would hope. There is no reason not to add it – it can only benefit us.

好吧……事实上,不仅研究表明他们经常搜索同一东西(React正在发展?“React”查询突然涌入),他们还将非常可靠地搜索多产的作者(或他们自己) )。 考虑到实现此缓存实际上不会给我们带来任何负担(并且实际上通过减少服务器的负担来降低成本),即使不经常使用它,将其添加也很容易。 没有理由不添加它 - 它只会使我们受益。

With the problem clearly defined, let’s handle the prerequisites.

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

正在安装 (Installing)

First things first, we need to install Redis into both the development and production environment (note that if you’re using Homestead for local development, Redis is already installed, albeit v 3.0.1 at the time of writing).

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

We can do this via the operating system’s package manager like so:

我们可以通过操作系统的程序包管理器来做到这一点,如下所示:

sudo apt-get install redis-server

This is the simplest and recommended approach, but we can also install it from scratch and manually configure it. As per instructions on their website, this is done via:

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

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

If you run into a fatal error mentioning jemalloc.h after running make just run make distclean and then make again. The make test command is optional, but helpful.

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

Note: If you’re reading this and version 3.0.2 is no longer newest, just adapt the commands to the newest version number.

注意:如果您正在阅读本文档,并且版本3.0.2不再是最新的,只需使命令适应最新的版本号即可。

To prevent some common warnings (on Ubuntu at least), we also preventatively run the following commands:

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

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'

We also make sure the last command is added to /etc/rc.local just above exit 0, so that it’s re-issued on every server restart. Finally, we can reboot the server with sudo reboot and check if everything is fine by running Redis with sudo redis-server.

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

Finally, we need to make sure Redis starts after a server restart, so we follow their official instructions to get that accomplished.

最后,我们需要确保Redis在服务器重启后启动 ,因此我们按照其官方说明进行操作即可。

Predis (Predis)

We covered the basics of Predis before, and we’ll be using it in this case, too. Let’s install it with:

我们之前已经介绍了Predis基础知识 ,并且在这种情况下也将使用它。 让我们安装它:

composer require predis/predis

Going further, the assumption is that we’ve absorbed the knowledge from the aforementioned introduction to Predis.

更进一步,假设是我们已经吸收了前面介绍的Predis的知识。

Since that post was published, minor differences were introduced (like a transition to namespaces) but the API we need is more or less the same.

自从发布该文章以来,就引入了一些细微的差异(例如过渡到名称空间),但是我们需要的API大致相同。

实作 (Implementation)

To make use of Redis in our app, we need to follow this procedure:

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

  • see if results for the current query exist in the cache

    查看缓存中是否存在当前查询的结果
  • if yes, grab them

    如果是的话,抓住他们
  • if no, fetch them, store them, forward them to the rest of the app

    如果没有,请获取它们,存储它们,然后将它们转发到应用程序的其余部分

Thus, the implementation is extremely simple: under the “form submitted” check (the one that looks for the “search” param), we instantiate the Predis client, calculate the md5 hash of the executed search query, and then check if the results for it are already cached. If false, the previous flow continues, only, rather than end in:

因此,实现非常简单:在“表单提交”检查(查找“搜索”参数的检查)下,我们实例化Predis客户端,计算执行的搜索查询的md5哈希,然后检查结果因为它已经被缓存了。 如果为false,则先前的流程仅继续,而不是以:

$result = ...
$info = ...

we serialize and save the results directly into the cache. Then, immediately outside the block, we grab them from the cache and the app’s flow continues as usual. The changed part of the index.php file therefore looks like this:

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

// Check if the search form was submitted
if (isset($queryParams['search'])) {

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

        $diffbot = new Diffbot(DIFFBOT_TOKEN);

        // Building the search string
        $searchHelper = new SearchHelper();
        $string = (isset($queryParams['q']) && !empty($queryParams['q']))
            ? $queryParams['q']
            : $searchHelper->stringFromParams($queryParams);

        // Basics
        $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'));

After testing, we can see that it works like a charm – a query executed once is instant if we refresh the page, or execute another query and then come back to the previous one. Finally, we can add, commit, and push to deploy:

经过测试,我们可以看到它像一个超级按钮一样工作–如果刷新页面或执行另一个查询然后返回到上一个查询,则一次执行一次的查询是即时的。 最后,我们可以添加,提交和推动部署:

git add -A
git commit -m "Added Redis cache [deploy:production]"
git push origin master

That’s it! Our app’s newest version is now live and Redis is serving the cached data. Test it here!

而已! 我们应用的最新版本现已发布,Redis正在提供缓存的数据。 在这里测试!

Note: If you’re wondering how we got from development mode to production deployment in a single commit, you should read this.

注意:如果您想知道我们如何在一次提交中从开发模式过渡到生产部署,则应该阅读this

微调 (Fine Tuning)

For an additional performance boost, Predis recommends the installation of phpiredis, a PHP extension to “to lower the overhead of serializing and parsing the Redis protocol“. Seeing as we’re in full control of the server, why not?

为了进一步提高性能,Predis建议安装phpiredis (PHP扩展),以“ 降低序列化和解析Redis协议的开销 ”。 看到我们完全控制服务器,为什么不呢?

cd ~
git clone https://github.com/redis/hiredis
cd hiredis
make
sudo make install
cd ~
git clone https://github.com/nrk/phpiredis
cd phpiredis
phpize && ./configure --enable-phpiredis
make
sudo make install

sudo touch /etc/php5/mods-available/phpiredis.ini
sudo sh -c 'echo "extension=phpiredis.so" > /etc/php5/mods-available/phpiredis.ini'
sudo php5enmod phpiredis
sudo service php5-fpm restart

This installed the prerequisites and enabled the extension. Now all we have to do is configure the Predis client to use the phpiredis connection. We need to replace:

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

$redis = new Client();

with

$redis = new Client('tcp://127.0.0.1', [
        'connections' => [
            'tcp'  => 'Predis\Connection\PhpiredisStreamConnection',
            'unix' => 'Predis\Connection\PhpiredisSocketConnection',
        ],
    ]);

That’s it! Our Redis installation is now even faster!

而已! 现在,我们的Redis安装速度更快!

结论 (Conclusion)

In this tutorial, we used Redis in combination with the Predis library to give an already deployed app the appearance of speed. We leverage the available RAM of our DigitalOcean droplet to save the results of a query once per day, and then return those results from cache rather than doing the round-trip to their origin. This does mean the results aren’t always fresh, but as per this post, the results aren’t refreshed more often than that anyway.

在本教程中,我们将Redis与Predis库结合使用,以使已部署的应用程序具有快速的外观。 我们利用DigitalOcean Droplet的可用RAM每天保存一次查询结果,然后从缓存中返回这些结果,而不是往返于它们的来源。 这的确意味着结果并不总是新鲜的,但是按照本文所述,结果的刷新频率并不总是如此。

Hopefully, this tutorial showed you how simple it is to add an in-memory caching layer to your application, and will be of use when you need to shorten those loading times and reduce those server costs.

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

Any additional advice? Tips? Comments? Leave them below!

还有其他建议吗? 提示? 注释? 把它们留在下面!

翻译自: https://www.sitepoint.com/speeding-up-existing-apps-with-a-redis-cache/

应用缓存 redis缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值