第五章 查询性能优化之多极缓存

Posted t96fxi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第五章 查询性能优化之多极缓存相关的知识,希望对你有一定的参考价值。

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内存的直接缓存,并且是离用户最近的节点,但是更新机制不太好

以上是关于第五章 查询性能优化之多极缓存的主要内容,如果未能解决你的问题,请参考以下文章

《大型网站技术架构演进与性能优化》——第五章:应用程序优化:代码级优化

第五章:创建高性能索引(上)

第五章:大数据 の HBase 进阶

第五章 MVC之Bundle详解

以C语言为例的程序性能优化 --《深入理解计算机系统》第五章读书笔记

Linux性能优化 第五章 性能工具:特定进程内存