redis相关内容介绍
top:这里忽略了redis基本数据结构的介绍,不熟悉的小伙伴可参考
教程
- redis:具有k-v特性的服务器,主要用于缓存。
- pipline:用于提高redis通信效率的管道技术。每执行一条命令便会与redis服务器进行一次通信,对redis的频繁操作,显然会增大服务器的通信压力。使用pipline将频繁的redis操作命令封装到管道中,待操作高峰过去后,一次性与redis进行通信,从而提高通信效率,降低服务器压力。
- publish、subscribe机制:作为缓存服务器的一种,数据的更新操作很重要。如何实现多用户之间数据的共享?redis采用发布/订阅机制来实现。简单的说,P(publiser)先生要发布信息,他会在某个频道channelx发布一条自己待发布的信息message:“I am P 先生”。这时,如果某个订阅者S(subscriber)订阅了这个频道channelx,他就会收到P先生发布的消息message。这就是简单的发布/订阅机制的原理。当然,发布者与订阅者之间是多对多的关系。一个发布者可以有多个订阅者,同时一个订阅者可以订阅多个发布者的频道。
模拟redis本地实现SubPub
情景介绍:
- 本机redis服务器:127.0.0.1 port:6379
- jedis实现发布者将数据插入redis,使用循环插入,利用pipline提高通信效率
- 本机客户端模拟一个订阅者A
- jedis实现一个订阅者B,监听订阅信息
测试数据集:
{“范冰冰”:”范爷”,”云南”:[“过桥米线”,”大理古城”,”普洱茶”],”UK”:[“king”:”威廉”,”queen”:”伊丽莎白”]}
实现
本地打开redis服务器
redis-server.exe
重开一个cmd,使用客户端建立一个到redis的连接
redis-cli.exe -h 127.0.0.1 -p 6379 -a 123456
模拟订阅者的客户端随即订阅一个
Mari
频道SUBSCRIBE "Mari"
,用于监听redis信道发布信息
订阅者线程启动,进行监听
public class JedisPubAndSub {
public static String channel = "Mari";
public static void main(String[] args) {
//使用redis pool获取jedis对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
JedisPool pool = new JedisPool(jedisPoolConfig,"localhost",6379,123456);
Jedis subscriber = pool.getResource();
//订阅者订阅信息
PubAndSub pubAndSub = new PubAndSub();
pubAndSub.proceed(subscriber.getClient(), channel);
System.out.println("客户:" + subscriber.getClient().toString() + "订阅了频道:" + channel);
}
}
- 发布者准备数据,进行发布
public class JedisPublish {
public static TreeMap<String,String> initData;
public static String channel = "Mari";
public static String key = "common";
static {
initData = new TreeMap<String,String>();
initData.put("范冰冰", "范爷");
initData.put("云南", "过桥米线");
initData.put("威廉", "伊丽沙白");
}
public static void main(String[] args) {
//使用redis pool获取jedis对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
JedisPool pool = new JedisPool(jedisPoolConfig,"localhost",6379,123456);
Publisher publisher = new Publisher(pool.getResource());
//发布者发布信息
String message = publisher.write2Redis(key, initData);
System.out.println("信息:" + message + "已经写入到redis...");
publisher.publish(channel,message);
System.out.println("发布者在频道:" + channel + "发布了信息:" + message);
}
}
客户端的订阅者这是就会监听或者接受到订阅的”Mari”频道的信息
订阅者监听到的信息
原码
/**
* jedis模拟实现发布订阅机制
* 订阅者
* @author CaptWang
*
*/
class PubAndSub extends JedisPubSub{
@Override
public void onMessage(String channel, String message) {
// TODO Auto-generated method stub
System.out.println("onMessage: channel:" + channel + "-- message:" + message);
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
System.out.println("onMessage: pattern:" + pattern + "subscribedChannels:" + subscribedChannels);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
System.out.println("onMessage: channel:" + channel + "subscribedChannels:" + subscribedChannels);
}
}
public class JedisPubAndSub {
public static String channel = "Mari";
public static void main(String[] args) {
//使用redis pool获取jedis对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
JedisPool pool = new JedisPool(jedisPoolConfig,"localhost",6379,123456);
Jedis subscriber = pool.getResource();
//订阅者订阅信息
PubAndSub pubAndSub = new PubAndSub();
pubAndSub.proceed(subscriber.getClient(), channel);
System.out.println("客户:" + subscriber.getClient().toString() + "订阅了频道:" + channel);
}
}
/**
* jedis模拟实现发布订阅机制
* 发布者
* @author CaptWang
*
*/
//publisher
class Publisher{
public Jedis publisher;
public static String message;
public Publisher(Jedis jedis){
this.publisher = jedis;
}
//向redis插入数据
public String write2Redis(String key,TreeMap<String,String> dataMap){
if(dataMap != null){
//开启pipeline
Pipeline pipline = publisher.pipelined();
Iterator<Map.Entry<String,String>> it = dataMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String, String> entry = it.next();
//待插入的数据
String temp = entry.getKey() + "-" + entry.getValue();
pipline.lpush(key, temp);
System.out.println(key + temp);
message = message + temp + " ";
}
pipline.sync();
}
return message;
}
//发布者将消息发布出去
public void publish(String channel,String message){
if(message != null){
publisher.publish(channel, message);
}
}
}
public class JedisPublish {
public static TreeMap<String,String> initData;
public static String channel = "Mari";
public static String key = "common";
static {
initData = new TreeMap<String,String>();
initData.put("范冰冰", "范爷");
initData.put("云南", "过桥米线");
initData.put("威廉", "伊丽沙白");
}
public static void main(String[] args) {
//使用redis pool获取jedis对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
JedisPool pool = new JedisPool(jedisPoolConfig,"localhost",6379,123456);
Publisher publisher = new Publisher(pool.getResource());
//发布者发布信息
String message = publisher.write2Redis(key, initData);
System.out.println("信息:" + message + "已经写入到redis...");
publisher.publish(channel,message);
System.out.println("发布者在频道:" + channel + "发布了信息:" + message);
}
}