
本文共 2499 字,大约阅读时间需要 8 分钟。
背景
在最近的项目中,我们需要对一个庞大的数据库进行查询,数据量大约在几千万条的级别。同时,对查询速度有很高的要求。我们最初使用的是Hive进行查询,单次查询速度在几分钟级别,显然无法满足交互式查询的需求。在使用Presto进行优化后,查询速度下降到了秒级别,但仍然对分页功能的支持不够友好,手动实现分页导致了后续优化的必要性。
缓存的选择
虽然Presto相比Hive带来了速度的提升(官方宣称是10倍),但在实际应用场景中,对前端分页支持仍不够理想。为了优化用户体验,采用了Redis缓存,这是让人不得已的选择。尽管如此,优化应从底层手始。 好吧,我们来看一下使用 RedisTemplate。Spring 提供了一个强大的 Redis 模板,RedisTemplate,这个模板在开发过程中使用非常方便。Redis 中可以存储各种数据类型,如 String、List、Set、Hash、Zset 等。本文将重点介绍 List 和 Hash 的使用方法。
List 操作
Redis 的 List 类型是一个简单的字符串列表。常见的操作方法包括:
- hasKey
- range
- delete
- size
- leftPush
- leftPushAll
- leftPushIfPresent
- leftPop
- rightPush
- rightPushAll
- rightPushIfPresent
- rightPop
- index
- trim
- remove
- rightPopAndLeftPush
Hash 操作
Hash 类型可以用来存储类似 HashMap 的数据。在开发中,一个 Redis 键可以理解为一个 HashMap:
- put
- putAll
- putIfAbsent
- get
- delete
- values
- entries
- hasKey
- keys
- size
- increment
- multiGet
- scan
引入 RedisTemplate
为了使用 RedisTemplate,需要在项目中引入相应的依赖和配置文件。具体步骤包括:
- 在 pom.xml 中添加 Spring Boot Data Redis 依赖。
- 创建一个 RedisConfig 配置文件,配置 RedisTemplate 的序列化。
- 将 RedisTemplate 注入应用程序,使用 @Autowired 注注。
配置文件样例如下:
package com.detectivehlh;
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
-
RedisConfig
-
@author Lunhao Hu
-
@date 2019-01-17 15:12 */ @Configuration public class RedisConfig {
@Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); jackson2JsonRedisSerializer.setObjectMapper(om); StringRedisTemplate template = new StringRedisTemplate(factory); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashKeySerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template;
}
}
这样配置后,可以在需要使用 Redis 操作的组件中注入 RedisTemplate 实例,并通过其提供的操作方法进行缓存操作。
最终,通过在前端中使用 Redis 缓存,可以有效减少对数据库的查询次数。当用户第一次查询时,会耗费较长时间;但一旦数据缓存完成,后续的分页操作则可以在毫秒级别完成,从而大幅提升用户体验。
发表评论
最新留言
关于作者
