目录
Redis pub/sub(Publish,Subscribe)
1、Pub/Sub功能
Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。
Publisher/subscribe 简易模型
2、 Pub/Sub机制
Pub/Sub功能(means Publish,Subscribe)即发布及订阅功能
1.
2.
3.
分类:
按照订阅方式分为基于主题(topic-based)、基于内容(content-based)、基于类型(type-based)的pub/sub方式。
总结:
Pub/Sub是可适用于可扩展要求高、松散耦合系统的分布式交互模型。
在抽象层中,它的时间非耦合、空间非耦合和同步非耦合性可允许参与者不依赖另一个而独立操作,具有一定的可扩展性;然而在实现层,可扩展性仍受其他原因的牵制。
例如:1、灵活的订阅要求复杂的过滤和路由算法;
4、庞大的订阅者数据带来的系统开销;
基于事件的Pub/Sub中间件的开发与利用在一定程度上可以提高系统的效率。
3、 Pub/Sub 在redis当中的实现
Redis-cli连接测试命令行参考附件I
协议测试命令
l
/usr/local/bin/redis-cli
redis-cli充当订阅者订阅(first 与second)两个topic
SUBSCRIBE firstsecond
l
/usr/local/bin/redis-cli
Pubish firstwangbin
Publish secondwangbin_second
l
l
Redis-cli对取消订阅有bug可以使用telnet 进行测试
取消订阅测试成功;
l
订阅者:
发布者:
publishnews.wangbin wangbin_patterncommand
l
在telnet下测试如下:
PSUBSCRIBE news.*
punsubscribe wangbin*
测试成功!
4、 Php-redis扩展测试
https://github.com/nicolasff/phpredispecl扩展包目前只提供了两个接口 publish
phpredis是c写的php模块
https://github.com/jamm/Memory/blob/master/RedisServer.php
php这个是php是基于redis protocol的fsocketopen链接后操作的类库,提供的接口比较全面;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){
定阅 redis_subscriber.php
SinaRedis::subscribe('wangbin_test');
发布redis_publisher.php
测试收到订阅者收到发布的内容
Php-redis扩展bug
段错误:
无论是connect 还是pcconnect 当超时断后,会报错segmentation fault;
超时设置bug
仍会断开解决方法:ini_set('default_socket_timeout', -1);// itworks fine
WebServer端测试
Web端订阅应用
Apache下ob_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
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
[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(): \
...
{'pattern': None, 'type': 'message','channel': 'wangbin_test', 'data': 'this is ainformation'}
收到json字符串
Publisher.py
Subscribe.py
6、 Redis pub/sub与node.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
安装: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
/usr/local/bin/npm
/usr/local/bin/npm
/usr/local/bin/npm
事件驱动用例:
Publish.js
var redis =require("redis");
try{
}
catch(e){
}
Subscribe.js
var redis =require("redis");
try{
}
catch(e){
}
测试结果:
另外还支持:pmessage, psubscribe, punsubscribe事件监听;
---------------------------------------------------------------------------------------------------------
Node.js
另外还支持:pmessage, psubscribe, punsubscribe事件监听;
Server.js
var app =require('http').createServer(handler)
var redis =require('redis');
var redis_client
app.listen(3000);
function handler (req, res){
}
io.sockets.on('connection', function (socket){
});
Index.html
<scriptsrc="/socket.io/socket.io.js"></script>
<script>
</script>
Redis-cli发送消息:
Publishwangbin_test test
Server.js订阅监控收到消息后通过socket.io主动push到brower
浏览器收到消息
7、 Redis pub/sub压力测试
redis-benchmark是redis的读写性能工具
生成测试数据源:
for
for i in $(seq 10);do (catpublish.data;sleep 100;)
订阅(模拟多个客户端同时订阅)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
(echo -ne 'subscribewangbin_test\r\n';sleep 10000)
watch -d -n 1 'wc-l
或者:
for i in $(seq 15); do wc -lsubscribe_*.txt > result_$i.txt ;sleep1;
测试结果为:
每秒返回的数据为4-5w/s
8、 Redis pub/sub服务应用场景分析
其他PECL 扩展[SAM]Simple Asynchronous Messaging
9、 附件: