分布式缓存技术Redis(二)应用实战

一、集成springboot

Spring Data Redis官方网站:https://docs.spring.io/spring-data/redis/docs/2.2.4.RELEASE/reference/html/#

1.maven依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.application.properties配置
# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 链接超时时间 单位 ms(毫秒)
spring.redis.timeout=3000
################ Redis 线程池设置 ##############
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接 默认 8
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.jedis.pool.min-idle=0
3.使用redisTemplate

RedisTemplate API:https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html

@RestController
public class TestController {
	
	@Autowired
	RedisTemplate redisTemplate;

	@GetMapping("testRedis")
	public Object testRedis(){
		redisTemplate.opsForValue().set("aaa","123");
		Object result = redisTemplate.opsForValue().get("aaa");
		return result;
	}
}

二、redis客户端介绍

Redis java客户端常见的开源项目有Redission、Jedis、Lettuce。

Jedis
Jedis是一个轻量级的redis客户端,其API提供了非常全面的redis命令支持。
官方文档:https://github.com/xetorthio/jedis

Redisson
Redisson实现了分布式和可扩展的java数据结构,和Jedis相比,功能比较简单,不支持字符串操作,不支持排序、事务、管道、分区等redis特性。Redssion主要促进使用者对redis的关注分离,从而让使用者能够将更多精力集中力处理业务逻辑上。
官方文档:https://github.com/redisson/redisson

Lettuce
Lettuce是基于Netty构建的一个可伸缩的线程安全的redis客户端,支持同步、异步、响应式模式。多个线程共享一个连接实例,而不必担心多线程并发问题。并且Lettuce是springboot2.0后默认支持的redis客户端。
官方文档:https://lettuce.io/

三、解决方案

缓存雪崩

缓存雪崩是指设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,或者缓存服务器宕机导致缓存全面失效,请求全部转发到了数据库层面,数据库由于瞬间压力增大而导致崩溃。大量数据时缓存失效导致的雪崩对底层数据库会造成较大的冲击。

解决方式:

  1. 如果发现从缓存中取不到值,那么通过加锁或者队列的方式保证缓存的单进程操作,从而避免失效时并发请求全部落到底层的存储系统上,但这种方式同时会带来性能上的损耗。
  2. 将缓存的失效时间分散,降低每一个缓存过期的重复率。
  3. 如果因为缓存服务器导致的问题,一方面需要保证服务器的高可用、另一方面,应用程序中可以采用多级缓存。
缓存穿透

缓存穿透是指查询一个根本不存在的数据,缓存和数据库都不会命中数据。出于容错的考虑,如果从数据库层面查询不到数据则bu不写入缓存,即数据库返回值为null时,不缓存null。缓存穿透问题可能会使后端数据库负载加大,由于很多数据库不具备高并发性,大量缓存穿透甚至可能造成数据库宕机。

解决方式:

  1. 如果查询数据库也为null时,直接设置一个默认值缓存在redis,这样第二次到缓存中获取就有值了,从而不会继续访问到数据库就直接返回。比如:默认值为"key"、"&&"等。在返回默认值时我们的应用可以认为这是一个不存在的key,那么我们的应用就可以决定是否继续等待后访问,还是放弃这次访问。如果过了一个时间轮询点后再次请求这个key还是只取到的不是默认值,就认为这个key有值了。这样就把大量的无效访问挡在了数据库之前。
  2. 根据缓存数据key的设计规则,将不符合规则的key进行过滤,采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的BigSet中,不存在的数据将会被拦截掉,从而避免了对底层数据库造成压力。
布隆过滤器

布隆过滤器是Burton Howard Bloom在1970年提出来的,一种空间效率极高的概率型算法和数据结构,主要用来判断一个元素是否在集合中存在。因为他是一个概率型的算法,所以会存在一定的误差,如果传入一个值去布隆过滤器中检索,可能会出现检测存在的结果但是实际上可能是不存在的,但是肯定不会出现实际上不存在然后反馈存在的结果。因此,Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极大节省。

bitmap

所谓的Bit-map就是用一个bit位来标记某个元素对应的value,通过bit为单位来存储数据,可以大大节省存储空间。所以我们可以通过一个int型的整数的32bit位的来存储32个10进制数字,那么这样所带来的好处是内存占用极少、效率高,比如我们要存储5(二进制:101)、3(二进制:11)两个数字,那么我们申请int型的内存空间会有32个比特位。这两个数字分别对应从右往坐开始数,比如第一个数字是5对应的二进制是101,那么从右往左数到第5位,把对应的二进制数据存储到32个比特位上。
第一个5就是-> 00000000000000000000000000101000
输入3时候----> 00000000000000000000000000001100

布隆过滤器原理

假设集合里面有两个元素{x, y},分别把这两个元素调用3个指定的不同哈希函数。首先将位数组进行初始化,将里面每个位都设置位0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询Z元素是否存在集合中的时候,同样的方法将Z元素通过3个指定的不同哈希函数映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。

实际业务中按照该方法处理所有的输入对象(哈希函数不一定是3个,哈希函数越多,映射冲突会越少但同时判断查询的性能也降低。),每个对象都可能把bitmap中一些白位置涂黑,也可能会遇到已经涂黑的位置,遇到已经为黑的让他继续为黑即可。处理完所有的输入对象之后,在bitMap中可能已经有相当多的位置已经被涂黑。至此,一个布隆过滤器生成完成,这个布隆过滤器代表之前所有输入对象组成的集合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值