问:
集群是怎么部署的? Redis集群运行原理是什么?Redis的高可用原理?Redis的单线程高并发的原理?
ES分布式架构的原理? 一般你们的ES是如何优化的?
——————————————————————————————————————————————————
一、SpringBoot配置Reids
1、pom引入spring-boot-starter-data-redis包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.4.1</version>
</dependency>
< !-- 设置了连接池的相关参数-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2、application.yml配置Redis地址、端口及基本信息
注:如果Redis开启了密码,在timeout前增加password:xxx
# Spring配置
spring:
# redis配置
redis:
# 地址
host: 127.0.0.1
# 端口,默认为6379
port: 6379
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1m
多redis配置
spring:
redis:
host: 127.0.0.1
port: 6379
password:
lettuce:
pool:
max-active: 32
max-wait: 300
max-idle: 16
min-idle: 8
database: 0
local-redis:
host: 127.0.0.1
port: 6379
database: 0
password:
lettuce:
pool:
max-active: 16
max-wait: 100
max-idle: 8
min-idle: 4
二、增加RedisConfig.java启动加载类
配置类,采用Lettuce,基本设置如下,套路都差不多,先读取配置,初始化ConnectionFactory
,然后创建RedisTemplate
实例,设置连接工厂
@Configuration
public class RedisAutoConfig {
@Bean
public LettuceConnectionFactory defaultLettuceConnectionFactory(RedisStandaloneConfiguration defaultRedisConfig,
GenericObjectPoolConfig defaultPoolConfig) {
LettuceClientConfiguration clientConfig =
LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(100))
.poolConfig(defaultPoolConfig).build();
return new LettuceConnectionFactory(defaultRedisConfig, clientConfig);
}
@Bean
public RedisTemplate<String, String> defaultRedisTemplate(
LettuceConnectionFactory defaultLettuceConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(defaultLettuceConnectionFactory);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
@ConditionalOnBean(name = "localRedisConfig")
public LettuceConnectionFactory localLettuceConnectionFactory(RedisStandaloneConfiguration localRedisConfig,
GenericObjectPoolConfig localPoolConfig) {
LettuceClientConfiguration clientConfig =
LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(100))
.poolConfig(localPoolConfig).build();
return new LettuceConnectionFactory(localRedisConfig, clientConfig);
}
@Bean
@ConditionalOnBean(name = "localLettuceConnectionFactory")
public RedisTemplate<String, String> localRedisTemplate(LettuceConnectionFactory localLettuceConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(localLettuceConnectionFactory);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Configuration
@ConditionalOnProperty(name = "host", prefix = "spring.local-redis")
public static class LocalRedisConfig {
@Value("${spring.local-redis.host:127.0.0.1}")
private String host;
@Value("${spring.local-redis.port:6379}")
private Integer port;
@Value("${spring.local-redis.password:}")
private String password;
@Value("${spring.local-redis.database:0}")
private Integer database;
@Value("${spring.local-redis.lettuce.pool.max-active:8}")
private Integer maxActive;
@Value("${spring.local-redis.lettuce.pool.max-idle:8}")
private Integer maxIdle;
@Value("${spring.local-redis.lettuce.pool.max-wait:-1}")
private Long maxWait;
@Value("${spring.local-redis.lettuce.pool.min-idle:0}")
private Integer minIdle;
@Bean
public GenericObjectPoolConfig localPoolConfig() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(maxActive);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
config.setMaxWaitMillis(maxWait);
return config;
}
@Bean
public RedisStandaloneConfiguration localRedisConfig() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPassword(RedisPassword.of(password));
config.setPort(port);
config.setDatabase(database);
return config;
}
}
@Configuration
public static class DefaultRedisConfig {
@Value("${spring.redis.host:127.0.0.1}")
private String host;
@Value("${spring.redis.port:6379}")
private Integer port;
@Value("${spring.redis.password:}")
private String password;
@Value("${spring.redis.database:0}")
private Integer database;
@Value("${spring.redis.lettuce.pool.max-active:8}")
private Integer maxActive;
@Value("${spring.redis.lettuce.pool.max-idle:8}")
private Integer maxIdle;
@Value("${spring.redis.lettuce.pool.max-wait:-1}")
private Long maxWait;
@Value("${spring.redis.lettuce.pool.min-idle:0}")
private Integer minIdle;
@Bean
public GenericObjectPoolConfig defaultPoolConfig() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(maxActive);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
config.setMaxWaitMillis(maxWait);
return config;
}
@Bean
public RedisStandaloneConfiguration defaultRedisConfig() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPassword(RedisPassword.of(password));
config.setPort(port);
config.setDatabase(database);
return config;
}
}
}
测试类如下,简单的演示下两个template的读写
@SpringBootApplication
public class Application {
public Application(RedisTemplate<String, String> localRedisTemplate, RedisTemplate<String, String>
defaultRedisTemplate)
throws InterruptedException {
// 10s的有效时间
localRedisTemplate.delete("key");
localRedisTemplate.opsForValue().set("key", "value", 100, TimeUnit.MILLISECONDS);
String ans = localRedisTemplate.opsForValue().get("key");
System.out.println("value".equals(ans));
TimeUnit.MILLISECONDS.sleep(200);
ans = localRedisTemplate.opsForValue().get("key");
System.out.println("value".equals(ans) + " >> false ans should be null! ans=[" + ans + "]");
defaultRedisTemplate.opsForValue().set("key", "value", 100, TimeUnit.MILLISECONDS);
ans = defaultRedisTemplate.opsForValue().get("key");
System.out.println(ans);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
上面表示说有多个ConnectionFactory存在,然后创建默认的RedisTemplate就不知道该选择哪一个了,有两种方法
方法一:指定默认的ConnectionFactory
借助@Primary
来指定默认的连接工厂,然后在使用工程的时候,通过@Qualifier
注解来显示指定,我需要的工厂是哪个(主要是localRedisTemplate
这个bean的定义,如果不加,则会根据defaultLettuceConnectionFactory
这个实例来创建Redis连接了)
@Bean
@Primary
public LettuceConnectionFactory defaultLettuceConnectionFactory(RedisStandaloneConfiguration defaultRedisConfig,
GenericObjectPoolConfig defaultPoolConfig) {
// ...
}
@Bean
public RedisTemplate<String, String> defaultRedisTemplate(
@Qualifier("defaultLettuceConnectionFactory") LettuceConnectionFactory defaultLettuceConnectionFactory) {
// ....
}
@Bean
@ConditionalOnBean(name = "localRedisConfig")
public LettuceConnectionFactory localLettuceConnectionFactory(RedisStandaloneConfiguration localRedisConfig,
GenericObjectPoolConfig localPoolConfig) {
// ...
}
@Bean
@ConditionalOnBean(name = "localLettuceConnectionFactory")
public RedisTemplate<String, String> localRedisTemplate(
@Qualifier("localLettuceConnectionFactory") LettuceConnectionFactory localLettuceConnectionFactory) {
// ...
}