千万级 PHP 接口优化
kim
问题
• 什么是千万级?
• 接口扛不住,措施 1 、 2 、 3 是?
• 如何优化?
并发数
• 10000000 / 86400 ≈ 116
• 按高峰期 10 倍,即 1160req/s
观察
• Ping
• Trace
• HttpWatch
• Uptime
• Top
• Free
• Nagios
Top 举例
紧急措施
• 重启
• 缓存穿透
• 启用备机(如果有的话)
系统日志
• Nginx access log
• Nginx error log
• PHP error log
• PHP slow log
访问统计
• 各种访问统计
• awk -F"[" '{ print $1 }'
/home/nginx/logs/access.log | sort | uniq -c
| sort -rn | head -n 10
非 200 统计
• 非 200 访问
• cat /home/nginx/logs/access.log | grep -v
""200""
日志统计系统
• https://56.com/ops/index.htm
PHP 慢?
• 有 opcode cache 的 PHP ,已经够快了
!
真正的原因
• 端口( Socket )连接慢
• 端口( Socket )数据交互多
举例 1
• mysql_connect()
• mysql_query()
• redis->connect()
• redis->select()
举例 2
• memcache->connect()
• memcache->get()
• new Mongo()
• MongoCollection->find()
举例 3
• Http::Get()
如何优化 Socket
释放要主动
• mysql_close()
• Redis->close()
• Memcache->close()
• Mongo->close()
• unset
验证要提前
• 比如: xxx.56.com/api/someapi.php :
• <?php
• if (!isset($_GET['ids'])) {
• die('Invalid arguments');
• }
• require 'index.php';
缓存要耦合
• 评论数
• 人气
• 视频顶踩
如何优化 PHP
PHP 优化利器
• http://pecl.php.net/package/xhprof
XHProf 安装
• XHProf lib 包
• 代码举例
XHProf 举例
代码“完美”了,还能优化吗?
Tcp 短连接也不能忍受了!
缓存优化利器
• https://github.com/twitter/twemproxy
• 安装与配置
特性
• 1. 轻量,安装配置简单
• 2. 多点长连接
• 3. 自动冗余
• 4. 支持 memcached ascii 和 redis 协议
• 5. 可监控,可记录日志
站内使用状况
• Infov 视频信息接口
• Stat 人气接口
• Album 专辑信息接口
客户端选择
• Memcached (推荐) VS Memcache
• Phpredis (推荐) VS Predis
反复实战
• Memp 类使用举例
• $mm = new Memp(array('servers' =>
array('127.0.0.1', 22122)));
Twemproxy 日志
• -v, --verbosity=N
set logging level (default: 5, min: 0, max:
11)
• 日志举例
Twemproxy 的问题
Memcache 删除不了
• Bug 如下:
• command_len = spprintf(&command, 0,
"delete %s %d", key, time);
• command[command_len] = '0';
• 需要人工修复:
• command_len = spprintf(&command, 0,
"delete %s", key);
乱码与截断
• 不能压缩
• Memcached->setOption(
Memcached::OPT_COMPRESSION,
false);
EOF
• Twemproxy 要求 EOL 是 “ rn” ,而不是
“ n” ,所以在一些情况下是要注意,比如
使用 nc 时,要带上 -C 参数,但不是每
个版本的 nc 都带这个参数
• $ echo get key | nc -C 127.0.0.1 22121
配置要接地气
• 痛苦的经历:不支持 redis->select()
保正一致性
• hash: md5
• distribution: ketama
缓存冗余
• auto_eject_hosts: true
• 无规律
• 不一致
如何清缓存?
• 循环删除 + 队列补刀
• Infov 代码举例
总结
毫秒必争
• 如过你的接口平均服务时间是 30ms ,那
么 1ms 的价值就是 3% 的性能提升!
• 提升 1ms 的途径:
• 1. 把 count 移出 for 循环
• 2. 把 preg_match 换成了 strstr
• 3. 去掉了数组的 交集 / 并集 / 合并 操作
• 4. 少创建了几个 memcache 对象
• 实践和测试
• 加节点是最后手段
谢谢!

PHP Optimization for Millions Visits Level