技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> PHP --> 通过Twemproxy提升PHP/Redis的性能

通过Twemproxy提升PHP/Redis的性能

浏览:999次  出处信息

   Twemproxy 可以说是最古老的 Redis 代理软件了,一般来说,引入代理后性能会比没有引入代理时低一些,毕竟代理会导致一些额外的性能损耗,可是 Twemproxy 却会提升性能, 这主要得益于它的 Pipelining 功能可以实现打包请求,简单点说:当代理收到多个并发请求时,它会把这些请求打包成一个请求发送给后端服务器,从而减少不必要的 RTT。关于 Pipelining 本文不做过多讨论,实际上我想说的是它的另一个功能:连接池!下面看看如何通过 Twemproxy 提升 PHP/Redis 的性能。

   

   众所周知,PHP 的运行方式很难实现真正的连接池,不过通过本地的 Unix Domain Socket,我们可以绕开连接池,实现曲线救国,具体介绍大家可以参考我以前写的旧文:史上最LOW的PHP连接池解决方案,在那篇文章里,我借助 Nginx 的 Stream 模块,实现了一个 Redis 代理,通过它来实现连接池功能,然后 PHP 通过本地的 Unix Domain Socket 来连接 Redis 代理,从而达到连接池的效果,不过在本文里,我不再自己编写 Redis 代理,而是直接使用 Twemproxy,让我们看看效果如何。

   为了让 PHP 能够通过本地的 Unix Domain Socket 来连接 Redis 代理,PHP 和 Redis 代理必须安装在同一台服务器上,后端真正的 Redis 服务器通常不会和 PHP 在同一台服务器上,本文使用 127.0.0.1 是出于方便的考虑,假设你已经安装好了,让我们看看配置文件 /etc/redis.yml:

instance:
  listen: /var/run/nutcracker.sock
  redis: true
  redis_auth: ...
  preconnect: true
  servers:
   - 127.0.0.1:6379:1

   让我们把服务运行起来,So easy:

shell> /path/to/nutcracker -c /etc/redis.yml

   下面让我们压测看看性能怎么样,测试脚本 test.php 如下:

<?php

$redis = new Redis;

if (empty($_GET['twemproxy'])) {
    $redis->connect('127.0.0.1', 6379);
} else {
    $redis->connect('/var/run/nutcracker.sock');
}

$redis->auth('...');

$redis->set('foo', 'bar');
echo $redis->get('foo');

?>

   通过 ab 模拟一个高并发的场景,压测看看性能有没有提升:

shell> ab -k -n 10000 -c 100 "http://path/test.php?twemproxy=0"
shell> ab -k -n 10000 -c 100 "http://path/test.php?twemproxy=1"

   一开始,结果让人非常沮丧,使用 Twemproxy,没有带来任何性能上的提升。这是为什么呢?原来是因为 Twemproxy 是单线程的,缺省情况下只能使用一个 CPU,这个问题好解决,我们只要按 CPU 个数启动多个进程(假设有 4 个 CPU)即可。

   首先,创建多个配置文件 /etc/redis[1-4].yml:

instance:
  listen: /var/run/nutcracker[1-4].sock
  redis: true
  redis_auth: ...
  preconnect: true
  servers:
   - 127.0.0.1:6379:1

   然后,启动多个 Twemproxy 进程:

shell> /path/to/nutcracker -c /etc/redis1.yml -m 512 -s 11111 -d
shell> /path/to/nutcracker -c /etc/redis2.yml -m 512 -s 22222 -d
shell> /path/to/nutcracker -c /etc/redis3.yml -m 512 -s 33333 -d
shell> /path/to/nutcracker -c /etc/redis4.yml -m 512 -s 44444 -d

   相应的,测试脚本 test.php 也要做出适当的调整:

<?php

$redis->connect('/var/run/nutcracker' . rand(1, 4) . '.sock');

?>

   再执行压测,结果发现使用 Twemproxy 后,性能整整提升了 100%!如果你在压测过程中通过 top 命令观察 CPU 情况的时候,会发现所有 CPU 都被吃满了,基本上没有 idle,此外,如果你在压测过程中通过 MONITOR 观察 Redis 执行的命令,你会观察到 Pipelining 现象,还会观察到 AUTH 被省略了,这些都是性能提升的原因。

   说明:为什么 mbuf-size 在高并发的时候推荐设置为 512,参考 recommendation

   此外,有时候系统可能会偏爱 CPU0,此时在运行多个 Twemproxy 进程的时候,可以考虑通过 taskset 命令绕开 CPU0,避免 CPU0 成为性能瓶颈。

建议继续学习:

  1. Xvfb+YSlow+ShowSlow搭建前端性能测试框架    (阅读:54292)
  2. 30分钟3300%性能提升――python+memcached网页优化小记    (阅读:12224)
  3. Go Reflect 性能    (阅读:10561)
  4. 长连接(KeepAlive)在 http 连接中的性能影响    (阅读:7157)
  5. SQL vs NoSQL:数据库并发写入性能比拼    (阅读:6693)
  6. 服务器性能测试工具推荐    (阅读:6570)
  7. WEB性能测试工具推荐    (阅读:5728)
  8. 分析进程内存分配情况,解决程序性能问题    (阅读:5440)
  9. 由12306.cn谈谈网站性能技术    (阅读:5058)
  10. [调优] Squid 不同版本的性能对比    (阅读:4337)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1