1、springboot整合redis
Jedis的作用
Jedis是基于Java语言的Redis的客户端,Jedis = Java + Redis。Redis不仅可以使用命令来操作,现在基本上主流的语言都有API支持,比如Java、C#、C++、PHP、Node.js、Go等。在官方网站里有一些Java的客户端:Jedis、Redisson、Jredis、JDBC-Redis等,其中官方推荐使用Jedis和Redisson。简言之Jedis是Redis的Java版本API,通过使用Jedis可以操作Redis中的数据。
jedis连接资源的创建与销毁是很消耗程序性能,所以jedis为我们提供了jedis的连接池技术,jedis
连接池在创建时初始化一些连接对象存储到连接池中,使用jedis连接资源时不需要自己创建jedis对象,而是从连接池中获取一个资源进行redis的操作。使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用。
pom坐标的引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
yml文件的配置:
spring:
redis: ##单机部署的话 需要使用下面的配置
host: localhost
password: 123456
timeout: 6000
port: 6379
jedis:
pool:
max-active: 8 # 最大连接
max-idle: 8 # 最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: 100ms # 连接等待时间
config配置类bean的配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 创建模板
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer =
new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
2、将热数据进行设置到缓存中
要将热数据设置到缓存中,可以按照以下步骤操作:
1. 选择一个适合的缓存系统:选择一个适合你的需求的缓存系统,常见的缓存系统有Redis、Memcached等。
2. 安装和配置缓存系统:按照缓存系统的官方文档,下载、安装和配置缓存系统。确保缓存系统能正常运行。
3. 编写代码连接缓存系统:使用编程语言连接到缓存系统,并确保能够正确地与缓存系统进行通信。
4. 设计缓存策略:根据热数据的特点和业务需求,设计一个适合的缓存策略。可以考虑使用LRU(最近最少使用)或LFU(最近最不常用)等缓存淘汰算法。
5. 将热数据设置到缓存中:根据缓存策略,将热数据设置到缓存中。可以通过缓存系统提供的API,将数据存储到缓存中。
6. 读取缓存中的数据:在需要读取热数据的地方,先尝试从缓存中读取数据。如果缓存中存在数据,则直接使用缓存中的数据。如果缓存中不存在数据,则从数据库或其他持久化存储中读取数据,并将数据存储到缓存中,以便下次使用。
7. 更新缓存中的数据:当热数据发生变化时,及时更新缓存中的数据。可以通过缓存系统提供的API,更新缓存中的数据。
通过以上步骤,你可以将热数据设置到缓存中,提高系统的读取性能和响应速度。
3、缓存击穿和雪崩问题的处理
缓存击穿是指在某个时间点,缓存中的某个数据过期了,同时又有大量的并发请求过来访问该数据,导致请求都落到了数据库上,造成数据库压力过大,甚至宕机的情况。
雪崩问题是指在某个时间点,缓存中的大部分数据同时过期,而且此时又有大量的并发请求过来访问这些数据,导致所有请求都落到了数据库上,造成数据库压力过大,甚至宕机的情况。
针对缓存击穿和雪崩问题,可以采取以下一些处理方式:
1. 设置合理的缓存过期时间:避免缓存过期时间集中在一个时间点,导致缓存大规模同时失效。
2. 使用互斥锁(mutex)或分布式锁:在缓存失效的时候,通过加锁的方式,只允许一个线程去访问数据源,而其他线程需要等待,避免了大量的并发请求落到数据库上。
3. 提前进行缓存预热:在缓存即将过期之前,提前主动刷新缓存,避免缓存失效期间的并发请求落到数据库上。
4. 使用熔断机制:在缓存失效期间,如果数据库压力过大,可以暂时屏蔽该服务,避免影响到其他服务。
5. 数据库优化:通过优化数据库性能,提高数据库的并发处理能力,减少数据库宕机的风险。
6. 限流降级:对并发请求进行限流,避免大量请求同时访问数据库,可以使用限流工具、负载均衡等方式。
总的来说,处理缓存击穿和雪崩问题需要综合考虑缓存设置、锁机制、缓存预热、熔断机制、数据库优化等多个方面的因素,根据具体情况采取适当的措施。
4、将一些重要的数据进行持久化
持久化数据是指将数据保存在存储介质上,以便在程序终止后仍然能够保留数据。以下是一些常见的持久化数据的方法:
1. 文件存储:将数据以文件的形式保存在磁盘上。可以使用文本文件、二进制文件或者特定格式的文件(如JSON、XML等),根据需求选择合适的文件格式。读写文件可以使用文件操作的API,如打开、写入和读取文件的操作。
2. 数据库存储:将数据保存在关系型数据库(如MySQL、Oracle等)或非关系型数据库(如MongoDB、Redis等)中。使用数据库可以更方便地对数据进行增删改查的操作,并且支持复杂的查询功能。
3. 缓存存储:将数据保存在缓存中,以加快访问速度。常见的缓存存储方式有内存缓存(如Redis)和分布式缓存(如Memcached)。
4. 对象持久化:将对象保存在持久化存储中,以保留对象的状态。可以使用对象持久化框架(如Hibernate)将对象映射到数据库中,并提供相应的操作方法。
5. 日志存储:将重要的数据写入日志文件中,以便后续分析和查看。可以使用日志框架(如Log4j)将日志信息输出到文件或者其他目标(如控制台、数据库等)。
需要根据具体需求和项目特点选择合适的持久化方案,并根据数据的重要程度和访问频率来确定持久化的策略。
5、数据一致性问题
数据一致性问题是指在分布式系统中,由于多个节点间的异步通信、并发操作等原因导致数据在不同节点间的不一致现象。
在分布式系统中,由于网络延迟、通信故障等原因,不同节点上的数据可能会有一定的延迟或不一致。例如,在一个分布式数据库系统中,当一个客户端在一个节点上执行了一个写操作,并且马上又执行了一个读操作,由于数据复制的延迟,读操作可能会读取到旧的数据,导致数据不一致。
数据一致性问题还会出现在并发写操作的情况下。当多个客户端同时对同一份数据进行写操作时,如果不加控制,可能会导致数据的覆盖或冲突,进而引发数据一致性问题。
为了解决数据一致性问题,可以采取以下几种措施:
1. 引入分布式事务:通过分布式事务管理器来保证多个节点上的操作的一致性,确保数据的正确更新。
2. 使用乐观锁和悲观锁:乐观锁使用版本号或时间戳来解决并发写操作的冲突问题,悲观锁通过加锁的方式来保证数据的一致性。
3. 使用分布式缓存:通过将数据缓存在分布式缓存中,可以降低对数据库的读写操作,并减少数据不一致的可能性。
4. 引入副本机制:将数据复制到多个节点上,通过复制机制来确保数据的一致性。
5. 采用一致性哈希算法:通过一致性哈希算法来分布数据到多个节点上,避免节点的增减对数据一致性产生影响。
总之,数据一致性问题是分布式系统设计中需要解决的重要问题,需要通过合适的技术手段来保证数据的一致性。