最近使用redis遇到一些问题,记录一下。
格式就不排了,有时间再弄吧。
一、版本信息
spring 4.2.5
mysql 5.1.18
mybatis 3.2.8
mybatis-spring 1.2.4
jedis 2.8.0
spring-data 1.7.1
... ...
二、jedis和spring集成
1. 配置数据源
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!--对拿到的connection进行validateObject校验 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<!--在进行returnObject对返回的connection进行validateObject校验 -->
<property name="testOnReturn" value="${redis.testOnReturn}" />
<!--定时对线程池中空闲的链接进行validateObject校验 -->
<property name="testWhileIdle" value="${redis.testWhileIdle}" />
</bean>
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.database}" />
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<bean id="redis4CacheConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.cache.database}" />
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
2.配置Template
<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redisConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
<property name="hashKeySerializer" ref="stringRedisSerializer" />
<!-- 默认即为 jdkRedisSerializer -->
<!-- <property name="valueSerializer" ref="jdkRedisSerializer" />
<property name="hashValueSerializer" ref="jdkRedisSerializer" /> -->
<!-- <property name="enableTransactionSupport" value="true" /> -->
</bean>
注:在spring事务中不执行Lua脚本可使用enableTransactionSupport,否则报java.lang.unsupportedclassversion
三、与springCache集成
<bean id="redis4CacheTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="redis4CacheConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
</bean>
<!-- 开启缓存注解 -->
<cache:annotation-driven/>
<!-- declare Redis Cache Manager -->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redis4CacheTemplate" />
<!-- 是否事务提交,如果事务回滚,缓存也回滚,默认false -->
<property name="transactionAware" value="true" />
<!-- 默认有效期1d 3600*24 -->
<property name="defaultExpiration" value="86400" />
</bean>
public abstract class BaseCache {
public String generateKey(String... args) {
return RedisUtil.generateKey(args);
}
@CacheEvict(allEntries = true)
public abstract void clearCaches(Class<?> clazz);
}
@Component(ActivityCache.SERVICE_NAME)
@CacheConfig(cacheNames = {ActivityCache.SERVICE_NAME})
public class ActivityCache extends BaseCache {
/**
* SERVICE_NAME:服务名
*/
public static final String SERVICE_NAME = "activityCache";
@Autowired
private ActivityDao activityDao;
@Cacheable(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
unless="#result == null")
public Activity getActivityInfo(String activityCode){
Activity activity = null;
try {
} catch (Exception e) {
log.error(e.getMessage(),e);
}
return activity;
}
@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activity.activityCode)",
unless="#result == null")
public Activity saveOrUpdateActivityInfo(Activity activity)
@CachePut(key="#root.target.generateKey(#root.targetClass.getSimpleName(), #activityCode)",
unless="#result == null")
public int delActivity(String activityCode)
@CacheEvict(allEntries = true)
public void clearCaches(Class<?> clazz)
}
四、关于取值异常问题
Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring.xml"
// ,
// "classpath:spring/spring-mvc.xml",
// "file:src/main/java/com/sinowel/eacpc/**/mapping/*.xml"
})
public class TestBase {
@Before
public void setUp() throws Exception {
}
}
public class TestLua2 extends TestBase {
private final Logger logger = LoggerFactory.getLogger(TestLua2.class);
@Resource(name = RedisService.SERVICE_NAME)
private RedisService redisService; // redis
@Resource(name = "redisTemplate")
private RedisTemplate<String, Object> redisTemplate; // redis
@Test
public void testInject() throws Exception {
// 在服务器redis-cli连接预存入Hash key=tt1 field=t1,t2的数值
String redisKey = "tt1";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
List<Long> list = redisService.getMultiHash(redisKey, fieldList, null);
System.out.println(list.get(0).longValue());
// 存入时使用stringRedisSerializer,取值时使用jdkRedisSerializer。xml RedisTemplate时配置
// 异常,先存,再次取,配置文件切换配置
String redisKey = "tt2";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
redisService.setHash(redisKey, "t1", "1");
redisService.setHash(redisKey, "t2", "2");
BoundHashOperations<String, String, Long> bhOps = redisTemplate
.boundHashOps(redisKey);
List<Long> list = bhOps.multiGet(fieldList);
System.out.println(list.get(0));
// keySerializer 和 hashKeySerializer 设置 stringRedisSerializer
// valueSerializer 和 hashValueSerializer 设置成默认 jdkRedisSerializer
// 则可以取得指定值,否则都使用stringRedisSerializer,取到的值一定是String类型
String redisKey = "tt3";
List<String> fieldList = Arrays.asList(new String[] {"t1", "t2"});
BoundHashOperations<String, String, Long> bhOps = redisTemplate
.boundHashOps(redisKey);
bhOps.put("t1", 1L);
bhOps.put("t2", 2L);
List<Long> list = bhOps.multiGet(fieldList);
System.out.println(list.get(0));
}
}
redis-cli取到序列化后的值【1】
stringRedisSerializer:
"\xac\xed\x00\x05t\x00\x011"
jdkRedisSerializer:
"\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x00\x01"
总结:各个RedisSerializer序列化的值存入redis后,取值时,是不能切换取值的。因为序列化方式不同。
分享到:
相关推荐
你可以在遇到任何关于Spring MVC和Redis集成的问题时,与其他开发者交流解决方案。 总结起来,这个项目是一个实践性强、易于学习的教程,涵盖了Spring MVC和Redis集成的各个方面,从配置到实际应用,再到测试验证,...
总之,Java Spring集成Redis涉及的库包主要包括Spring Data Redis、Jedis或Lettuce客户端,以及相应的配置和操作API。在集成过程中,要注意依赖管理,确保所有库包版本兼容,以避免出现不兼容问题。通过正确配置和...
Spring Boot提供了多种集成Session的解决方案,其中一种就是使用Redis作为Session的存储介质。Redis是一个高性能的键值数据库,支持丰富的数据结构,如字符串、哈希、列表、集合等,非常适合用来存储Session。 要...
在应用中使用Spring Data Redis,你可以声明一个`@Autowired`的`RedisTemplate`实例,然后调用它的方法来存取数据。例如,使用`opsForValue()`方法可以操作字符串类型的键值对: ```java @Autowired private ...
总结来说,这个压缩包文件的内容将涵盖Spring Boot项目中集成Redis的基本步骤,包括设置单机和集群模式,以及如何在应用中使用Redis进行数据缓存。对于初学者,这将是一个很好的实践指南,而对于有经验的开发者,也...
在使用Spring Redis时,可能会遇到网络问题、数据序列化错误等异常,应合理捕获并处理这些异常,确保程序的健壮性。 八、最佳实践 1. 合理设置缓存过期时间,避免数据过期后仍被使用。 2. 使用合适的序列化方式,如...
Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份认证、授权、会话管理和...在实际应用中,你可能还需要结合其他技术,如 Spring Boot 或者 Dubbo,来更好地整合 Shiro 和 Redis,实现完整的安全和缓存管理。
综上,本资源包提供了一站式的Redis学习资料,从基础的安装配置到高级的Spring集成,覆盖了开发中可能遇到的各种场景。通过深入学习和实践,开发者可以熟练掌握Redis的使用,提升应用的性能和可扩展性。
在实际项目中,我们可能会遇到分布式环境下的缓存一致性问题。Spring Boot结合Redis的发布/订阅(Pub/Sub)模式,可以实现消息的实时同步,确保在分布式系统中的数据一致性。 总结来说,"spring-boot-redis.zip...
Java生态是目前软件开发领域的重要组成部分,其丰富的框架和工具为开发者提供了强大的支持。...这将帮助Java初学者快速掌握核心组件的用法,避免在实践中遇到的常见问题,从而提升他们的开发技能和效率。
综上所述,解决Java开发中使用Redis缓存时的多线程数据同步延迟和缓存穿透问题,可以通过引入布隆过滤器、空值缓存策略,以及在代码中使用同步关键字或锁机制来实现。在Springboot2.x环境中,可以通过注解和编码方式...
在SpringBoot项目中集成Redis可以使用Spring Data Redis模块,它简化了Redis的操作,并且与Spring生态系统紧密结合。 **Nosql概述** Nosql,即“Not Only SQL”,它包括键值对存储、列存储、文档存储、图形数据库...
如果遇到session丢失问题,检查网络连接、Redis配置和Tomcat日志是常见的排查手段。 7. **最佳实践** - 尽量减少session中的数据量,只存储必要信息,避免占用过多的Redis内存。 - 考虑使用Spring Session等更...
SSM+Shiro+Redis项目实例是一个典型的Java Web开发架构,涵盖了Spring、Spring MVC、MyBatis、Apache Shiro和Redis等多种技术。...通过这个项目,开发者可以提升自己的技能,为实际工作中遇到的类似问题提供解决方案。
此外,还涵盖了主从复制、哨兵系统和Cluster集群,这些都是在分布式环境中使用Redis时不可或缺的知识点。 在性能优化方面,《Redis实战》探讨了内存管理、命令阻塞问题、过期策略、lua脚本的使用等,帮助读者理解...
在本项目"redis_cluster_simple.zip"中,我们探讨的是如何使用Spring Boot来配置和操作一个Redis集群。Redis是一个高性能的键值存储系统,常用于数据库、缓存和消息中间件等场景。Spring Boot则简化了Java应用的初始...
1. **集成度**:Spring Retry与Spring框架紧密结合,易于在Spring应用中使用,而Guava Retry作为独立库,可以被任何Java项目采用,但需要手动集成。 2. **使用方式**:Spring Retry更注重声明式编程,注解方式更...
在实际使用过程中,可能会遇到的问题及解决方案包括: 1. **性能优化**:根据业务需求调整Redis的内存大小、过期策略和缓存淘汰策略。 2. **安全性**:为Redis服务器设置访问控制,限制非必要的网络访问,避免...
Spring Session是一个为Java平台提供会话管理的库,它提供了一个统一的API和实现用于管理用户会话信息,其核心目的是解决应用程序在分布式系统中处理HTTP会话时可能遇到的常见问题,尤其是在实现集群环境下的会话...
通过阅读《Redis实战》,读者将学习如何配置和管理Redis服务器,如何设计高效的数据模型,如何利用Redis实现缓存、消息队列等功能,以及如何在实际项目中遇到问题时进行调试和优化。此外,书中可能还会涉及与其他...