Redis是单线程的工作模式
https://www.jianshu.com/p/xsMzfn
<-------------------
队头 L---------队尾 R,即left,right b即block阻塞
redis能做消息队列得益于他list对象blpop brpop接口以及Pub/Sub(发布/订阅)的某些接口。他们都是阻塞版的,所以可以用来做消息队列。
可以避免轮询操作,减轻CPU的消耗,你的数据库也可以用来做消息 队列,只不过目前的数据库还没有这样的接口。
另外做消息队列的其他特性例如FIFO也很容易实现,只需要一个List对象从头取数据,从尾部塞数据即可实现。
https://www.cnblogs.com/happyday56/p/4142761.html
rpop,lpop弹出的直接是value
brpop,blpop弹出的是List列表,第一个元素为key,第二个元素为value
当没有元素可以被弹出时返回一个 nil 的多批量值,并且 timeout 过期。
当有元素弹出时会返回一个双元素的多批量值,其中第一个元素是弹出元素的 key,第二个元素是 value。
https://blog.youkuaiyun.com/educast/article/details/48153813
https://blog.youkuaiyun.com/simonchi/article/details/51504563
http://blog.sina.com.cn/s/blog_5f54f0be0102uxgg.html
redis默认的数据库是0~15一共16个数据库
https://blog.youkuaiyun.com/kry1201/article/details/72629107
Redis基本概念
https://blog.youkuaiyun.com/Jae_Peng/article/details/81298802
使用xshell 连接redis插入的数据 等同于使用StringRedisTemplate操作redis
https://blog.youkuaiyun.com/AlbertFly/article/details/79499694
spring-boot-starter-data-redis 、jedis区别
https://www.cnblogs.com/superfj/p/9232482.html
https://www.cnblogs.com/austinspark-jessylu/p/8945586.html 对redisTemplate封装
https://www.cnblogs.com/haitao-xie/p/6323423.html 对redisTemplate封装
StringRedisTemplate使用的是StringRedisSerializer类;RedisTemplate使用的是JdkSerializationRedisSerializer类。反序列化,则是一个得到String,一个得到ObjectStringRedisTemplate
https://blog.youkuaiyun.com/Sky786905664/article/details/80671899?utm_source=copy
Redis 过期事件监听
https://github.com/zhouna/redisDemo.git
https://blog.youkuaiyun.com/familyshizhouna/article/details/74993032
使用redis的brpop方式做队列,经过一段时间,会发现程序莫名其妙的卡主。也就是进程一切ok,redis的lpush也正常,唯独brpop不再消费。该问题十分不好复现,但是总是过了一段时间就会重现。本人采用了高并发,高延迟,弱网络环境等方式试图复现都没有成功,目前仍然在寻找解决方案。
升级了 redis 3.2 版本之后,运行了一个多月,目前没有再出现卡住的问题。
https://www.jianshu.com/p/9c04890615ba
使用Redis中list的操作BLPOP(弹出头元素)或BRPOP(弹出尾元素),即列表的阻塞式(blocking)弹出
brpop:
1、当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
2、当给定多个key参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。
另外,BRPOP 除了弹出元素的位置和 BLPOP 不同之外,其他表现一致。
https://blog.youkuaiyun.com/doujinlong1/article/details/81746632
一、背景: 选择合适的使用场景
很多时候Redis被误解并乱用了,造成的Redis印象:耗内存、价格成本很高:
- 为了“赶时髦”或者对于Mysql的“误解”在一个并发量很低的系统使用Redis,将原来放在Mysql数据全部放在Redis中。
----(Redis比较适用于高并发系统,如果是一些复杂Mis系统,用Redis反而麻烦,因为单从功能讲Mysql要更为强大,而且Mysql的性能其实已经足够了。) - 觉得Redis就是个KV缓存
-----(Redis支持多数据结构,并且具有很多其他丰富的功能) - 喜欢做各种对比,比如Mysql, Hbase, Redis等等
-----(每种数据库都有自己的使用场景,比如Hbase吧,我们系统的个性化数据有1T,此时放在Redis根本就不合适,而是将一些热点数据放在Redis)
总之就是在合适的场景,选择合适的数据库产品。
http://carlosfu.iteye.com/blog/2254572
1.lpush
从左往右添加元素
在key 对应 list的头部添加字符串元素
2.rpush
从右到左添加元素
在key 对应 list 的尾部添加字符串元素
https://blog.youkuaiyun.com/u010098331/article/details/68490024
https://blog.youkuaiyun.com/kfengqingyangk/article/details/53442367
Redis工具类
https://blog.youkuaiyun.com/w690333243/article/details/82848314
Redis消息队列使用
push消息
jedis.rpush(REQEST, JSONObject.toJSONString("requestmessage"));将消息放到消息队列队尾
public static void redisMessageQueue() {
Jedis jedis = JedisUtil.getInstance().getJedis();
new Thread(new RedisRunnable(jedis)).start();
}
RedisRunnable.java
public class RedisRunnable implements Runnable {
private Jedis jedis;
private boolean exit = false;
RedisRunnable(Jedis jedis) {
this.jedis = jedis;
}
public boolean isExit() {
return exit;
}
public void setExit(boolean exit) {
this.exit = exit;
}
private static final Logger log = Logger.getLogger(RedisRunnable.class.getName());
private static final String REQUEST = "request";
private static final String RESPONSE = "response";
private static String redisMsgType[] = new String[] { REQUEST };
@Override
public void run() {
// TODO Auto-generated method stub
while (!exit) {
if (jedis == null) {
log.log(Level.WARNING, "jedis is null");
return;
}
List<String> msgList = jedis.blpop(0, redisMsgType);//从消息队列队头取消息,如果没有,则当前线程会阻塞在这
if (msgList == null || msgList.size() < 2) {
return;
}
String key = msgList.get(0);
String value = msgList.get(1);
if (key != null && key.trim().length() > 0 && value != null && value.trim().length() > 0) {
switch (key) {
case REQUEST:
String request = JSON.parseObject(value, new TypeReference<String>() {
});
jedis.rpush(RESPONSE, JSONObject.toJSONString("success"));
break;
}
}
}
}
}
Redis订阅发布
public static void subScribe() {
Jedis jedis = JedisUtil.getInstance().getJedis();
SubscribeClient client = new SubscribeClient();
System.out.println("54------阻塞了吗---------");
//可以订阅多个频道 当前线程会阻塞在这儿
client.unsubscribe();
jedis.subscribe(client, "test");
System.out.println("49------阻塞了吗---------");
}
public static void publish() {
Jedis jedis = JedisUtil.getInstance().getJedis();
JSONObject jsonObject = new JSONObject();
String pubStr = JSON.toJSONString("啊啊啊");
jedis.publish("test", pubStr);
}
SubscribeClient.java
public class SubscribeClient extends JedisPubSub {
private String TAG = "CustomJedisPubSub";
@Override
public void subscribe(String... channels) {
// TODO Auto-generated method stub
if(channels == null || channels.length <= 0) {
return;
}
System.out.println("订阅了频道:" + channels);
}
/**
* JedisPubSub类是一个没有抽象方法的抽象类,里面方法都是一些空实现
* 所以可以选择需要的方法覆盖,这儿使用的是SUBSCRIBE指令,所以覆盖了onMessage
* 如果使用PSUBSCRIBE指令,则覆盖onPMessage方法
* 当然也可以选择BinaryJedisPubSub,同样是抽象类,但方法参数为byte[]
*/
@Override
public void onMessage(String channel, String message) {
// TODO Auto-generated method stub
if("xxxx".equals(channel)) {
System.out.println("接收到消息: channel : " + message);
//接收到消息后退出
if("xxxx".equals(message)) {
}
}
}
@Override
public void onPMessage(String pattern, String channel, String message) {
// TODO Auto-generated method stub
super.onPMessage(pattern,channel, message);
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
if(channel == null) {
return;
}
System.out.println("订阅了频道:" + channel);
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
// TODO Auto-generated method stub
super.onUnsubscribe(channel, subscribedChannels);
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
super.onPUnsubscribe(pattern, subscribedChannels);
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
// TODO Auto-generated method stub
super.onPSubscribe(pattern, subscribedChannels);
}
@Override
public void unsubscribe() {
// TODO Auto-generated method stub
super.unsubscribe();
}
@Override
public void unsubscribe(String... channels) {
// TODO Auto-generated method stub
super.unsubscribe(channels);
}
@Override
public void psubscribe(String... patterns) {
// TODO Auto-generated method stub
super.psubscribe(patterns);
}
@Override
public void punsubscribe() {
// TODO Auto-generated method stub
super.punsubscribe();
}
@Override
public void punsubscribe(String... patterns) {
// TODO Auto-generated method stub
super.punsubscribe(patterns);
}
@Override
public boolean isSubscribed() {
// TODO Auto-generated method stub
return super.isSubscribed();
}
@Override
public int getSubscribedChannels() {
// TODO Auto-generated method stub
return super.getSubscribedChannels();
}
}
https://blog.youkuaiyun.com/huahuagongzi99999/article/details/13659849 redis 强大的工具类
https://blog.youkuaiyun.com/cctcc/article/details/50515548?locationNum=8&fps=1
https://blog.youkuaiyun.com/liuxiao723846/article/details/50401406
https://blog.youkuaiyun.com/pengyu432/article/details/73467118
https://blog.youkuaiyun.com/qq_35573689/article/details/79045185
https://blog.youkuaiyun.com/qq_26525215/article/details/72510794
2个命令都是属于无序集合的范畴,并不是有序集合zset等,顾知晓!
redis订阅发布
https://blog.youkuaiyun.com/qq_34212276/article/details/78455004
https://blog.youkuaiyun.com/jslcylcy/article/details/78201812
https://blog.youkuaiyun.com/liyongbing1122/article/details/80888790
https://blog.youkuaiyun.com/eguid_1/article/details/52600755
https://blog.youkuaiyun.com/Seven__________7/article/details/70225830
https://blog.youkuaiyun.com/songfeihu0810232/article/details/78648706
https://blog.youkuaiyun.com/JaCman/article/details/51246449
https://blog.youkuaiyun.com/chou_out_man/article/details/79666306
https://blog.youkuaiyun.com/stationxp/article/details/45731413
https://blog.youkuaiyun.com/hjm4702192/article/details/80518856
https://blog.youkuaiyun.com/qq_37610423/article/details/72660063
https://blog.youkuaiyun.com/qq_34212276/article/details/78455004
https://segmentfault.com/a/1190000012244418
redis与mysql同步
https://blog.youkuaiyun.com/socho/article/details/52292064
https://blog.youkuaiyun.com/xundh/article/details/46288547
https://blog.youkuaiyun.com/tb3039450/article/details/53928351
https://blog.youkuaiyun.com/chenleixing/article/details/50530419 Redis上踩过的一些坑-美团
https://www.cnblogs.com/jhoney/p/4492324.html redis队列及多线程应用
https://blog.youkuaiyun.com/w690333243/article/details/82848314
springboot集成redis
https://blog.youkuaiyun.com/a67474506/article/details/52595053
https://blog.youkuaiyun.com/qincidong/article/details/76687164
https://blog.youkuaiyun.com/plei_yue/article/details/79362372
https://blog.youkuaiyun.com/qq_31001665/article/details/74080154
https://blog.youkuaiyun.com/abombhz/article/details/78123253
https://blog.youkuaiyun.com/i_vic/article/details/53081241
https://blog.youkuaiyun.com/soda_lw/article/details/78981112