Redis常用客户端及配置

目前常用的客户端有jedis,lettuce,redisson

共同点:都提供了基于Redis操作的Java API,只是封装程度,具体实现稍有不同

不同点:

  •   jedis:

是Redis的Java实现的客户端。支持基本的数据类型如:String、Hash、List、Set、Sorted Set。

特点:使用阻塞的I/O,方法调用同步,程序流需要等到socket处理完I/O才能执行,不支持异步操作。Jedis客户端实例不是线程安全的,需要通过连接池来使用Jedis。

  • Redisson

优点: 分布式锁,分布式集合,可通过Redis支持延迟队列

  •  Lettuce

用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。

基于Netty框架的事件驱动的通信层,其方法调用是异步的。Lettuce的API是线程安全的,所以可以操作单个Lettuce连接来完成各种操作。

lettuce连接池配置

    org.springframework.bootspring-boot-starter-data-redis//在2.0版本之前默认引入是jedispool连接池,在2.0之后默认引入lettuce连接池org.apache.commonscommons-pool2

##application.properties 添加redis连接信息

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

server.port=8945


#redis数据库默认使用db0
spring.redis.database=2
spring.redis.password=
spring.redis.port=6379
spring.redis.host=127.0.0.1
# 连接超时时间
spring.redis.timeout=5000
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=3
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=2
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=3
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=-1
#在关闭客户端连接之前等待任务处理完成的最长时间,在这之后,无论任务是否执行完成,都会被执行器关闭,默认100ms
spring.redis.lettuce.shutdown-timeout=100
#是否缓存空值
spring.cache.redis.cache-null-values=false

//配置类
package org.example.base.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;/*** @author l* @date Created in 2020/11/3 10:51*/
@Configuration
@EnableCaching
public class RedisConfig {@Value("${spring.redis.database}")private int database;@Value("${spring.redis.host}")private String host;@Value("${spring.redis.password}")private String password;@Value("${spring.redis.port}")private int port;@Value("${spring.redis.timeout}")private long timeout;@Value("${spring.redis.lettuce.shutdown-timeout}")private long shutDownTimeout;@Value("${spring.redis.lettuce.pool.max-idle}")private int maxIdle;@Value("${spring.redis.lettuce.pool.min-idle}")private int minIdle;@Value("${spring.redis.lettuce.pool.max-active}")private int maxActive;@Value("${spring.redis.lettuce.pool.max-wait}")private long maxWait;Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);@Beanpublic LettuceConnectionFactory lettuceConnectionFactory() {GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();genericObjectPoolConfig.setMaxIdle(maxIdle);genericObjectPoolConfig.setMinIdle(minIdle);genericObjectPoolConfig.setMaxTotal(maxActive);genericObjectPoolConfig.setMaxWaitMillis(maxWait);genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(100);RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();redisStandaloneConfiguration.setDatabase(database);redisStandaloneConfiguration.setHostName(host);redisStandaloneConfiguration.setPort(port);redisStandaloneConfiguration.setPassword(RedisPassword.of(password));LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(timeout)).shutdownTimeout(Duration.ofMillis(shutDownTimeout)).poolConfig(genericObjectPoolConfig).build();LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
//        factory.setShareNativeConnection(true);
//        factory.setValidateConnection(false);return factory;}@Beanpublic RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {RedisTemplate template = new RedisTemplate<>();template.setConnectionFactory(lettuceConnectionFactory);//使用Jackson2JsonRedisSerializer替换默认的JdkSerializationRedisSerializer来序列化和反序列化redis的value值ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(mapper);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Bean("redisCacheManager")@Primarypublic CacheManager cacheManager( LettuceConnectionFactory lettuceConnectionFactory) {RedisSerializer redisSerializer = new StringRedisSerializer();//解决查询缓存转换异常的问题ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(mapper);// 配置1 ,RedisCacheConfiguration config1 = RedisCacheConfiguration.defaultCacheConfig()//缓存失效时间.entryTtl(Duration.ofSeconds(30))//key序列化方式.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//value序列化方式.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))//不允许缓存null值.disableCachingNullValues();//配置2 ,RedisCacheConfiguration config2 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(1000)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();//设置一个初始化的缓存空间set集合Set cacheNames = new HashSet<>();cacheNames.add("my-redis-cache1");cacheNames.add("my-redis-cache2");//对每个缓存空间应用不同的配置Map configurationMap = new HashMap<>(3);configurationMap.put("my-redis-cache1", config1);configurationMap.put("my-redis-cache2", config2);return RedisCacheManager.builder(lettuceConnectionFactory)//默认缓存配置.cacheDefaults(config1)//初始化缓存空间.initialCacheNames(cacheNames)//初始化缓存配置.withInitialCacheConfigurations(configurationMap).build();}
 

使用时引入redistemplate即可

RedissonClient 操作示例

org.springframework.bootspring-boot-starter-data-redisorg.redissonredisson3.8.2trueorg.redissonredisson-spring-boot-starterLATEST
# Redisson 配置
singleServerConfig:address: "redis://192.168.1.140:6379"password: nullclientName: nulldatabase: 15 #选择使用哪个数据库0~15idleConnectionTimeout: 10000pingTimeout: 1000connectTimeout: 10000timeout: 3000retryAttempts: 3retryInterval: 1500reconnectionTimeout: 3000failedAttempts: 3subscriptionsPerConnection: 5subscriptionConnectionMinimumIdleSize: 1subscriptionConnectionPoolSize: 50connectionMinimumIdleSize: 32connectionPoolSize: 64dnsMonitoringInterval: 5000#dnsMonitoring: falsethreads: 0
nettyThreads: 0
codec:class: "org.redisson.codec.JsonJacksonCodec"
transportMode: "NIO"
spring:redis:redisson:config: classpath:redisson-config.yaml
@RestController
@RequestMapping("/")
public class TeController {@Autowiredprivate RedissonClient redissonClient;static long i = 20;static long sum = 300;//    ========================== String =======================@GetMapping("/set/{key}")public String s1(@PathVariable String key) {// 设置字符串RBucket keyObj = redissonClient.getBucket(key);keyObj.set(key + "1-v1");return key;}@GetMapping("/get/{key}")public String g1(@PathVariable String key) {// 设置字符串RBucket keyObj = redissonClient.getBucket(key);String s = keyObj.get();return s;}//    ========================== hash =======================-=@GetMapping("/hset/{key}")public String h1(@PathVariable String key) {Ur ur = new Ur();ur.setId(MathUtil.randomLong(1,20));ur.setName(key);// 存放 HashRMap ss = redissonClient.getMap("UR");ss.put(ur.getId().toString(), ur);return ur.toString();}@GetMapping("/hget/{id}")public String h2(@PathVariable String id) {// hash 查询RMap ss = redissonClient.getMap("UR");Ur ur = ss.get(id);return ur.toString();}// 查询所有的 keys@GetMapping("/all")public String all(){RKeys keys = redissonClient.getKeys();Iterable keys1 = keys.getKeys();keys1.forEach(System.out::println);return keys.toString();}// ================== ==============读写锁测试 =============================@GetMapping("/rw/set/{key}")public void rw_set(){
//        RedissonLock.RBucket ls_count = redissonClient.getBucket("LS_COUNT");ls_count.set("300",360000000l, TimeUnit.SECONDS);}// 减法运算@GetMapping("/jf")public void jf(){String key = "S_COUNT";//        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
//        atomicLong.set(sum);
//        long l = atomicLong.decrementAndGet();
//        System.out.println(l);RAtomicLong atomicLong = redissonClient.getAtomicLong(key);if (!atomicLong.isExists()) {atomicLong.set(300l);}while (i == 0) {if (atomicLong.get() > 0) {long l = atomicLong.getAndDecrement();try {Thread.sleep(1000l);} catch (InterruptedException e) {e.printStackTrace();}i --;System.out.println(Thread.currentThread().getName() + "->" + i + "->" + l);}}}@GetMapping("/rw/get")public String rw_get(){String key = "S_COUNT";Runnable r = new Runnable() {@Overridepublic void run() {RAtomicLong atomicLong = redissonClient.getAtomicLong(key);if (!atomicLong.isExists()) {atomicLong.set(300l);}if (atomicLong.get() > 0) {long l = atomicLong.getAndDecrement();i --;System.out.println(Thread.currentThread().getName() + "->" + i + "->" + l);}}};while (i != 0) {new Thread(r).start();
//            new Thread(r).run();
//            new Thread(r).run();
//            new Thread(r).run();
//            new Thread(r).run();}RBucket bucket = redissonClient.getBucket(key);String s = bucket.get();System.out.println("================线程已结束================================" + s);return s;}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章