第五章 查询性能优化之多极缓存
1.redis集中式缓存
//商品详情页浏览
@RequestMapping(value = "/get",method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType getItem(@RequestParam(name = "id")Integer id){
ItemModel itemModel = null;
// 先从本地缓存取
itemModel = (ItemModel) cacheService.getFromCommonCache("item_"+id);
if(itemModel == null) {
// 再从redis缓存中取
itemModel = (ItemModel) redisTemplate.opsForValue().get("item_"+id);
if(itemModel == null) {
// 最后从数据库取
itemModel = itemService.getItemById(id);
redisTemplate.opsForValue().set("item_"+id, itemModel);
redisTemplate.expire("item_"+id, 10, TimeUnit.MINUTES);
}
cacheService.setCommonCache("item_"+id, itemModel);
}
ItemVO itemVO = convertVOFromModel(itemModel);
return CommonReturnType.create(itemVO);
}springboot redis存储数据会编码,去除编码直接string序列化
@Component
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 解决key序列化方式
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
// 时间序列化格式
simpleModule.addSerializer(DateTime.class, new JodaDateTimeJsonSerializer());
// 时间反序列化格式
simpleModule.addDeserializer(DateTime.class, new JodaDateTimeJsonDeserializer());
objectMapper.registerModule(simpleModule);
// 序列化时增加类型,方便解析成对应类型
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonRedisSerializer.setObjectMapper(objectMapper);
template.setValueSerializer(jsonRedisSerializer);
return template;
}
}/** 时间序列化 **/public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime>{
@Override public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss")); }
}
/**时间反序列化**/
public class JodaDateTimeJsonDeserializer extends JsonDeserializer<DateTime> {
@Override public DateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { String dateTime = p.readValueAs(String.class); DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); return format.parseDateTime(dateTime); }}
缺点:redis的存或者取都需要经过网络IO达到redis Server上,并根据redis协议更新对应状态,所以相对操作本地缓存会慢些
2.本地热点缓存,使用谷歌的guava cache
@Service
public class CacheServiceImpl implements CacheService {
private Cache<String, Object> commonCache = null;
@PostConstruct
public void init() {
commonCache = CacheBuilder.newBuilder()
// 初始容量为10
.initialCapacity(10)
// 最大容量100
.maximumSize(100)
// 失效时间60秒
.expireAfterWrite(60, TimeUnit.MICROSECONDS)
.build();
}
@Override
public void setCommonCache(String key, Object value) {
commonCache.put(key, value);
}
@Override
public Object getFromCommonCache(String key) {
// TODO Auto-generated method stub
return commonCache.getIfPresent(key);
}
}CacheService的使用在上面getItem方法的代码中。
3.nginx缓存,shared dic共享内存字典
也是key和value类型的缓存。优势:基于nginx内存的直接缓存,并且是离用户最近的节点,但是更新机制不太好
相关推荐
houdaxiami 2020-08-15
yanzhelee 2020-10-13
89243453 2020-08-24
89253818 2020-07-30
89253818 2020-07-19
81264454 2020-07-17
iftrueIloveit 2020-07-04
ItBJLan 2020-06-28
开心就好 2020-06-16
Jaystrong 2020-06-16
iftrueIloveit 2020-06-11
QiHsMing 2020-06-08
webfullStack 2020-06-07
不知道该写啥QAQ 2020-06-06
fsl 2020-06-05
Carlos 2020-05-31
85231843 2020-05-31
curiousL 2020-05-27