欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Redis之在Java中使用

程序员文章站 2022-07-10 19:13:03
在本篇中主要是代码演示,演示三种客户端连接三种模式下的redis的方式,可以帮助大家快速学习和使用redis...

操作系统:CentOS-7.8
Redis版本:6.0.5
SpringBoot 2.1.5.RELEASE
Java Version 1.8.0_231

本篇内容主要演示在Java代码中连接和使用Redis,对Redis不熟悉的朋友可以先看前两篇《一起学习Redis基础》《一起学习Redis高可用》,本篇涉及到的代码完整版github地址为:https://github.com/telundusiji/dream-hammer/tree/master/module-6

一、使用Redis客户端

Jedis、Redisson和Lettuce都是比较常用的支持连接Redis的客户端,所以在这里我们主要演示这三种客户端如何连接不同的redis模式的redis

1.Jedis

Jedis特点

  • 比较经典的Redis的Java客户端,对Redis的命令支持比较全面

  • 比较轻量和简洁,对其进行改造和集成比较方便

  • 不支持异步,方法调用都是同步的,使用的阻塞IO

  • 客户端实例非线程安全,多线程并发场景下,需要通过连接池来使用客户端

  • 早期版本Spring的默认客户端

使用演示

  • pom依赖

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.3</version>
</dependency>

  • Jedis连接单机单实例Redis

import redis.clients.jedis.Jedis;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class SingleInstanceJedis {


    private String host;
    private Integer port;
    private String password;

    /**
     * 连接单机单实例的redis
     *
     * @param host     redis主机地址
     * @param port     redis服务端口
     * @param password redis认证密码
     */
    public SingleInstanceJedis(String host, Integer port, String password) {
        this.host = host;
        this.port = port;
        this.password = password;
    }

    /**
     * 连接redis
     *
     * @return 一个Jedis客户端
     */
    public Jedis connect() {
        Jedis jedis = new Jedis(host, port);
        jedis.auth(password);
        return jedis;
    }

}


  • Jedis连接哨兵模式Redis

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;

import java.util.Set;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class SentinelJedis {

    private JedisSentinelPool jedisSentinelPool;

    /**
     * 连接哨兵模式的redis
     *
     * @param masterName redis的master名称
     * @param sentinels  哨兵的主机和端口信息
     * @param password   redis的认证密码
     */
    public SentinelJedis(String masterName, Set<String> sentinels, String password) {
        //根据redis的信息创建一个redis哨兵的连接池
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        config.setMinIdle(5);
        jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, password);
    }

    /**
     * 从连接池中取出一个客户端
     *
     * @return 获取一个Jedis客户端
     */
    public Jedis connect() {
        return jedisSentinelPool.getResource();
    }

    /**
     * 销毁连接池
     */
    public void close() {
        jedisSentinelPool.close();
        jedisSentinelPool.destroy();
    }
}


  • Jedis连接集群模式Redis

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.Set;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class ClusterJedis {

    private Set<HostAndPort> redisNodes;
    private String password;
    private GenericObjectPoolConfig config;

    /**
     * 连接redis cluster
     *
     * @param redisNodes 集群中redis节点信息
     * @param password   redis 密码
     */
    public ClusterJedis(Set<HostAndPort> redisNodes, String password) {
        this.redisNodes = redisNodes;
        this.password = password;
        config = new GenericObjectPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        config.setMinIdle(5);
    }

    /**
     * 连接redis cluster
     *
     * @return 一个redis cluster客户端
     */
    public JedisCluster connect() {
        JedisCluster jedisCluster = new JedisCluster(redisNodes, 10000, 10000, 3, password, config);
        return jedisCluster;
    }

}


以上三段代码是使用Jedis连接三种模式下Redis的简易演示代码,下面再附上测试类代码

  • 测试类

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */

public class JedisTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(JedisTest.class);
    private static final String TEST_KEY = "jedis";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void singleInstance() {
        SingleInstanceJedis singleInstanceJedis = new SingleInstanceJedis("192.168.56.90", 6379, "123456");
        Jedis jedis = singleInstanceJedis.connect();
        jedis.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis单机单实例:{}", jedis.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedis.get(TEST_KEY));
    }

    @Test
    public void sentinel() {
        Set<String> sentinels = new HashSet<>();
        sentinels.add("192.168.56.91:26379");
        sentinels.add("192.168.56.92:26379");
        sentinels.add("192.168.56.93:26379");
        SentinelJedis sentinelJedis = new SentinelJedis("redis-master", sentinels, "123456");
        Jedis jedis = sentinelJedis.connect();
        jedis.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis哨兵模式:{}", jedis.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedis.get(TEST_KEY));
    }

    @Test
    public void cluster() {
        Set<HostAndPort> redisNodes = new HashSet<>();
        redisNodes.add(new HostAndPort("192.168.56.81",6379));
        redisNodes.add(new HostAndPort("192.168.56.82",6379));
        redisNodes.add(new HostAndPort("192.168.56.83",6379));
        redisNodes.add(new HostAndPort("192.168.56.84",6379));
        redisNodes.add(new HostAndPort("192.168.56.85",6379));
        redisNodes.add(new HostAndPort("192.168.56.86",6379));
        ClusterJedis clusterJedis = new ClusterJedis(redisNodes, "123456");
        JedisCluster jedisCluster = clusterJedis.connect();
        jedisCluster.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("jedis集群模式:{}", jedisCluster.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE, jedisCluster.get(TEST_KEY));
    }
}


2.Redisson

Redisson特点

  • 基于Netty实现,使用非阻塞IO,支持异步,性能高

  • API是线程安全的,可以操作单个Redisson连接来完成多种操作

  • 实现多种分布式和可扩展的Java数据结构,例如,分布式锁,分布式集合,可通过Redis支持延迟队列

  • Redisson注重分布式和锁的相关功能,所以在基础功能上较为简单,不支持Redis的原生命令操作,比如不支持字符串操作等

使用演示

  • pom依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.5</version>
</dependency>

  • redisson连接单机单实例Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class SingleInstanceRedisson {

    private Config config;

    /**
     * 连接单机单实例的redis
     *
     * @param host     redis主机地址
     * @param port     redis 端口
     * @param password redis密码
     */
    public SingleInstanceRedisson(String host, Integer port, String password) {
        config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + host + ":" + port)
                .setPassword(password);

    }

    /**
     * 连接redis
     *
     * @return 一个RedissonClient客户端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
}


  • redisson连接哨兵模式Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class SentinelRedisson {

    private Config config;

    /**
     * 连接哨兵模式redis
     *
     * @param masterName redis的master名称
     * @param sentinels  哨兵的连接信息 redis://sentinelHost:sentinelPort
     * @param password   redis密码
     */
    public SentinelRedisson(String masterName, String[] sentinels, String password) {
        config = new Config();
        config.useSentinelServers()
                .setMasterName(masterName)
                .addSentinelAddress(sentinels)
                .setPassword(password);

    }

    /**
     * 连接redis
     *
     * @return 一个RedissonClient客户端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

}


  • redisson连接集群模式Redis

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/17
 */
public class ClusterRedisson {

    private Config config;

    /**
     * 连接cluster模式的redis
     *
     * @param redisNodes redis集群中节点信息 redis://nodeHost:nodePort
     * @param password   redis密码
     */
    public ClusterRedisson(String[] redisNodes, String password) {
        config = new Config();
        config.useClusterServers()
                .addNodeAddress(redisNodes)
                .setPassword(password);

    }

    /**
     * 连接redis
     *
     * @return 一个RedissonClient客户端
     */
    public RedissonClient connect() {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

}


以上三段代码是使用Redisson连接三种模式下Redis的简易演示代码,下面再附上测试类代码

  • 测试类

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
public class RedissonTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedissonTest.class);
    private static final String TEST_KEY = "redisson";
    private static final long TEST_VALUE = 100L;

    @Test
    public void singleInstance() {
        SingleInstanceRedisson singleInstanceRedisson = new SingleInstanceRedisson("192.168.56.90", 6379, "123456");
        RedissonClient redissonClient = singleInstanceRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson单机单实例:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }

    @Test
    public void sentinel() {
        String[] sentinels = new String[]{"redis://192.168.56.91:26379", "redis://192.168.56.92:26379", "redis://192.168.56.93:26379"};
        SentinelRedisson sentinelRedisson = new SentinelRedisson("redis-master", sentinels, "123456");
        RedissonClient redissonClient = sentinelRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson哨兵模式:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }

    @Test
    public void cluster() {
        String[] redisNodes = new String[]{
                "redis://192.168.56.81:6379",
                "redis://192.168.56.82:6379",
                "redis://192.168.56.83:6379",
                "redis://192.168.56.84:6379",
                "redis://192.168.56.85:6379",
                "redis://192.168.56.86:6379"
        };
        ClusterRedisson clusterRedisson = new ClusterRedisson(redisNodes, "123456");
        RedissonClient redissonClient = clusterRedisson.connect();
        RAtomicLong atomicLong = redissonClient.getAtomicLong(TEST_KEY);
        atomicLong.set(TEST_VALUE);
        LOGGER.info("redisson集群模式:{}", redissonClient.getAtomicLong(TEST_KEY).get());
        Assert.assertEquals(TEST_VALUE, redissonClient.getAtomicLong(TEST_KEY).get());
    }
}


3.Lettuce

Lettuce特点

  • Redis高级客户端,线程安全的,单个Lettuce连接可以在多个线程中操作

  • 基于Netty实现,使用非阻塞IO,支持异步

  • 对Redis基础操作支持全面,相对Jedis来说更加高效,不要考虑太多线程安全问题

  • 相对Redisson来说分布式锁和分布式数据结构等都需要自行实现

  • Spring现有版本的默认redis客户端

使用演示

  • pom依赖

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

  • lettuce连接单机单实例Redis

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulRedisConnection;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
public class SingleInstanceLettuce {

    private RedisURI redisURI;

    /**
     * 使用Lettuce连接单机单实例的redis
     * @param host redis的主机地址
     * @param port redis的端口号
     * @param password redis的密码
     */
    public SingleInstanceLettuce(String host, Integer port, String password) {
        redisURI = RedisURI.builder()
                .withHost(host)
                .withPort(port)
                .withPassword(password)
                .build();
    }

    /**
     * 连接redis获取一个连接
     * @return 一个redis连接
     */
    public StatefulRedisConnection<String, String> connect() {
        RedisClient redisClient = RedisClient.create(redisURI);
        StatefulRedisConnection<String, String> connect = redisClient.connect();
        return connect;
    }
}


  • lettuce连接哨兵模式redis

import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.codec.Utf8StringCodec;
import io.lettuce.core.masterslave.MasterSlave;
import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection;

import java.util.List;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
public class SentinelLettuce {
    private List<RedisURI> redisURIList;

    /**
     * 连接哨兵模式的redis
     * @param redisURIList 哨兵模式redis下的哨兵的信息,建议使用RedisURI.builder.sentinel填写哨兵信息来进行构造
     */
    public SentinelLettuce(List<RedisURI> redisURIList) {
        this.redisURIList = redisURIList;
    }

    /**
     * 连接redis获取一个连接
     * @return 一个redis的连接
     */
    public StatefulRedisMasterSlaveConnection<String, String> connect() {
        RedisClient redisClient = RedisClient.create();
        StatefulRedisMasterSlaveConnection<String, String> connect = MasterSlave.connect(redisClient, new Utf8StringCodec(), redisURIList);
        return connect;
    }
}


  • lettuce连接集群模式Redis

import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;

import java.util.List;

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
public class ClusterLettuce {

    private List<RedisURI> redisURIList;

    /**
     * 使用Lettuce连接集群模式redis
     * @param redisURIList 集群中redis节点的信息,建议使用RedisURI.builder来进行构造
     */
    public ClusterLettuce(List<RedisURI> redisURIList) {
        this.redisURIList = redisURIList;
    }

    /**
     * 连接redis获取一个连接
     * @return 一个redis的连接
     */
    public StatefulRedisClusterConnection<String, String> connect() {
        RedisClusterClient redisClusterClient = RedisClusterClient.create(redisURIList);
        StatefulRedisClusterConnection<String, String> connect = redisClusterClient.connect();
        return connect;
    }


}

以上三段代码是使用Lettuce连接三种模式下Redis的简易演示代码,下面再附上测试类代码

  • 测试类

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
public class LettuceTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(LettuceTest.class);
    private static final String TEST_KEY = "lettuce";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void SingleInstance(){
        SingleInstanceLettuce singleInstanceLettuce = new SingleInstanceLettuce("192.168.56.90", 6379, "123456");
        StatefulRedisConnection<String, String> connection = singleInstanceLettuce.connect();
        RedisCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce单机单实例:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

    @Test
    public void sentinel(){
        List<RedisURI> redisURIList = new ArrayList<>();
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.91",26379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.92",26379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withSentinelMasterId("redis-master").withSentinel("192.168.56.93",26379).withPassword("123456").build());
        SentinelLettuce sentinelLettuce = new SentinelLettuce(redisURIList);
        StatefulRedisMasterSlaveConnection<String, String> connection = sentinelLettuce.connect();
        RedisCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce哨兵模式:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

    @Test
    public void cluster(){
        List<RedisURI> redisURIList = new ArrayList<>();
        redisURIList.add(RedisURI.builder().withHost("192.168.56.81").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.82").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.83").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.84").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.85").withPort(6379).withPassword("123456").build());
        redisURIList.add(RedisURI.builder().withHost("192.168.56.86").withPort(6379).withPassword("123456").build());
        ClusterLettuce clusterLettuce = new ClusterLettuce(redisURIList);
        StatefulRedisClusterConnection<String, String> connection = clusterLettuce.connect();
        RedisAdvancedClusterCommands<String, String> commands = connection.sync();
        commands.set(TEST_KEY, TEST_VALUE);
        LOGGER.info("lettuce集群模式:{}",commands.get(TEST_KEY));
        Assert.assertEquals(TEST_VALUE,commands.get(TEST_KEY));
    }

}


二、在SpringBoot中使用Redis

在上一部分我们演示了直接使用不同的redis客户端连接Redis,并进行简单操作,在这一部分,我们将演示一下,在SpringBoot如何连接三种模式的redis

  • pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

  • 在application.yml文件中配置redis连接信息

# 连接单机单实例版的redis配置
spring:
  redis:
    host: 192.168.56.90
    port: 6379
    password: 123456
    database: 0

# 连接哨兵模式的redis配置
spring:
  redis:
    sentinel:
      master: redis-master
      nodes: 192.168.56.91:26379,192.168.56.92:26379,192.168.56.92:26379
    password: 123456
   
# 连接集群模式redis配置
spring:
  redis:
    cluster:
      nodes: 192.168.56.81:6379,192.168.56.82:6379,192.168.56.83:6379,192.168.56.84:6379,192.168.56.85:6379,192.168.56.86:6379
    password: 123456

  • 使用演示代码

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
@Service("redisSpring")
public class RedisSpring {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public Object redisTemplateOperate(Object key, Object value) {
        redisTemplate.opsForValue().set(key, value);
        return redisTemplate.opsForValue().get(key);
    }

    public String stringRedisTemplateOperate(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
        return stringRedisTemplate.opsForValue().get(key);
    }

}

  • 测试该功能的代码

/**
 * @author 爱做梦的锤子
 * @create 2020/7/20
 */
@SpringBootTest(classes = Application.class)
@RunWith(SpringRunner.class)
@EnableAutoConfiguration
public class SpringTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringTest.class);

    @Autowired
    private RedisSpring redisSpring;

    private static final String TEST_KEY = "spring";
    private static final String TEST_VALUE = "dream-hammer";

    @Test
    public void test() {
        Object value = redisSpring.redisTemplateOperate(TEST_KEY, TEST_VALUE);
        LOGGER.info("redisTemplate:{}",value);
        Assert.assertEquals(value,TEST_VALUE);
        String s = redisSpring.stringRedisTemplateOperate(TEST_KEY, TEST_VALUE);
        LOGGER.info("stringRedisTemplate:{}",s);
        Assert.assertEquals(TEST_VALUE,s);
    }

}

总结

在本篇中主要是代码演示,演示三种客户端连接三种模式下的redis的方式,可以帮助大家快速学习和使用redis。由于本篇代码比较多,所以代码锤子也传到了github地址为:https://github.com/telundusiji/dream-hammer/tree/master/module-6

个人公众号【爱做梦的锤子】,全网同id,个站 http://te-amo.site,欢迎关注,里面会分享更多有用知识

觉得不错就点个赞叭QAQ

本文地址:https://blog.csdn.net/telundusiji/article/details/107491732

相关标签: redis java