什么是redis
一个非关系型数据库,可以将一部分数据持久化在本地,但是其内存运行的特性保证了redis的速度,所以多用作web服务的缓存,用于缓解后台服务器数据库的并发压力。
我们是否真的需要redis
redis主要用于缓存数据,在高速读写的环境下使用。
一般来说,我们只有在某些特定的场景中才会需要缓存来加速我们的应用
- 数据是常用数据吗,业务运行时数据的命中率如何,如果命中率很低,也就是说数据更新频繁,那么就不太适合写入缓存
- 该业务数据是读取的操作多,还是写入的操作多?写入更多参考上一条,不适合写入缓存
- 数据量有多少,虽然redis的最大单值容量可以达到512MB但还是不太适合存放过大的数据,而且也没有必要
解决String与JAVA对象的相互转换
redis只支持了六种数据类型,string/hash/list/set/zset/hyperloglog
,而没有JAVA中最常使用的object,所以我们需要在string与object做序列化的工作,来调用。
对此我们需要重写redisTemplate的序列化方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;
@Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisCacheConfig { @Bean public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory connectionFactory) { RedisTemplate<String, Serializable> template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setConnectionFactory(connectionFactory); return template; } }
|
在POJO增删改查时中使用缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| @Service public class UserServiceImpl implements UserService { private static Map<Integer, User> userMap = new HashMap<>();
static { userMap.put(1, new User(1, "张三", 25)); userMap.put(2, new User(2, "李四", 26)); userMap.put(3, new User(3, "王五", 24)); }
@CachePut(value = "user", key = "#user.id") @Override public User save(User user) { userMap.put(user.getId(), user); return user; }
@CacheEvict(value = "user", key = "#id") @Override public void delete(int id) { userMap.remove(id); return; }
@Cacheable(value = "user", key = "#id") @Override public User get(int id) { return userMap.get(id); }
@CachePut(value = "user", key = "#user.id") @Override public void update(User user) { userMap.put(user.getId(), user); return; } }
|
很明显,对不同的操作,用了不同的缓存策略。
- 当需要变更数据库的数据时,缓存就会被标记为无效,同时将会更新缓存中的值
- 当不需要更改,这直接读取缓存而不是去查数据库,这样就能规避数据库查询带来的时间损耗
遇到的错误
1
| Could not connect to Redis at 127.0.0.1:6379: Connection refused
|
连接失败,多是因为redis没有默认在后台运行,可以编辑redis.conf
文件中的daemonize属性,来让redis在后台静默运行。
spring boot运行redis项目无法启动
1
| Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer'
|
redis没有启动,启动redis即可解决。