通过Twemproxy提升PHP/Redis的性能
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 成为性能瓶颈。
建议继续学习:
- Xvfb+YSlow+ShowSlow搭建前端性能测试框架 (阅读:54214)
- 30分钟3300%性能提升――python+memcached网页优化小记 (阅读:12128)
- Go Reflect 性能 (阅读:9957)
- 长连接(KeepAlive)在 http 连接中的性能影响 (阅读:7052)
- SQL vs NoSQL:数据库并发写入性能比拼 (阅读:6629)
- 服务器性能测试工具推荐 (阅读:6473)
- WEB性能测试工具推荐 (阅读:5650)
- 分析进程内存分配情况,解决程序性能问题 (阅读:5351)
- 由12306.cn谈谈网站性能技术 (阅读:4944)
- [调优] Squid 不同版本的性能对比 (阅读:4211)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:老王 来源: 火丁笔记
- 标签: twemproxy 性能
- 发布时间:2018-06-26 12:25:17
- [55] 如何拿下简短的域名
- [54] IOS安全–浅谈关于IOS加固的几种方法
- [53] Go Reflect 性能
- [53] Oracle MTS模式下 进程地址与会话信
- [51] android 开发入门
- [49] 图书馆的世界纪录
- [49] 读书笔记-壹百度:百度十年千倍的29条法则
- [46] 【社会化设计】自我(self)部分――欢迎区
- [38] 程序员技术练级攻略
- [31] 视觉调整-设计师 vs. 逻辑