Redis在项目中的应用(二)
项目中少不了redis用于存储我们要的数据,那么我们该如何高效的使用redis来为我们服务呢?
为了让 Key 的命名和使用更加规范,以及今后避免再次遇到这种情况,下午睡醒之后,我就在 Redis 公共组件库里面添加了一个配置和自定义了 Key 序列化。
代码如下:
@ConfigurationProperties(prefix = "spring.redis.prefix") public class RedisKeyPrefixProperties { private Boolean enable = Boolean.TRUE; private String key; public Boolean getEnable() { return enable; } public void setEnable(Boolean enable) { this.enable = enable; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
/** * @desc 对字符串序列化新增前缀 * @author create by liming sun on 2020-07-21 14:09:51 */ public class PrefixStringKeySerializer extends StringRedisSerializer { private Charset charset = StandardCharsets.UTF_8; private RedisKeyPrefixProperties prefix; public PrefixStringKeySerializer(RedisKeyPrefixProperties prefix) { super(); this.prefix = prefix; } @Override public String deserialize(@Nullable byte[] bytes) { String saveKey = new String(bytes, charset); if (prefix.getEnable() != null && prefix.getEnable()) { String prefixKey = spliceKey(prefix.getKey()); int indexOf = saveKey.indexOf(prefixKey); if (indexOf > 0) { saveKey = saveKey.substring(indexOf); } } return (saveKey.getBytes() == null ? null : saveKey); } @Override public byte[] serialize(@Nullable String key) { if (prefix.getEnable() != null && prefix.getEnable()) { key = spliceKey(prefix.getKey()) + key; } return (key == null ? null : key.getBytes(charset)); } private String spliceKey(String prefixKey) { if (StringUtils.isNotBlank(prefixKey) && !prefixKey.endsWith(":")) { prefixKey = prefixKey + "::"; } return prefixKey; } }
使用效果:为了避免再次发生这种工作低效而又不得不做的事情,我们在开发规范中规定,新项目中 Redis 的使用必须设置此配置,前缀就设置为:项目编号。
另外,一个模块中的 Key 必须统一定义在二方库的 RedisKeyConstant 类中。
配置如下:
spring: redis: prefix: enable: true key: E00P01
@Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 支持key前缀设置的key Serializer redisTemplate.setKeySerializer(new PrefixStringKeySerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; }
通过以上方式,我们至少可以从项目维度来区分出 Key,避免了多个项目之间共用同一个集群时而导致重复 Key 的问题。
从项目维度对 Key 进行了划分。更方便管理和运维。如果对于 Key 的管理粒度要求更细,我们甚至可以细化到具体业务维度。
我们在测试环境进行了压测,增加 Key 前缀对 Redis 性能几乎没有影响。性能方面能接受。