Redis pub/sub(Publish,Subscribe)

目录

Redis pub/sub(Publish,Subscribe)

1        Pub/Sub功能

2        Pub/Sub机制

3        Pub/Sub redis当中的实现

4        Php-redis扩展测试

5        Redis pub/sub python客户端测试

6        Redis pub/subnode.js结合

7        Redis pub/sub压力测试

8        Redis pub/sub服务应用场景分析

9        附件:

 


1、Pub/Sub功能

Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。

 

Redis <wbr>pub/sub(Publish,Subscribe)

Publisher/subscribe 简易模型

 

2、 Pub/Sub机制

Pub/Sub功能(means Publish,Subscribe)即发布及订阅功能Redis <wbr>pub/sub(Publish,Subscribe)


 

1.      时间非耦合:发布者和订阅者不必同时在线,它们不必同时参与交互。

Redis <wbr>pub/sub(Publish,Subscribe)

 

2.      空间非耦合:发布者和订阅者不必相互知道对方所在的位置。发布者通过事件服务发布事件,订阅者通过事件服务间接获得事件。发布者和订阅者不需要拥有直接到对方的引用,也不必知道有多少个订阅者或者是发布者参与交互。

Redis <wbr>pub/sub(Publish,Subscribe)

 

3.      同步非耦合:发布者/订阅者是异步模式。发布者可不断地生产事件,而订阅者(通过一个回调)则可异步地得到产生事件的通知。

Redis <wbr>pub/sub(Publish,Subscribe)




 

分类:

按照订阅方式分为基于主题(topic-based)、基于内容(content-based)、基于类型(type-based)的pub/sub方式。

 

 

 Redis <wbr>pub/sub(Publish,Subscribe)


 

 

总结:

Pub/Sub是可适用于可扩展要求高、松散耦合系统的分布式交互模型。

在抽象层中,它的时间非耦合、空间非耦合和同步非耦合性可允许参与者不依赖另一个而独立操作,具有一定的可扩展性;然而在实现层,可扩展性仍受其他原因的牵制。

例如:1、灵活的订阅要求复杂的过滤和路由算法;

     2、高可用性开销(事件侦听、日志重传);

     3、消息认可带来的网络流量消耗;

4、庞大的订阅者数据带来的系统开销;

基于事件的Pub/Sub中间件的开发与利用在一定程度上可以提高系统的效率。

3、 Pub/Sub redis当中的实现

Redis-cli连接测试命令行参考附件I

协议测试命令

 

l 订阅者(redis-cli)连接订阅

/usr/local/bin/redis-cli  -h 10.54.37.212 -p6380


Redis <wbr>pub/sub(Publish,Subscribe)

 

redis-cli充当订阅者订阅(first second)两个topic

SUBSCRIBE firstsecond

Redis <wbr>pub/sub(Publish,Subscribe)

 

l 发布者(redis-cli)连接发布

/usr/local/bin/redis-cli  -h 10.54.37.212 -p6380

Pubish firstwangbin

Publish secondwangbin_second

Redis <wbr>pub/sub(Publish,Subscribe)

l 订阅者(redis-cli)信息接收

 

 Redis <wbr>pub/sub(Publish,Subscribe)


l 取消订阅UNSUBSCRIBE测试

Redis-cli对取消订阅有bug可以使用telnet 进行测试

 

Redis <wbr>pub/sub(Publish,Subscribe)

取消订阅测试成功;

l 匹配模式订阅PSUBSCRIBE测试

订阅者:

Redis <wbr>pub/sub(Publish,Subscribe)

 

发布者:

publishnews.wangbin wangbin_patterncommand

Redis <wbr>pub/sub(Publish,Subscribe)

 

l 匹配模式取消订阅PUNSUBSCRIBE测试

telnet下测试如下:

PSUBSCRIBE news.* wangbin*

punsubscribe wangbin*

Redis <wbr>pub/sub(Publish,Subscribe)

 

测试成功!

4、 Php-redis扩展测试

https://github.com/nicolasff/phpredispecl扩展包目前只提供了两个接口 publish  subscribe

phpredisc写的php模块

https://github.com/jamm/Memory/blob/master/RedisServer.php

php这个是php是基于redis protocolfsocketopen链接后操作的类库,提供的接口比较全面;publish可以进入数据,但是subscrbie没有阻塞;

可以在原类包当中修改其加入对阻塞模形的支持;

发布功能:

$redis= new Redis();

$res =$redis->connect($REDIS_HOSTS['CACHE']['host'],$REDIS_HOSTS['CACHE']['port'], 1 );

$res =$redis->publish($key,$value);

定阅功能:                           

$redis= new Redis();

$res =$redis->pconnect($REDIS_HOSTS['CACHE']['host'],$REDIS_HOSTS['CACHE']['port']);

$res =$redis->subscribe(array($key),array('SinaRedis','subscribe_handler'));

第二个参数为回调方法;

public static function subscribe_handler($redis, $channel,$msg){

           print_r($redis);

           echo $chan;

           echo $msg;

           return true;

 }

 

定阅 redis_subscriber.php

SinaRedis::subscribe('wangbin_test');

发布redis_publisher.php

测试收到订阅者收到发布的内容

 

 Redis <wbr>pub/sub(Publish,Subscribe)


Php-redis扩展bug

段错误:

无论是connect 还是pcconnect 当超时断后,会报错segmentation fault;

超时设置bug

仍会断开解决方法:ini_set('default_socket_timeout', -1);// itworks fine

WebServer端测试

Web端订阅应用

Apacheob_flush flush后可以输出,但是会漏下最后一条;求解决方案

Nginx 会报504错误;求解决方法

Nginx 模块与redis直接连接呢?

Php-Fpm有没有什么设置呢

5、 Redis pub/sub python客户端测试

Wgethttps://github.com/downloads/andymccurdy/redis-py/redis-2.2.4.tar.gz

tar -xvf  redis-2.2.4.tar.gz

cd redis-2.2.4

python setup.py intall

安装成功

交互模式下测试:

发布者:

Python

Type "help", "copyright", "credits" or"license" for more information.

>>> importredis

>>> r =redis.Redis('10.54.37.212',6380);

>>>r.publish('wangbin_test','this is ainformation');

59L

>>> 

订阅者:

[root@hadoop-master1 python]#python

Python 2.4.3 (#1, Sep  3 2009, 15:37:12)

[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] onlinux2

Type "help", "copyright", "credits" or"license" for more information.

>>> importredis

>>> r =redis.Redis('10.54.37.212',6380);

>>>r.subscribe('wangbin_test');

>>> for msg inr.listen(): \

...    print msg

{'pattern': None, 'type': 'message','channel': 'wangbin_test', 'data': 'this is ainformation'}

收到json字符串

Publisher.py

Redis <wbr>pub/sub(Publish,Subscribe)

 

Subscribe.py

 

 Redis <wbr>pub/sub(Publish,Subscribe)


6、 Redis pub/subnode.js结合

Wgethttp://nodejs.org/dist/v0.6.6/node-v0.6.6.tar.gz

Tar –xvf node-v0.6.6.tar.gz

Cd node-v0.6.6

./configure

Make

Make install

Node 安装在/usr/localbin

添加到环境变量里面:

export PATH=/usr/local/bin/:$PATH

安装:npm

curl -O http://npmjs.org/install.sh

sh install.sh

安装成功

Tar 版本过低,升级下

wget http://ftp.gnu.org/gnu/tar/tar-1.26.tar.gz

./configure --prefix=/usr --bindir=/bin--libexecdir=/usr/bin 

Make

Make install

Tar –version

tar (GNU tar) 1.26 升级成功

安装socket.io  expresshiredis redis

/usr/local/bin/npm  install socket.io

/usr/local/bin/npm  install express

/usr/local/bin/npm  install hiredisredis

事件驱动用例:

Publish.js

var redis =require("redis");

 

try{

 

   var client =redis.createClient(6380,'10.54.37.212');

 

   client.on(

       "error",

       function(err){

           console.log("err"+err);

           }

 

   );

   client.on('ready',

       function(){

           client.publish('wangbin_test',"test,i am test");

           client.publish('wangbin_test2',"test,i am test2");

           client.end();

           }

   );

}

catch(e){

       console.log("err:"+e);

}

Subscribe.js

var redis =require("redis");

 

try{

   var client =redis.createClient(6380,'10.54.37.212');

   client.on(

       "error",

       function(err){

           console.log("err"+err);

           }

   );

   client.on('ready',

       function(){

           client.subscribe('wangbin_test');

           client.subscribe('wangbin_test2');

           //client.end();

           }

   );

   client.on('subscribe',

       function(channel,count){

           console.log("channel:" + channel + ",count:"+count);

           }

   );

   client.on('message',

       function(channel,message){

           console.log("channel:"+ channel + ", msg:"+message);

           }

   );

   client.on('unsubscribe',

       function(channel,count){

           console.log("channel:" + channel + ",count:"+count);

           }

   );

}

catch(e){

       console.log("err:"+e);

}

测试结果:

Redis <wbr>pub/sub(Publish,Subscribe)

 

另外还支持:pmessage, psubscribe, punsubscribe事件监听;

---------------------------------------------------------------------------------------------------------

Node.js  Socket.io redispub/sub主动推送数据到浏览器前端

另外还支持:pmessage, psubscribe, punsubscribe事件监听;

 

Server.js

var app =require('http').createServer(handler)

  , io= require('socket.io').listen(app)

  , fs= require('fs');

var redis =require('redis');

var redis_client  =redis.createClient(6380,'10.54.37.212');

app.listen(3000);

function handler (req, res){

 fs.readFile(__dirname + '/index.html',

 function (err, data) {

    if(err) {

     res.writeHead(500);

     return res.end('Error loading index.html');

   }

 

   res.writeHead(200);

   res.end(data);

 });

}

io.sockets.on('connection', function (socket){

 socket.emit('news', { hello: 'world' });

     redis_client.subscribe('wangbin_test');

     redis_client.on('message',

       function(channel,message){

            socket.emit('news', message);

            console.log("channel:" + channel + ",msg:"+message);

        }

        );

 

 socket.on('my other event', function (data) {

   console.log(data);

 });

 

});

Index.html

<scriptsrc="/socket.io/socket.io.js"></script>

<script>

  varsocket = io.connect('http://10.54.37.212');

   socket.on('news', function (data) {

       

       alert(data);

               socket.emit('my other event', { my: 'data' });

                 });

</script>

Redis-cli发送消息:

Publishwangbin_test test

Server.js订阅监控收到消息后通过socket.io主动pushbrower

浏览器收到消息

Redis <wbr>pub/sub(Publish,Subscribe)

 

7、 Redis pub/sub压力测试

redis-benchmarkredis的读写性能工具

生成测试数据源:

for  in `seq 10000000` ;do echo  -ne  'publish   wangbin_test"'$i'"\r\n' >> publish.data;done;

 

          发布:

for i in $(seq 10);do (catpublish.data;sleep 100;)  |nc 10.54.37.212 6380 ;done;

 

订阅(模拟多个客户端同时订阅)

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_01.txt  &

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_02.txt  &

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_03.txt  &

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_04.txt  &

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_05.txt  &

(echo -ne 'subscribewangbin_test\r\n';sleep 10000)  | nc 10.54.37.212 6380 |grep  "\".*\""> subscribe_06.txt  &
    
性能监控测试

watch -d -n 1 'wc-l  subscribe_*.txt'

或者:

for i in $(seq 15); do wc -lsubscribe_*.txt > result_$i.txt ;sleep1;  done;

测试结果为:

每秒返回的数据为4-5w/s

8、 Redis pub/sub服务应用场景分析

其他PECL 扩展[SAM]Simple Asynchronous Messaging

9、 附件:

      i.            Redis-cli命令信息:

  -h<hostname>   域名或ip

  -p<port>       端口号(default:6379)

  -s<socket>     例如:/usr/local/bin/redis-cli  -s  /tmp/redis.sock

  -a<password>  密码

  -r<repeat>     重复次数

  -i<interval>       重复时间隔时间

  -n<db>        数据库个数

  -x             最后的标准输入

  -d<delimiter>    分隔符

  --raw          原始格式回复

  --latency       采集延迟模式

 

Redis <wbr>pub/sub(Publish,Subscribe)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值