Redis长短连接的区别

 

本文介绍了phpredis中与redis创建链接的两种方式:connect(短链接)和pconnect(长链接)的区别。
问题背景:
项目采用LNMP架构,考虑到数据访问性能问题,所以使用redis来作数据存储,以前一直都是经过直连IP的方式来访问redis,可是运维说redis用sentinel作的高可用,若是直连IP去访问,高可用就没法生效了,所以决定切换成域名的访问方式。
切换域名以后,问题就来了,不少接口出现调用超时的状况,在php-fpm的慢日志中能够看到超时接口的函数调用栈,接口的逻辑很简单,只是从redis取一些数据出来,并无作其余事情,甚至连日志都没打,为什么会超时呢?
问题追踪:
既然当天作了切换访问方式的变动,就必定跟这个有关。切换先后惟一的区别就是切换成域名的访问方式以后,每次链接redis须要先到域名服务器将域名解析成IP,而后再去链接,若是直连IP就能够省去域名解析的过程,难道是域名解析速度太慢致使超时?
问题定位:
写了一个简单的脚本,看了一下域名访问和IP访问的耗时差异到底多大,代码以下,
//test.php
<?php
function microtime_float()
{
list($usec, $sec) = explode(” “, microtime());
return ((float)$usec + (float)$sec);
}

$begin = microtime_float();
$redis=new Redis();
$redis->connect(“10.100.24.198″,6380);
$end = microtime_float();
$ip_cost = intval(($end – $begin)*1000000);

$begin = microtime_float();
$redis->connect(“videogh-6380-redis1.m6.tudou.com”,6380);
$end = microtime_float();
$domain_cost = intval(($end – $begin)*1000000);

echo “ip costip_cost us,domain_costdomain_cost us\n”;

//结果
ip cost:514 us,domain_cost:26972 us
IP直连和域名链接的耗时居然差了40倍之多!!难怪会有如此多的请求超时。
问题解决:
既然切换成域名后,与redis频繁创建链接致使超时,所以考虑redis的长链接方式,即pconnect方式。注意,这里说的长链接和短链接,并非指TCP和UDP,其实redis自己也只支持域套接字和TCP链接,这里说的长链接是指屡次请求之间能够对redis链接进行复用,即只在第一次执行请求是创建链接,之后每次请求只是从链接池中将链接取出,再也不从新创建链接;而短链接表示链接在屡次请求之间不可复用,每次请求都须要从新创建链接。
理论上虽然可行,但还须要对pconnect的实际执行效果进行验证,验证过程以下。
验证过程:
考虑用抓包和lsof两种方式进行验证,
准备工做
环境:
Linux+nginx+fpm+PHP5.5
将fpm的参数配置为
pm.max_children = 1;
pm.start_servers = 1;
pm.max_spare_servers = 1;
经过修改php-fpm的参数,将php-fpm的进程设置为一个,这样就能够准确找到执行请求的php-fpm进程id,
页面对应的php代码
public function test_redis()
{
$redis = new Redis();
//redis->connect(“127.0.0.1”, 6379); //connect链接
redis->pconnect(“127.0.0.1”, 6379); //pconnect链接
exit();
}

一、lsof方式
先用pconnect的方式链接方式请求页面的test_redis函数,并执行命令lsof –n –p (fpm-pid),查看php-fpm的句柄使用状况,以下图所示
说明请求结束后,php-fpm中仍然保持与redis的链接,下次请求仍然能够对该链接进行复用;若是使用connect,则获取不到链接信息。

二、抓包方式
抓包命令:tcpdump –i any –X –v –vv tcp and dst port 6379
一样用connec方式和pconnect方式执行屡次,经过抓包发现,使用connect方式链接每次都能抓到包,说明connect每次都会创建链接;使用pconnect方式链接只有第一次访问的时候能抓到包,之后每次执行都抓不到包,说明链接只创建一次。
并且,当使用pconnect方式链接时,经过redis-cli链接到redis,并执行info clients,能够看到connected_clients=2,排除终端的命令行链接之外,还有一个是与php-fpm保持的长链接,说明即便请求结束,php-fpm仍然会保留与redis的链接;若是采用connect方式进行链接,则connected_clients=1,即请求结束后php-fpm就释放了与redis的链接。

 

 

 

原文连接:http://bbs.redis.cn/forum.php?mod=viewthread&tid=721php

相关文章
相关标签/搜索