博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用Redis cache优化app查询速度实践
阅读量:5880 次
发布时间:2019-06-19

本文共 4201 字,大约阅读时间需要 14 分钟。

注意:本篇文章译自,如需要转载请注明出处。

发现问题

在应用解决方法之前,我们需要对我们面对的问题有一个清晰的认识。

App所遇到的问题是,当执行一个查询时,它会跑到 然后查询数据集。子集被返回并展示出来。根据Diffbot服务器的繁忙程度,可能需要花5秒左右的时间去完成这一过程。如果扩展计算机的能力这种情形无疑会改进,如果一个查询执行一次就被记住并且重复使用24小时,通常可以把这个过程看成刷新这个集合,并且这个方式会非常的高效。

你可能会怀疑“缓存一个查询有什么好处呢?”大多数人应该都不会只查询一个东西或者同样的事物。

呃...事实上,不仅调查表明人们经常查询一个事情或相同的事,他们通常也会去搜索多产作家(或自己)。考虑到事实上应用这一缓存方式并没有增加纸面上的成本(其实是通过减少服务器压力而减少成本),把这个加进来是一个容易的盈利点,即使它使用频率并没有我们希望那样高。但我们也没有任何理由不使用它----因为它可以给我们带来利益。

既然问题已经界定清楚,让我们先处理先决条件。

配置环境

首先,我们需要在开发和生产环境下安装Redis(需要注意的是,如果你把Homestead用于本地开发,Redis就已经安装好了,目前使用的是v3.0.1版本)

我们可以通过操作系统的包管理器来做这件事:

sudo apt-get install redis-server

这是最简单也是最为推荐的方法,但我们也可以从头来安装并且手动配置。根据的说明,我们可以如此配置:

sudo apt-get install gcc make build-essential tclwget http://download.redis.io/releases/redis-3.0.2.tar.gztar xzf redis-3.0.2.tar.gzcd redis-3.0.2makemake testsudo make install

如果你运行make遇到错误提示jemalloc.h那么运行make distclean然后在运行makemake test命令是选择性运行的,但是很有帮助。

注意:如果你看到这里,而3.0.2已经不是最新的版本,那么根据你的最新版本号去调节命令。

为了防止一些常见的警告(至少在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'

我们也要确保最后的命令在exit 0上被添加到了/etc/rc.local,因此能保证在每个重启的服务器上能重新发送。最后我们可以用sudo reboot重启服务器并且运行有sudo redis-server的Redis检查是否一切正常。

最后,我们要,所以我们要跟着官方的说明去完成配置。

Predis

我们之前说了一些关于,我们将要将其用到本文的例子中:

composer require predis/predis

进一步的,假设我们已经了解之前叙述的关于Predis的知识。

和之前发表的关于Predis相比,虽然是有一些不同(比如过渡到命名空间),但我们需要的API几乎是一样的。

实施

要在我们app里运用Redis,我们需要遵循以下的程序:
 查看当前的缓存中是否有查询结果
 如果是,抓取他们
 如果没有,把他们拿来,储存,将他们发送到app的其他部分

因此,实施非常的简单:在“form submitted”下检查(寻找“search”参数),我们实例化Predis客户端,计算search查询的MD5 hash值,然后检查查询结果是否已经被缓存。如果失败,就在重复前面的流程。

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

我们将查询结果序列化并直接保存到cache里。然后我们在模块外立即抓取他们,app的流程就和往常一样继续。而index.php改变的部分如下:

// Check if the search form was submittedif (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'));

进过测试,我们可以看到它的魅力所在—如果我们刷新页面,或执行另一个查询,就会立即执行一次查询,然后会回到之前的那个。最后我们添加,提交,推动部署一下内容:

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

就是这么简单,我们的最新版的app已经上线,而且使用的Redis。

注意:如果你想知道我们是如何用一条命令从开发模式转到生产部署,你可以看。

微调

为了进一步的提升性能,Predis推荐安装phpiredis,这是个PHP的扩展,目的是“降低序列化和解析Redis协议的成本”。可以看作我们完全控制了服务器,有什么理由不试试呢?

cd ~git clone https://github.com/redis/hirediscd hiredismakesudo make installcd ~git clone https://github.com/nrk/phpirediscd phpiredisphpize && ./configure --enable-phpiredismakesudo make installsudo touch /etc/php5/mods-available/phpiredis.inisudo sh -c 'echo "extension=phpiredis.so" > /etc/php5/mods-available/phpiredis.ini'sudo php5enmod phpiredissudo service php5-fpm restart

以上是安装的前提,并且启用了扩展。现在我们要做的就是利用链接去配置Predis客户端。因此我们需要更换:

$redis = new Client();

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

就是这么简单!现在我们的Redis安装会更快!

总结:

在本教程中,我们利用Redis结合Predis库来提升已部署的app的速度,我们平衡大数据海洋的水滴中可用的RAM来存储每天一次查询的结果,然后从缓存中返回这些结果,而不是重新运行一遍查询。但这确实意味着结果不会总是最新的,但就这边文章,其实查询结果没有被刷新的次数比这种情况多得多。

注:关于更多的有关Redis的知识可以参考redisdoc.com (此网站文档是 Redis Command Reference 和 Redis Documentation 的中文翻译版, 阅读这个文档可以帮助你了解 Redis 命令的具体使用方法, 并学会如何使用 Redis 的事务、持久化、复制、Sentinel、集群等功能。)

我们云巴的产品也是使用redis存储实践,大家也可以来交流学习~

你可能感兴趣的文章
PHP 程序员的技术成长规划
查看>>
用于守护进程的出错处理函数
查看>>
memcached 分布式聚类算法
查看>>
禁止body滚动允许div滚动防微信露底
查看>>
Xtreme8.0 - Kabloom dp
查看>>
jquery css3问卷答题卡翻页动画效果
查看>>
MDK5.00中*** error 65: access violation at 0xFFFFFFFC : no 'write' permission的一种解决方法
查看>>
Android 集成支付宝支付详解
查看>>
SQL分布式查询、跨数据库查询
查看>>
C#------连接SQLServer和MySQL字符串
查看>>
Arcgis Licensemanager 不能启动的原因之一(转载)
查看>>
(原)Android在子线程用handler发送的消息,主线程是怎么loop到的?
查看>>
$digest already in progress 解决办法——续
查看>>
虚拟机 centos设置代理上网
查看>>
Struts2中Date日期转换的问题
查看>>
mysql 数据类型
查看>>
Ubuntu 设置当前用户sudo免密码
查看>>
设置tomcat远程debug
查看>>
android 电池(一):锂电池基本原理篇【转】
查看>>
Total Command 常用快捷键
查看>>