0

0

如何使用Java连接Redis数据库 Java连接Redis的实现方式

看不見的法師

看不見的法師

发布时间:2025-07-21 11:44:02

|

979人浏览过

|

来源于php中文网

原创

java连接redis的核心解决方案是使用jedis或lettuce客户端库;1. 引入客户端依赖,2. 创建客户端实例,3. 执行redis命令,4. 关闭连接;jedis简单易用适合低并发场景,lettuce基于netty支持异步和反应式编程,适合高并发应用;连接池通过复用连接提升性能、管理资源、增强稳定性,配置需关注最大/最小连接数、空闲检查等;常见问题包括连接泄露、不合理配置、大key操作等,优化策略涵盖使用连接池、批量操作、高效序列化、合理数据结构选择等。

如何使用Java连接Redis数据库 Java连接Redis的实现方式

Java连接Redis数据库,核心在于利用其官方或社区维护的客户端库。最主流且功能强大的选择当属Jedis和Lettuce,它们为Java应用提供了与Redis服务器进行高效数据交互的API。通过这些库,我们可以轻松地建立连接、执行各类Redis命令,从而实现数据的存取、管理等操作。

如何使用Java连接Redis数据库 Java连接Redis的实现方式

解决方案

要实现Java与Redis的连接,通常你需要以下几个步骤:

  1. 引入客户端库依赖: 在你的项目(如Maven或Gradle)中添加Jedis或Lettuce的依赖。
  2. 创建客户端实例: 根据选择的客户端库,创建相应的连接对象。
  3. 执行Redis命令: 使用客户端实例提供的方法,执行如SET、GET、LPUSH、HSET等Redis命令。
  4. 关闭连接: 使用完毕后,务必关闭连接,释放资源,尤其是在非连接池模式下。

使用Jedis连接Redis示例:

立即学习Java免费学习笔记(深入)”;

如何使用Java连接Redis数据库 Java连接Redis的实现方式
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisExample {

    // 通常生产环境会使用连接池
    private static JedisPool jedisPool;

    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(100); // 最大连接数
        poolConfig.setMaxIdle(20);  // 最大空闲连接数
        poolConfig.setMinIdle(5);   // 最小空闲连接数
        poolConfig.setTestOnBorrow(true); // 借用连接时是否测试
        poolConfig.setTestOnReturn(true); // 归还连接时是否测试
        poolConfig.setTestWhileIdle(true); // 空闲时是否测试连接可用性

        // 假设Redis运行在本地,端口6379,无密码
        // 如果有密码,JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379, 2000, "your_password");
        jedisPool = new JedisPool(poolConfig, "localhost", 6379);
    }

    public static void main(String[] args) {
        // 从连接池获取一个连接
        try (Jedis jedis = jedisPool.getResource()) {
            // 设置一个键值对
            jedis.set("mykey", "Hello Redis from Jedis!");
            System.out.println("设置键值对:mykey = " + jedis.get("mykey"));

            // 列表操作
            jedis.lpush("mylist", "value1", "value2", "value3");
            System.out.println("列表内容:mylist = " + jedis.lrange("mylist", 0, -1));

            // Hash操作
            jedis.hset("myhash", "field1", "valueA");
            jedis.hset("myhash", "field2", "valueB");
            System.out.println("Hash内容:myhash = " + jedis.hgetAll("myhash"));

        } catch (Exception e) {
            System.err.println("Jedis操作失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 在try-with-resources结构中,连接会自动关闭并返回池中
            // 如果不是try-with-resources,需要手动 jedis.close();
        }

        // 应用关闭时,关闭连接池
        // jedisPool.close();
    }
}

使用Lettuce连接Redis示例 (以同步API为例,Lettuce更强大之处在于其异步和反应式API):

import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

public class LettuceExample {
    public static void main(String[] args) {
        // 创建RedisClient实例
        // 如果有密码:RedisClient redisClient = RedisClient.create("redis://password@localhost:6379/0");
        RedisClient redisClient = RedisClient.create("redis://localhost:6379/0");

        // 建立连接
        StatefulRedisConnection<String, String> connection = redisClient.connect();

        // 获取同步命令API
        RedisCommands<String, String> syncCommands = connection.sync();

        try {
            // 设置一个键值对
            syncCommands.set("anotherkey", "Hello Redis from Lettuce!");
            System.out.println("设置键值对:anotherkey = " + syncCommands.get("anotherkey"));

            // 列表操作
            syncCommands.lpush("anotherlist", "item1", "item2");
            System.out.println("列表内容:anotherlist = " + syncCommands.lrange("anotherlist", 0, -1));

        } catch (Exception e) {
            System.err.println("Lettuce操作失败:" + e.getMessage());
            e.printStackTrace();
        } finally {
            // 关闭连接
            connection.close();
            // 关闭RedisClient
            redisClient.shutdown();
        }
    }
}

为什么选择Jedis或Lettuce?它们各自的优势是什么?

在Java生态中连接Redis,Jedis和Lettuce无疑是两座大山。我个人觉得,选择哪一个,很大程度上取决于你的项目需求、团队偏好以及你对异步编程的接受程度。

如何使用Java连接Redis数据库 Java连接Redis的实现方式

Jedis 就像一个老朋友,它非常直观和简单。它的API设计几乎是Redis命令的直接映射,所以如果你熟悉Redis命令,上手Jedis会非常快。它是一个阻塞式客户端,这意味着当你执行一个命令时,线程会一直等待直到命令执行完成并返回结果。对于一些简单的、并发量不那么高的应用,或者快速原型开发,Jedis用起来简直不要太舒服。它的连接池(JedisPool)也相当成熟,能很好地管理连接资源。但如果你的应用并发量非常大,并且对响应时间极其敏感,阻塞式的特性可能会成为瓶颈,因为一个线程在等待Redis响应时无法做其他事情。

Lettuce 则更像一个现代的、性能优异的跑车。它是基于Netty构建的,支持非阻塞I/O,这意味着它能够以更少的线程处理更多的并发请求。Lettuce原生支持异步操作,你可以用CompletableFuture来处理结果,甚至可以与RxJava或Project Reactor这样的反应式编程框架无缝集成。这对于构建高性能、高并发的微服务应用来说,简直是量身定制。在我看来,如果你正在构建一个Spring WebFlux应用,或者需要处理海量的并发请求,Lettuce几乎是唯一的选择。当然,它的学习曲线相比Jedis会稍微陡峭一些,异步编程的思维模式需要一点时间来适应。不过,一旦你掌握了,你会发现它的强大和灵活性是Jedis无法比拟的。

总的来说,如果你追求简单、快速开发,并且对性能要求没那么极致,Jedis是个不错的选择。而如果你需要构建一个高性能、可扩展、反应式的应用,或者你的项目已经在使用Spring Boot 2.x+和Spring Data Redis,那么Lettuce无疑是更优的方案。

ShopEx助理
ShopEx助理

一个类似淘宝助理、ebay助理的客户端程序,用来方便的在本地处理商店数据,并能够在本地商店、网上商店和第三方平台之间实现数据上传下载功能的工具。功能说明如下:1.连接本地商店:您可以使用ShopEx助理连接一个本地安装的商店系统,这样就可以使用助理对本地商店的商品数据进行编辑等操作,并且数据也将存放在本地商店数据库中。默认是选择“本地未安装商店”,本地还未安

下载

连接池在Java连接Redis中扮演什么角色?如何配置?

连接池在Java连接Redis中扮演的角色,我用一个比喻来说,就像是你在一个繁忙的餐厅里,不需要每次点餐都重新建一个厨房。它管理着一批预先创建好的、随时可用的Redis连接。每次你需要与Redis交互时,不是新建一个连接,而是从池子里“借”一个现成的连接来用;用完之后,再把连接“还”回池子。

它的核心作用主要有几点:

  1. 性能提升: 创建和销毁TCP连接是一个相对耗时的操作。连接池避免了频繁的连接建立和关闭,显著减少了这部分开销,从而提升了应用的整体性能和响应速度。
  2. 资源管理: 它限制了同时打开的连接数量,防止应用因为创建过多连接而耗尽服务器资源(如文件描述符),或者导致Redis服务器过载。
  3. 稳定性: 连接池通常会包含连接的健康检查机制,比如在借出连接前或归还连接后测试连接的可用性,确保你拿到的都是“活的”连接。这有助于提高应用的稳定性。
  4. 减少延迟: 由于连接是预先建立的,省去了连接建立的握手时间,每次操作的延迟会更低。

如何配置连接池?

以Jedis为例,配置连接池主要通过JedisPoolConfig类和JedisPool来实现。

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolConfigExample {
    public static void main(String[] args) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();

        // 最大连接数:池中“最多”有多少个连接
        // 我通常会根据服务器的CPU核数、Redis的并发能力以及应用自身的并发量来估算这个值。
        poolConfig.setMaxTotal(100);

        // 最大空闲连接数:池中“最多”有多少个空闲连接
        // 太多可能浪费资源,太少可能在高峰期需要频繁创建新连接。
        poolConfig.setMaxIdle(20);

        // 最小空闲连接数:池中“至少”保留多少个空闲连接
        // 保证在低峰期也有足够的连接立即可用,避免冷启动时的连接创建延迟。
        poolConfig.setMinIdle(5);

        // 当连接池耗尽时,是否阻塞等待可用连接。
        // 如果设置为true,会阻塞直到有连接可用或达到maxWaitMillis。
        // 如果设置为false,则会立即抛出异常。我个人倾向于阻塞,但要设置合理的maxWaitMillis。
        poolConfig.setBlockWhenExhausted(true);

        // 当连接池耗尽时,阻塞等待可用连接的最长时间(毫秒)。
        poolConfig.setMaxWaitMillis(2000); // 等待2秒

        // 借用连接时,是否测试连接的可用性。
        // 开启可以保证拿到的连接是健康的,但会有轻微性能开销。
        poolConfig.setTestOnBorrow(true);

        // 归还连接时,是否测试连接的可用性。
        // 开启可以确保归还的连接是健康的,但同样有开销。
        poolConfig.setTestOnReturn(false); // 通常不开启,因为借出时已经测试过

        // 空闲连接检查:空闲连接是否需要周期性地测试可用性。
        // 这是防止连接长时间空闲后被Redis服务器关闭(如timeout)的关键。
        poolConfig.setTestWhileIdle(true);
        // 两次空闲连接测试之间的最小间隔时间(毫秒)。
        poolConfig.setMinEvictableIdleTimeMillis(60000L); // 60秒
        // 空闲连接驱逐线程的运行间隔时间(毫秒)。
        poolConfig.setTimeBetweenEvictionRunsMillis(30000L); // 30秒
        // 每次空闲连接驱逐时,检查的连接数量。
        poolConfig.setNumTestsPerEvictionRun(3);

        // 创建JedisPool实例
        // 假设Redis在localhost:6379,没有密码
        JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);

        // 实际使用时,从池中获取连接
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.set("test_pool_key", "value_from_pool");
            System.out.println("从连接池获取并设置值:" + jedis.get("test_pool_key"));
        } catch (Exception e) {
            System.err.println("连接池操作失败:" + e.getMessage());
        } finally {
            // 应用关闭时,务必关闭连接池
            // jedisPool.close();
        }
    }
}

对于Lettuce,虽然它底层也管理连接,但其连接管理方式与Jedis的传统连接池有所不同,它更倾向于单个RedisClient实例管理多个StatefulRedisConnection,并且推荐使用ClientResources来配置线程模型等。在Spring Data Redis中,这些复杂的连接管理和池化配置通常会被更高层次的抽象(如LettuceConnectionFactory)所封装,让你无需直接面对复杂的底层配置。

连接Redis时常见的坑和性能优化策略有哪些?

在Java应用连接Redis的过程中,我见过不少团队踩过一些坑,也总结了一些行之有效的优化策略。很多时候,我们总觉得Redis慢是Redis本身的问题,但实际上,客户端侧的细节,比如连接管理、序列化,甚至网络配置,才是真正的性能杀手。

常见的“坑”:

  1. 未关闭连接或连接泄露: 这是最常见的,也是最致命的问题之一。如果每次操作都新建连接而不关闭,或者从连接池借出连接后没有正确归还,最终会导致连接耗尽,应用无法再连接到Redis,甚至Redis服务器也会因为连接数过多而崩溃。try-with-resources语句块是Java中解决这个问题的优雅方式。
  2. 不合理的连接池配置: maxTotal设置过小会导致连接不够用,应用阻塞;maxIdle设置过大可能浪费资源;testOnBorrowtestWhileIdle不开启,可能拿到“死”连接。没有根据实际负载进行调优,连接池反而成了性能瓶颈。
  3. 序列化问题: Java对象直接存入Redis,默认的Java序列化(Serializable接口)效率低、体积大,且与非Java客户端不兼容。这不仅浪费存储空间,还增加了网络传输开销。
  4. 大Key/大Value问题: 单个Key存储的Value过大(比如几MB甚至几十MB),或者一个Hash、List、Set、ZSet中包含的元素过多,都会严重影响Redis的性能。大Key的读写会阻塞Redis服务器,导致其他命令延迟。
  5. N+1查询问题: 类似数据库的N+1问题,如果需要获取多个Key的值,却循环地一个一个去GET,而不是批量操作,会导致大量的网络往返时间(RTT),性能极差。
  6. 阻塞式操作滥用: 尤其是在Jedis这类阻塞式客户端中,如果执行了耗时的Redis命令(如KEYS、FLUSHALL),或者在单线程环境下进行了大量同步操作,会导致整个应用线程阻塞。
  7. 网络延迟: 客户端与Redis服务器部署距离过远,网络延迟(RTT)高,每次命令的响应时间都会增加。

性能优化策略:

  1. 使用连接池: 这是基石,务必正确配置并使用。它能有效管理连接生命周期,避免频繁创建销毁连接的开销。
  2. 选择合适的客户端: 根据并发量、是否需要异步/反应式编程模型等因素,合理选择Jedis或Lettuce。对于高并发场景,Lettuce的非阻塞特性优势明显。
  3. 批量操作 (Pipelining/Transactions): 这是减少网络RTT的“银弹”。如果你需要执行多个独立的Redis命令,将它们打包成一个Pipeline一次性发送给Redis,Redis会一次性返回所有结果。这能显著提高吞吐量。对于需要原子性的操作,可以使用Redis事务(MULTI/EXEC)。
    // Jedis Pipelining 示例
    try (Jedis jedis = jedisPool.getResource()) {
        Pipeline pipeline = jedis.pipelined();
        pipeline.set("key1", "value1");
        pipeline.get("key1");
        pipeline.lpush("mylist", "a", "b", "c");
        Response<String> getResponse = pipeline.get("key1");
        Response<List<String>> lrangeResponse = pipeline.lrange("mylist", 0, -1);
        pipeline.sync(); // 执行所有命令并获取结果
        System.out.println("Pipeline GET: " + getResponse.get());
        System.out.println("Pipeline LRANGE: " + lrangeResponse.get());
    }
  4. 合理序列化: 不要使用Java默认序列化。推荐使用JSON (如Jackson、Gson)、Protobuf、Kryo等高效、跨语言的序列化框架。它们能显著减小数据体积,提高传输效率。
  5. 小Key/小Value原则: 尽量避免大Key。对于大对象,考虑拆分成多个小Key,或者使用Redis的Hash结构来存储对象的多个字段。例如,一个用户信息对象,可以将其各个字段作为Hash的field-value对存储,而不是整个对象序列化后作为String存储。
  6. 充分利用Redis数据结构: Redis提供了String、Hash、List、Set、Sorted Set等多种数据结构。根据业务场景选择最合适的数据结构,能大大提高操作效率。比如存储用户会话信息用Hash,存储排行榜用Sorted Set。
  7. 读写分离/集群: 对于非常高的并发场景,可以考虑部署Redis主从架构实现读写分离,或者使用Redis Cluster集群来分摊负载和提高可用性。
  8. 监控和日志: 实时监控Redis服务器的性能指标(如CPU、内存、连接数、QPS、慢查询日志)和应用侧的Redis客户端性能,结合详细的日志,能够帮助你快速定位和解决问题。

很多时候,性能瓶颈并不在Redis本身,而是在于我们如何使用它。深入理解Redis的特性和客户端库的工作原理,并结合实际业务场景进行优化,才能真正发挥Redis的强大能力。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

155

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

88

2026.01.26

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

139

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

408

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

73

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

147

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

271

2025.12.24

Spring Boot企业级开发与MyBatis Plus实战
Spring Boot企业级开发与MyBatis Plus实战

本专题面向 Java 后端开发者,系统讲解如何基于 Spring Boot 与 MyBatis Plus 构建高效、规范的企业级应用。内容涵盖项目架构设计、数据访问层封装、通用 CRUD 实现、分页与条件查询、代码生成器以及常见性能优化方案。通过完整实战案例,帮助开发者提升后端开发效率,减少重复代码,快速交付稳定可维护的业务系统。

32

2026.02.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 7.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号