memcache的安装就不说了。
redis的安装参看这里:http://www.oschina.net/question/12_18065
不过要注意的是cp redis-benchmark redis-cli redis-server /usr/bin/ 可能不成功,也许是版本不同,我安装时这些文件在安装后的src目录中。
phpredis的下载https://github.com/nicolasff/phpredis
安装:
# tar -zxvf owlient-phpredis-2.1.1-0-g5a07edc.tar.gz # mv owlient-phpredis-5a07edc php-5.3.4/ext/phpredis/ # cd php-5.3.4/ext/phpredis/ # /usr/local/php/bin/phpize # ./configure --with-php-config=/usr/local/php/bin/php-config # make && make install # vi /usr/local/php/lib/php.ini (加入: extension=redis.so ) # service httpd -k restart
如果phpize不能运行,请检查是否安装了php-devel。
测试代码及结果:
memcache的测试代码如下:(用时 7.2866051197052 秒)
$mem = new Memcache; $mem->connect("127.0.0.1", 11211); $time_start = microtime_float(); //保存数据 for($i = 0; $i < 100000; $i ++){ $mem->set("key$i",$i,0,3); } $time_end = microtime_float(); $run_time = $time_end - $time_start; echo "用时 $run_time 秒\n"; function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
redis的测试代码如下:redis1.php (用时 7.1237368583679 秒)
//连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $time_start = microtime_float(); //保存数据 for($i = 0; $i < 100000; $i ++){ $redis->sadd("key$i",$i); } $time_end = microtime_float(); $run_time = $time_end - $time_start; echo "用时 $run_time 秒\n"; //关闭连接 $redis->close(); function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
如果需要在设置键值的同时设置过期时间,测试代码如下:redis2.php(用时 14.462860107422 秒)
//连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $time_start = microtime_float(); //保存数据 for($i = 0; $i < 100000; $i ++){ $redis->sadd("key$i",$i); $redis->expire("key$i",3); } $time_end = microtime_float(); $run_time = $time_end - $time_start; echo "用时 $run_time 秒\n"; //关闭连接 $redis->close(); function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
后来在网上发现redis有一个神奇的功能叫事务,通过multi原子性的将一段代码块依次执行,从而达到一个完整功能模块的执行。不幸的是,通过测试发现,采用multi方式执行代码时并没有减少请求次数,相反在执行multi指令和exec指令时都要发送请求,从而将运行时间变成了原来的四倍,即四条指令的运行时间。测试代码如下:redis3.php(用时 28.565366983414 秒)
//连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $time_start = microtime_float(); //保存数据 for($i = 0; $i < 100000; $i ++){ $redis->multi(); $redis->sadd("key$i",$i); $redis->expire("key$i",3); $redis->exec(); } $time_end = microtime_float(); $run_time = $time_end - $time_start; echo "用时 $run_time 秒\n"; //关闭连接 $redis->close(); function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
问题出现了瓶颈,有好多公司需要海量数据处理,每秒5000次远不能满足需求,然后由于redis主从服务器上比memcache有更大的优势,为了将来数据的着想,不得不使用redis,这时候出现了一种新的方式,即phpredis提供的pipline功能,该功能能够真正的将几条代码封装成一次请求,从而大大提高了运行速度。测试代码如下:redis4.php(用时 8.7219619750977 秒)
//连接 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $time_start = microtime_float(); //保存数据 for($i = 0; $i < 100000; $i ++){ $pipe=$redis->pipeline(); $pipe->sadd("key$i",$i); $pipe->expire("key$i",3); $replies=$pipe->execute(); } $time_end = microtime_float(); $run_time = $time_end - $time_start; echo "用时 $run_time 秒\n"; //关闭连接 $redis->close(); function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); }
运用这个操作可以非常完美的将赋值操作和设置过期时间操作打包到一个请求去执行,大大提高了运行效率。