关于REDIS的并发问题的请教

428 views
Skip to first unread message

语镜汽车——闵敢

unread,
Aug 27, 2012, 8:30:43 AM8/27/12
to thinkinlamp
各位大侠:
     小弟目前碰到一个棘手的问题,用REDIS来做缓存的时候,发现在并发情况下,REDIS 对于短连接的处理能力很差。
     测试环境:CENTOS 6.2 PHP 5.4 PHPREDIS2.0插件  nginx/1.1.16 
      DELL 2950 八核八G  REDIS 的并发数的配置文件部分已经注释掉了。硬盘保存功能也关闭了。
      内网同样配置的机器用webbench 发起攻击,并发调用同样的PHP
$sUserID = 'abcasdasda';
$sKey = 'ProvinceName';
$redis = new Redis();
$nError = $redis->connect('127.0.0.1', 6379);
if ($nError != 1)
    echo -9998;
$b = $redis->hget($sUserID, $sKey);
if(empty($b))
echo -9999;
else
$redis->incr('newCount');
$redis->close();

在浏览器中测试成功后,运行一次PHP 。newcount 加一。
 
运行webbench 经过N轮各种参数的测试,每秒newcount 只能增加470个左右。
同样环境下运行插入MYSQL 的PHP

<?php
$con = mysql_connect("localhost","root","abc123");
if (!$con) {
die('Could not connect: ' . mysql_error());
echo -9999;//......
return -9999;
}
else {
mysql_select_db("test", $con);

if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) 
{
        $realip = $_SERVER["HTTP_X_FORWARDED_FOR"];   
    } 
    elseif (isset($_SERVER["HTTP_CLIENT_IP"])) 
{
        $realip = $_SERVER["HTTP_CLIENT_IP"];   
    } 
    else 
{
        $realip = $_SERVER["REMOTE_ADDR"];
    }
$URL=$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$query="Insert into url_log (time,url,u_return,client_ip) values ( now(), '".$URL."', '".$strReturn."','".$realip."')";
if(mysql_query($query))
{
        echo "DB Insert OK";//......
    }
    else
{
        echo "DB Insert Error";//......
    }
}
mysql_close($con);
?>

每秒插入的记录数,稳定在2000以上,远远比REDIS 要完成的操作多。

想请问大家,如何能提高REDIS 的并发能力,我们的应用场景是短链接为主,每个链接处理的问题都比较少。
希望能利用REDIS 作为读的主力。希望大家指点,谢谢!


------------------
 
------------------
  路   况  快   分   享 !
mirrtalk语镜道客
 
+ 关注  语镜道客--闵敢 http://weibo.com/mg00736448
闵敢13816372844
QQ:182050540
固定电话:021-32525243,44,45,46
www.mirrtalk.com
上海长宁区北渔路28弄8号101室
上海语镜汽车信息技术有限公司
 

小马xiaoma

unread,
Aug 27, 2012, 10:28:30 PM8/27/12
to think...@googlegroups.com
首先,你的对比测试有问题

在REDIS中,有两次操作,一次是$redis->hget($sUserID, $sKey); 而另外一次操作是incr('newCount'); incr操作是一个原子操作,其中包含的操作如下:
1. 对newCount上写锁
2. 读取newCount数值
3. 读取到的数值+1
4. 对newCount解锁。

incr('newCount')应该是为了统计操作次数而增加代码,但是这个代码已经严重影响了性能,自然照成了测试结果的巨大偏差。

而mysql只有一条插入语句,数据库没有锁操作,可以支持大并发。

你可以把$redis->incr('newCount');语句去掉,再看看效果,统计可以通过web日志得到结果。

其次看看别人的测试结果:

性能测试结果:

SET操作每秒钟 110000 次,GET操作每秒钟 81000 次,服务器配置如下:

Linux 2.6Xeon X3320 2.5Ghz.

stackoverflow 网站使用 Redis 做为缓存服务器。



 

--
ThinkingInLAMP邮件组使用说明:http://blog.thinkinlamp.com/?p=758

张伟

unread,
Aug 28, 2012, 3:39:35 AM8/28/12
to think...@googlegroups.com
redis是单进程,不存在锁问题

--
ThinkingInLAMP邮件组使用说明:http://blog.thinkinlamp.com/?p=758

min gan

unread,
Sep 24, 2012, 10:32:37 PM9/24/12
to think...@googlegroups.com
我后来测试过了,用一个PHP文件对REDIS持续操作,每秒最多7000次INCR 还是比较低。
现在用webdis,感觉好多了。同样环境下,每秒INCR到了17000次。不知道还想提高的话应该用什么办法

在 2012年8月28日星期二UTC+8下午3时39分57秒,张伟hemono写道:

张伟

unread,
Sep 25, 2012, 12:16:02 AM9/25/12
to think...@googlegroups.com
ngx_lua扩展+resty.redis

--nginx.conf--

worker_processes  1;
worker_rlimit_nofile 10240;

events {
    worker_connections 10240;
}

http {
    lua_package_path "/home/hemon/www/lua/lib/?.lua;;";
    resolver 8.8.8.8;
    server {
        listen 8080;
        root /home/hemon/www/lua/www;
        location / {
            content_by_lua_file /home/hemon/www/lua/incr.lua;
        }
    }
}

-- incr.lua --

local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end
res, err = red:incr("incr")
if not ok then
    ngx.say("500 err\n", err)
    return
end
ngx.say("200 ok\n", res)
red:set_keepalive(0, 100)

--AB Test (keep alive)--
Vmware虚拟机 : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz  单核+512M内存

C:\Users\hemon>ab -n 10000 -c 100 -k http://192.168.203.81:8080/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.203.81 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        Tengine/1.2.3
Server Hostname:        192.168.203.81
Server Port:            8080

Document Path:          /incr
Document Length:        14 bytes

Concurrency Level:      100
Time taken for tests:   0.899 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Keep-Alive requests:    9948
Total transferred:      1631533 bytes
HTML transferred:       140154 bytes
Requests per second:    11122.83 [#/sec] (mean)
Time per request:       8.991 [ms] (mean)
Time per request:       0.090 [ms] (mean, across all concurrent requests)
Transfer rate:          1772.19 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       5
Processing:     1    9   4.1      9      48
Waiting:        1    9   4.1      9      48
Total:          1    9   4.1      9      50

Percentage of the requests served within a certain time (ms)
  50%      9
  66%     11
  75%     12
  80%     12
  90%     14
  95%     15
  98%     16
  99%     19
 100%     50 (longest request)



--
ThinkingInLAMP邮件组使用说明:http://blog.thinkinlamp.com/?p=758

Reply all
Reply to author
Forward
0 new messages