SpringBoot整合Redis及Redis简介
2019-04-04 本文已影响0人
maxzhao_
前言
由于版本原因,SpringBoot2.0整合Redis和低版本的SpringBoot不太一样,此方案基于Srping Boot 2.x
。
整合
maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 下面的不用加,用于分布式共享session的配置 -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
分布式共享session
参考:参考
配置文件application.properties
# Redis 数据库索引
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=maxzhao
# 连接池最大连接数
spring.redis.jedis.pool.max-active=1000
# 连接池最大阻塞等待时间,负值没有限制
spring.redis.jedis.pool.max-wait=-1
# 连接池中最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
# 超时时间 毫秒
spring.redis.timeout=1000
注入
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
// StringRedisTemplate是继承RedisTemplate的,
// RedisTemplate在StringRedisTemplate中泛型定义为String
StringRedisTemplate
源码
public class StringRedisTemplate extends RedisTemplate<String, String> {
public StringRedisTemplate() {
this.setKeySerializer(RedisSerializer.string());
this.setValueSerializer(RedisSerializer.string());
this.setHashKeySerializer(RedisSerializer.string());
this.setHashValueSerializer(RedisSerializer.string());
}
public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
this();
this.setConnectionFactory(connectionFactory);
this.afterPropertiesSet();
}
protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
return new DefaultStringRedisConnection(connection);
}
}
StringRedisTemplate
测试
这里用的是Springboot Test
@RunWith(SpringRunner.class)
@SpringBootTest(classes = IttestApplication.class)
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testRedisTemplate() {
String prefix = "maxzhao:redisTemplate:";
HashOperations hashOperations = redisTemplate.opsForHash();
ValueOperations valueOps = redisTemplate.opsForValue();
ListOperations listOps = redisTemplate.opsForList();
SetOperations setOps = redisTemplate.opsForSet();
ZSetOperations zSetOps = redisTemplate.opsForZSet();
GeoOperations geoOperations = redisTemplate.opsForGeo();
ClusterOperations clusterOperations = redisTemplate.opsForCluster();
Map map = Arrays.stream(new String[]{"a", "B"}).collect(Collectors.toMap(Function.identity(), Function.identity()));
hashOperations.putAll(prefix + "hash", map);
}
@Test
public void testStringRedisTemplate() {
String prefix = "maxzhao:stringRedisTemplate:";
HashOperations hashOperations = stringRedisTemplate.opsForHash();
hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"a", "b"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"c", "d"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
hashOperations.putAll(prefix + "hash", Arrays.stream(new String[]{"e", "f"}).collect(Collectors.toMap(Function.identity(), Function.identity())));
hashOperations.put(prefix + "hash", "max", "maxvalue");// a b c d e f max
hashOperations.get(prefix + "hash", "max");// maxvalue
hashOperations.delete(prefix + "hash", "f");// return 1 database:a b c d e max
hashOperations.delete(prefix + "hash", "c", "d");// return 2 database:a b e max
hashOperations.hasKey(prefix + "hash", "max");//return true
hashOperations.values(prefix + "hash");// return map object
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
valueOperations.set(prefix + "value", "value");
valueOperations.set(prefix + "value", "valueTest");//value 被覆盖
valueOperations.get(prefix + "value");// return valueTest
ListOperations listOps = stringRedisTemplate.opsForList();
// listOps.remove(prefix + "list", listOps.size(prefix + "list"), 1);
listOps.leftPush(prefix + "list", "A");
listOps.leftPush(prefix + "list", "B");
listOps.rightPush(prefix + "list", "C", "D");//只有 1:B 2:A
listOps.leftPush(prefix + "list", "C");
listOps.leftPush(prefix + "list", "D");//return 3 1:D 2:C 3:A
listOps.range(prefix + "list", 0, listOps.size(prefix + "list"));//return 3 0:D 1:C 2:A list下标从0开始
listOps.leftPop(prefix + "list");//只有 1:A 返回的为B
listOps.leftPush(prefix + "list2", "A");
listOps.leftPush(prefix + "list2", "B");//只有 1:B 2:A
listOps.rightPush(prefix + "list2", "C");//只有 1:B 2:A 3 C
// set 是无序的,所有pop等获取value的操作,得到结果可能不同
SetOperations setOps = stringRedisTemplate.opsForSet();
setOps.add(prefix + "set", "A");//return 1
setOps.add(prefix + "set", "A");//return 0
setOps.add(prefix + "set", "B");//return 1
setOps.difference(prefix + "set", "A");//return HashSet A,B
setOps.isMember(prefix + "set", "A");//return true
setOps.isMember(prefix + "set", "C");//return false
setOps.members(prefix + "set");//return HashSet A,B
setOps.pop(prefix + "set");// 出序列并删除 1个
setOps.add(prefix + "set", "A","B", "C", "D", "E");//return 5
setOps.pop(prefix + "set", 2);// 出序列并删除 2个
setOps.add(prefix + "set", "A","B", "C", "D", "E");
setOps.move(prefix + "set", "D", "A");//return true database=BCE
// 把当前key=set的c值,move到 key=set1
setOps.move(prefix + "set", "C", prefix + "set1");//return true
setOps.remove(prefix + "set", "C", "D");//删除
// 有序的set
ZSetOperations zSetOps = stringRedisTemplate.opsForZSet();
GeoOperations geoOperations = stringRedisTemplate.opsForGeo();
// 只有jedis 和 lettuce 支持Redis Cluster。
ClusterOperations clusterOperations = stringRedisTemplate.opsForCluster();
System.out.println("====================");
}
}
Redis Cluster
Enabling Redis Cluster
<p>集群的支持是基于非集群通讯构建的。RedisClusterConnection 是RedisConnection 的一个扩展,用来处理和Redis Cluster的通讯,转换错误信息到Spring DAO异常层。RedisClusterConnection 是通过RedisConnectionFactory 创建的,该工程的创建要依据于RedisClusterConfiguration配置。</p>
Example 1. Sample RedisConnectionFactory Configuration for Redis Cluster
@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties {
/*
* spring.redis.cluster.nodes[0] = 127.0.0.1:7379
* spring.redis.cluster.nodes[1] = 127.0.0.1:7380
* ...
*/
List<String> nodes;
/**
* Get initial collection of known cluster nodes in format {@code host:port}.
*
* @return
*/
public List<String> getNodes() {
return nodes;
}
public void setNodes(List<String> nodes) {
this.nodes = nodes;
}
}
@Configuration
public class AppConfig {
/**
* Type safe representation of application.properties
*/
@Autowired ClusterConfigurationProperties clusterProperties;
public @Bean RedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory(
new RedisClusterConfiguration(clusterProperties.getNodes()));
}
}
通过配置文件配置:
# 这个初始化的配置为驱动库指定了一组初始化集群节点。集群可以在线修改配置,但修改结果只会保存在本驱动的内存中,不会写入到配置文件中。
spring.redis.cluster.nodes: Comma delimited list of host:port pairs.
spring.redis.cluster.max-redirects: Number of allowed cluster redirections.
参考:官方文档中文版(个人站)
参考:官方文档中文版(官网)
本文地址:SpringBoot整合Redis及Redis简介
RedisTemplate
源码
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
// 是否支持事物,必须通过设置setEnableTransactionSupport(true)显式地为使用中的每个RedisTemplate启用事务支持这将强制将正在使用的重断开绑定到当前线程触发MULTI。如果事务完成时没有错误,则调用EXEC,否则丢弃。一旦在MULTI中,RedisConnection将对写操作进行排队,所有只读操作(例如键)都将通过管道传输到一个新的(非线程绑定的)RedisConnection。
private boolean enableTransactionSupport = false;
// 有一个this.createRedisConnectionProxy代理
private boolean exposeConnection = false;
// afterPropertiesSet()方法用到,此方法允许bean实例在设置了所有bean属性后执行总体配置的验证和最终初始化。
private boolean initialized = false;
// 默认序列化
private boolean enableDefaultSerializer = true;
// 默认使用JdkSerializationRedisSerializer序列化
@Nullable
private RedisSerializer<?> defaultSerializer;
@Nullable
private ClassLoader classLoader;
// 默认使用 this.defaultSerializer 序列化
@Nullable
private RedisSerializer keySerializer = null;
// 默认使用 this.defaultSerializer 序列化
@Nullable
private RedisSerializer valueSerializer = null;
// 默认使用 this.defaultSerializer 序列化
@Nullable
private RedisSerializer hashKeySerializer = null;
// 默认使用 this.defaultSerializer 序列化
@Nullable
private RedisSerializer hashValueSerializer = null;
// 默认使用 new StringRedisSerializer(StandardCharsets.UTF_8)
private RedisSerializer<String> stringSerializer = RedisSerializer.string();
// 用于执行Redis脚本的ScriptExecutor
@Nullable
private ScriptExecutor<K> scriptExecutor;
@Nullable
private ValueOperations<K, V> valueOps;
@Nullable
private ListOperations<K, V> listOps;
@Nullable
private SetOperations<K, V> setOps;
@Nullable
private ZSetOperations<K, V> zSetOps;
@Nullable
private GeoOperations<K, V> geoOps;
@Nullable
private HyperLogLogOperations<K, V> hllOps;
public RedisTemplate() {
}
public void afterPropertiesSet() ;
// 在连接中执行给定的操作对象
@Nullable
public <T> T execute(RedisCallback<T> action) ;
// 在连接中执行给定的操作对象,该对象可以公开,也可以不公开。
@Nullable
public <T> T execute(RedisCallback<T> action, boolean exposeConnection) ;
// 在可公开或不可公开的连接中执行给定的操作对象。此外,可以对连接进行流水线操作。注意,管道的结果被丢弃(使其适合只写的场景)。有道翻译
@Nullable
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline);
// 执行一个Redis会话。允许在同一个会话中执行多个操作,通过RedisOperations.multi()和RedisOperations.watch(Collection)操作启用“事务”功能。
public <T> T execute(SessionCallback<T> session) ;
//在管道连接上执行给定的Redis会话。允许流水线处理事务。注意,回调函数不能返回非空值,因为它被管道覆盖。
public List<Object> executePipelined(SessionCallback<?> session) ;
// 自定义序列化
public List<Object> executePipelined(SessionCallback<?> session, @Nullable RedisSerializer<?> resultSerializer) ;
// 在管道连接上执行给定的操作对象,返回结果。注意,回调函数不能返回非空值,因为它被管道覆盖。此方法将使用默认的序列化器反序列化结果
public List<Object> executePipelined(RedisCallback<?> action) ;
// 自定义序列化
public List<Object> executePipelined(RedisCallback<?> action, @Nullable RedisSerializer<?> resultSerializer) ;
public <T> T execute(RedisScript<T> script, List<K> keys, Object... args) ;
public <T> T execute(RedisScript<T> script, RedisSerializer<?> argsSerializer, RedisSerializer<T> resultSerializer, List<K> keys, Object... args) ;
public <T extends Closeable> T executeWithStickyConnection(RedisCallback<T> callback) ;
private Object executeSession(SessionCallback<?> session) {
return session.execute(this);
}
protected RedisConnection createRedisConnectionProxy(RedisConnection pm) ;
protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) ;
@Nullable
protected <T> T postProcessResult(@Nullable T result, RedisConnection conn, boolean existingConnection) ;
public boolean isExposeConnection();
public void setExposeConnection(boolean exposeConnection) ;
public boolean isEnableDefaultSerializer() ;
public void setEnableDefaultSerializer(boolean enableDefaultSerializer) ;
@Nullable
public RedisSerializer<?> getDefaultSerializer() ;
public void setDefaultSerializer(RedisSerializer<?> serializer) ;
public void setKeySerializer(RedisSerializer<?> serializer) ;
public RedisSerializer<?> getKeySerializer() ;
public void setValueSerializer(RedisSerializer<?> serializer) ;
public RedisSerializer<?> getValueSerializer() ;
public RedisSerializer<?> getHashKeySerializer() ;
public void setHashKeySerializer(RedisSerializer<?> hashKeySerializer) ;
public RedisSerializer<?> getHashValueSerializer() ;
public void setHashValueSerializer(RedisSerializer<?> hashValueSerializer) ;
public RedisSerializer<String> getStringSerializer() ;
public void setStringSerializer(RedisSerializer<String> stringSerializer) ;
public void setScriptExecutor(ScriptExecutor<K> scriptExecutor) ;
private byte[] rawKey(Object key) ;
private byte[] rawString(String key) ;
private byte[] rawValue(Object value) ;
private byte[][] rawKeys(Collection<K> keys) ;
private K deserializeKey(byte[] value) ;
@Nullable
private List<Object> deserializeMixedResults(@Nullable List<Object> rawValues, @Nullable RedisSerializer valueSerializer, @Nullable RedisSerializer hashKeySerializer, @Nullable RedisSerializer hashValueSerializer) ;
private Set<?> deserializeSet(Set rawSet, @Nullable RedisSerializer valueSerializer) ;
private Set<TypedTuple<V>> convertTupleValues(Set<Tuple> rawValues, @Nullable RedisSerializer valueSerializer) ;
public List<Object> exec() ;
public List<Object> exec(RedisSerializer<?> valueSerializer) ;
protected List<Object> execRaw() ;
public Boolean delete(K key) ;
public Long delete(Collection<K> keys) ;
public Boolean unlink(K key) ;
public Long unlink(Collection<K> keys) ;
public Boolean hasKey(K key) ;
public Long countExistingKeys(Collection<K> keys) ;
public Boolean expire(K key, long timeout, TimeUnit unit) ;
public Boolean expireAt(K key, Date date) ;
public void convertAndSend(String channel, Object message);
public Long getExpire(K key) ;
public Long getExpire(K key, TimeUnit timeUnit) ;
public Set<K> keys(K pattern) ;
public Boolean persist(K key) ;
public Boolean move(K key, int dbIndex) ;
public K randomKey() ;
public void rename(K oldKey, K newKey) ;
public Boolean renameIfAbsent(K oldKey, K newKey) ;
public DataType type(K key);
public byte[] dump(K key) ;
public void restore(K key, byte[] value, long timeToLive, TimeUnit unit, boolean replace) ;
public void multi() ;
public void discard() ;
public void watch(K key) ;
public void watch(Collection<K> keys) ;
public void unwatch() ;
public List<V> sort(SortQuery<K> query) ;
public <T> List<T> sort(SortQuery<K> query, @Nullable RedisSerializer<T> resultSerializer) ;
public <T> List<T> sort(SortQuery<K> query, BulkMapper<T, V> bulkMapper) ;
public <T, S> List<T> sort(SortQuery<K> query, BulkMapper<T, S> bulkMapper, @Nullable RedisSerializer<S> resultSerializer) ;
public Long sort(SortQuery<K> query, K storeKey) ;
public void killClient(String host, int port);
public List<RedisClientInfo> getClientList() ;
public void slaveOf(String host, int port) ;
public void slaveOfNoOne() ;