《Spring Boot框架入门到实践》(10)集成使用Redis

认识Redis

这里引用百度的一段话:
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括String(字符串)、List(链表)、Set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
详细使用
MySQL和Redis的区别
安装Redis 启动REdis也可直接在安装目录中启动点击redis-server.exe
Redis图形化客户端下载

集成Redis步骤

  1. 在pom.xml中添加jar包依赖
<!-- redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 在Spring boot配置文件application.properties中配置redis连接信息,这些只不过是最基础的,另外的配置信息查看上方的【详细使用】。
spring.redis.host=#主机名(默认:)
spring.redis.port=#端口号(默认:6379)
spring.redis.password=#密码

这三部分全部信息可以在Redis图形化客户端显示。
3. 配置了上面的步骤,Spring boot将自动配置Redis Template,在需要操作Redis的类中注入RedisTemplate。
在使用的类中注入:

	@Autowired
	/** 注入Spring boot自动配置号的RedisTemplate **/
	private RedisTemplate<Object, Object> redisTemplate;

	@Autowired
	/** 注入Spring boot自动配置号的RedisTemplate **/
	private RedisTemplate<String, String> redisTemplate;

spring boot帮我们注入的redisTemplate类,泛型里面只能写<String,String>或<Object, Object>
4. 注入后,有了RedisTemplate后就可以操作数据库了,这里选择一个查询数据库的方法。

	@Override
	public List<User> selectAll() {
		// 先在Redis缓存中查询缓存
		List<User> Userlist = (List<User>) redisTemplate.opsForValue().get("alluser");
		//判断缓存里是否有数据,没有数据就把数据库查询出来的数据放入Redis
		if (null == Userlist) {
			// 缓存为空查询一遍数据库
			Userlist = mapper.selectAll();
			// 把数据库查询出来的数据放入Redis
			redisTemplate.opsForValue().set("alluser", Userlist);
		}
		return Userlist;
	}
  1. 注意实体类必须实现序列化接口,否则在存储数据时会抛出如下异常:class invalid for deserialization
    Serializable
    在这里插入图片描述
  2. 查看Redis Desktop我们已经把MySQL数据库中的数据存储到了Redis缓存中。
    在这里插入图片描述
    因为我们存储的是二进制文件,所以看起来好像是乱码一样。
  3. 把key的序列化方式改一下,让它看起来可读性更好一些。
    在方法的头部中添加序列化器转化Key。
		// 字符串序列化器
		RedisSerializer redisSerializer = new StringRedisSerializer();
		// 在RedisTemplate操作数据之前就设置Key为String
		redisTemplate.setKeySerializer(redisSerializer);

将Redis缓存删除后重新运行,可以看到key已经变成了字符串形式的了。
在这里插入图片描述

高并发条件下缓存穿透问题处理

什么是高并发

这里引用百度百科的一段话:
由于分布式系统的问世,高并发(High Concurrency)通常是指通过设计保证系统能够同时并行处理很多请求。通俗来讲,高并发是指在同一个时间点,有很多用户同时的访问同一 API 接口或者 Url 地址。它经常会发生在有大活跃用户量,用户高聚集的业务场景中。简单点就是在同一时刻不同用户访问同一资源的问题。

什么是缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是空时需要从数据库查询。查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决方法

  1. 我们先来看看方法执行的步骤
    在这里插入图片描述

  2. 这个方法本身是没有问题的,但是如果是一万个人同时访问这个数据库也就是同时执行第五步的话就会产生缓存穿透,因为数据库的效率本身就没有Redis强,如果还有一万个人同时访问数据库的话就会使数据库异常,影响其他用户的使用。

  3. 解决就是设置一个拦截器,让一个人进入数据库查询数据,其他的九千九百九九都是直接查询缓存然后直接返回数据。
    3.1. 最简单的方法就是在方法上加一把锁,synchronized锁
    在这里插入图片描述
    Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码。
    这个方法随可以解决但是效率低一些。
    因为,Synchronized是一把锁,他会把同一时间进入方法的用户挡在外面,一次只给一个人钥匙让他们进去,所以这样效率会低一些。

    3.2. 所以我们用第二种方法,就是将Synchronized细化一下,让他不在方法上拦截,而是让用户进入方法后,让第一个用户进入数据库查询数据,后面的用户等第一个用户查询完后再进入,后面的用户就不用进入数据库查询数据库了,因为第一个用户已经帮他们查询好了数据,所以效率会稍微好一些。
    步骤:
    在原来的基础上添加双重检测锁
    在这里插入图片描述

哨兵模式(Sentinel)

什么是哨兵模式
spring boot集成哨兵模式

发布了50 篇原创文章 · 获赞 13 · 访问量 1878

猜你喜欢

转载自blog.csdn.net/qq_43581078/article/details/103516665