文章目录
- [0. 引言](#0. 引言)
- [1. pika客户端支持](#1. pika客户端支持)
- [2. jedis集成pika](#2. jedis集成pika)
- [3. pika性能测试](#3. pika性能测试)
0. 引言
上节我们讲解了pika的搭建,这节我们来看下如何在java项目中利用jedis集成pika
1. pika客户端支持
pika支持的客户端与redis完全一致,所以理论上redis支持的客户端pika也都支持,并且其操作接口用法也相同。
具体列表可查看官方说明:https://github.com/OpenAtomFoundation/pika/wiki/支持的语言和客户端
这里我们以jedis为例,在springboot项目中集成pika
2. jedis集成pika
1、创建springboot项目,引入jedis依赖,为了方便和springboot项目集成,我这里单独引入了spring-data-redis
xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 书写web接口用于测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 使用@ConfigurationProperties注解引入配置项 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2、application.yml中书写配置项
yml
spring:
redis:
host: pika
port: 9221
password:
database: 0
maxTotal: 100
maxIdle: 10
minIdle: 1
blockWhenExhausted: true
maxWaitMillis: 60000
testOnBorrow: false
testOnReturn: false
jmxEnabled: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 120000
numTestsPerEvictionRun: 1
3、创建配置项实体
java
@Data
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private String host;
private Integer port;
private String password;
private int database;
private int maxTotal;
private int maxIdle;
private int minIdle;
private Boolean blockWhenExhausted;
private int maxWaitMillis;
private Boolean testOnBorrow;
private Boolean testOnReturn;
private Boolean jmxEnabled;
private Boolean testWhileIdle;
private long timeBetweenEvictionRunsMillis;
private long minEvictableIdleTimeMillis;
private int numTestsPerEvictionRun;
}
4、创建配置类,用于声明jedis连接池
java
@EnableCaching
@Configuration
@Slf4j
public class RedisConfig {
@Resource
private RedisProperties redisProperties;
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
log.info("开始初始redis -->redisTemplate");
RedisSerializer<Object> serializer = redisSerializer();
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置 redisTemplate 的序列化器
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
log.info("初始redis完成 -->redisTemplate");
return redisTemplate;
}
/**
* jedis连接工厂
*
* @param jedisPoolConfig
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
//单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisProperties.getHost());
redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase());
redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
redisStandaloneConfiguration.setPort(redisProperties.getPort());
//获得默认的连接池构造器
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpccb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
jpccb.poolConfig(jedisPoolConfig);
//通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpccb.build();
//单机配置 + 客户端配置 = jedis连接工厂
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
jedisPoolConfig.setMinIdle(redisProperties.getMinIdle());
jedisPoolConfig.setBlockWhenExhausted(redisProperties.getBlockWhenExhausted());
jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
jedisPoolConfig.setTestOnBorrow(redisProperties.getTestOnBorrow());
jedisPoolConfig.setTestOnReturn(redisProperties.getTestOnReturn());
jedisPoolConfig.setJmxEnabled(redisProperties.getJmxEnabled());
//空闲Jedis对象检测由下列四个参数组合完成。
jedisPoolConfig.setTestWhileIdle(redisProperties.getTestWhileIdle());
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
jedisPoolConfig.setMinEvictableIdleTimeMillis(redisProperties.getMinEvictableIdleTimeMillis());
jedisPoolConfig.setNumTestsPerEvictionRun(redisProperties.getNumTestsPerEvictionRun());
return jedisPoolConfig;
}
public RedisSerializer<Object> redisSerializer() {
//创建JSON序列化器
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
serializer.setObjectMapper(objectMapper);
return serializer;
}
}
5、创建一个controller,然后书写测试接口
java
@Resource
RedisTemplate<String, Object> redisTemplate;
@GetMapping("singleSet")
public String singleSet(String key, String value) {
redisTemplate.opsForValue().set(key, value);
return Objects.requireNonNull(redisTemplate.opsForValue().get(key)).toString();
}
测试结果如下,因为数据是从pika中查询的,说明设置成功
从上述可以看到,其集成过程与redis完全一致,大家要实现集群模式或者哨兵模式的集成,也可以参考redis的形式
3. pika性能测试
最后,为了验证pika与redis之间的差别,在服务器中对pika进行了压测,pika配置中仅调整了thread-num : 4
,让其线程数与cpu核数保持一致,其他按照官方默认配置进行
提前导入了7亿数据,占用磁盘30G,磁盘采用机械硬盘,pika单节点测试结果如下
并发数 | 平均查询耗时 | 循环次数 |
---|---|---|
50 | 5ms | 10 |
100 | 9ms | 10 |
200 | 26ms | 10 |
500 | 88ms | 10 |
可以看到pika在低并发下的耗时是可以控制在10ms内的,高并发下也在100ms内,可以满足高并发低延迟的使用场景