Redis学习

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印象:耗内存、价格成本很高:

  1. 为了“赶时髦”或者对于Mysql的“误解”在一个并发量很低的系统使用Redis,将原来放在Mysql数据全部放在Redis中。
    ----(Redis比较适用于高并发系统,如果是一些复杂Mis系统,用Redis反而麻烦,因为单从功能讲Mysql要更为强大,而且Mysql的性能其实已经足够了。)
  2. 觉得Redis就是个KV缓存
    -----(Redis支持多数据结构,并且具有很多其他丰富的功能)
  3. 喜欢做各种对比,比如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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值