第四章 Redis(2023版本IDEA)

学习目标

Redis是一个高性能的缓存数据库,能够在高并发场景下为应用提供高效的数据访问能力,因而在各类互联网应用中被广泛运用。(如果没有了解可以去我主页看看Java开发之框架基础技术第1-3章(2023版本IEDA)来学习)本章将学习Redis服务的安装、配置及使用,并介绍如何将Redis与java应用相结合,从而极大地提高java应用的数据访问效率。

4.1 Redis简介

在Java中操作Redis,你通常会使用Jedis或Lettuce这样的客户端库。这里我将提供一个使用Jedis库的简单示例,来展示如何在Java中与Redis进行基本的交互,如连接Redis服务器、设置和获取键值对等。

首先,你需要在你的Java项目中包含Jedis库。如果你使用Maven作为构建工具,可以在你的pom.xml文件中添加以下依赖:

xml 复制代码
<dependency>  
    <groupId>redis.clients</groupId>  
    <artifactId>jedis</artifactId>  
    <version>最新版本号</version> <!-- 请替换为发布时的最新版本号 -->  
</dependency>

请注意,你应该检查并使用发布时的最新版本号。

以下是一个使用Jedis的Java示例代码:

java 复制代码
import redis.clients.jedis.Jedis;  
  
public class RedisExample {  
  
    public static void main(String[] args) {  
        // 连接到Redis服务器  
        // 假设Redis服务器运行在本地,默认端口6379,没有设置密码  
        try (Jedis jedis = new Jedis("localhost", 6379)) {  
            // 认证(如果Redis服务器设置了密码)  
            // jedis.auth("yourpassword");  
  
            // 设置键值对  
            String key = "name";  
            String value = "John Doe";  
            jedis.set(key, value);  
  
            // 获取键值对  
            String name = jedis.get(key);  
            System.out.println("Name: " + name);  
  
            // 其他操作...  
  
            // 示例:使用哈希类型  
            String hashKey = "user:1";  
            jedis.hset(hashKey, "username", "johndoe");  
            jedis.hset(hashKey, "email", "[email protected]");  
  
            String username = jedis.hget(hashKey, "username");  
            System.out.println("Username: " + username);  
  
            // 关闭连接(在try-with-resources语句中自动完成)  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}

在这个示例中,我们首先创建了一个Jedis实例来连接到Redis服务器。然后,我们使用set和get方法分别来设置和获取一个简单的字符串类型的键值对。接下来,我们还展示了如何使用哈希类型(hset和hget)来存储和检索更复杂的数据结构。

请注意,由于Jedis实例被创建在try-with-resources语句中,因此当代码执行完毕后,它会自动关闭连接,释放资源。这是一种处理资源的好方法,可以确保即使发生异常也能正确关闭连接。

如果你需要连接到设置了密码的Redis服务器,你可以在创建Jedis实例后调用auth方法,并传入你的密码作为参数。然而,在大多数开发环境中,你可能更倾向于在Redis的配置文件中或通过命令行参数来设置密码,并在连接时自动进行身份验证。但在某些情况下,你可能需要在代码中动态处理密码。

4.2 Linux环境Redis安装及配置

4.2.1 Redis服务的安装环境

  • 服务器操作系统CentOS 6.5 64位。
  • Redis 版本:3.2.8。

4.2.2 安装Redis

Redis的官网地址是http://redis.io

将下载的redis文件通过FTP工具复制至Linux服务器的某目录(如/usr/local/share/applications)在/usr/local/share/applications目录下解压Redis压缩包,得到包含安装文件的Redis-3.2.8目录。

命令:

  1. tar -zxvf redis-3.2.8.tar.gz

进入redis-3.2.8目录,执行编译和安装命令

命令:

root@iz7xv7wh4c9vf6zwkqgla7z applications\]# cd redis-3.2.8 \[root@iz7xv7wh4c9vf6zwkqgla7z redis-3.2.8\]# make PREFIX=/usr/loca/redis-3.2.8 install 注意   (1)PREFIX参数是配置安装时的顶级目录名,一般而言,如果不配置,该选项默认为usr/local,安装后可执行文件默认放在/usr/local/bin中,库文件默认放在/usr/local/lib中,配置文件默认放在/usr/local/etc中,其他的资源文件则放在/usr/local/share中,各类文件的放置位置比较分散。上述命令通过配置PREFIX参,指定将存放各类文件的目录都集中创建在/usr/local/redis-3.2.8目录中。   (2)由于安装操作系统时所选择的组件可能不同,因此在安装过程中可能会出现gcc命令未找到错误提示,解决办法为安装gcc-c++组件。 命令: 1- yum -y install gcc-c++   (3)另外在安装过程中也有可能会出现jemalloc未安装错误提示,解决办法为执行make命令加上MALLOC=libc参数。 命令: 1- make PREFIX=/usr/local/redis-3.2.8 MALLOC=libc install   Malloc的全称为memory allocation,即动态内存分配,Redis默认是针对libc malloc编译和链接的,而Linux操作系统默认使用jemalloc,由于jemalloc未安装,因此这里使用MALLOC参数强制使用libc malloc编译。

4.2.3 配置Redis

为了能够更好地使用Redis服务,安装完成后还需要对Redis进行多方面配置。

配置Redis主要涉及编辑Redis的配置文件(通常是redis.conf),以满足特定的使用需求。以下是一些常见的Redis配置选项及其说明,以及配置Redis的基本步骤。

常见的Redis配置选项

1. 绑定地址(bind):

用于指定Redis服务器监听的IP地址。如果设置为127.0.0.1,则Redis只能接受来自本机的连接。如果设置为0.0.0.0或注释掉此行,则Redis将接受来自任何IP地址的连接。

示例:bind 0.0.0.0 或 # bind 127.0.0.1

2. 端口(port):

Redis服务器监听的端口号,默认为6379。

示例:port 6379

3. 守护进程(daemonize):

用于指定Redis是否以守护进程(即后台进程)运行。设置为yes时,Redis将在后台运行。

示例:daemonize yes

4. 密码(requirepass):

设置访问Redis服务器所需的密码。

示例:requirepass yourpassword

5. 持久化相关配置:

RDB持久化: 通过save指令和dbfilename、dir等配置来控制。

AOF持久化: 通过appendonly、appendfsync等配置来控制。

6. 日志文件(logfile):

指定Redis的日志文件路径。

示例:logfile "/var/log/redis/redis-server.log"

7. 数据库数量(databases):

设置Redis服务器中数据库的数量。

示例:databases 16

配置Redis的基本步骤

1. 找到配置文件:

Redis的配置文件通常名为redis.conf,位于Redis源码包的根目录下或安装后的某个目录中。
2. 编辑配置文件:

使用文本编辑器(如vim、nano等)打开配置文件,并根据需要修改配置项。
3. 启动Redis时指定配置文件:

在启动Redis服务器时,使用--config-file参数(或在某些情况下直接使用配置文件路径作为参数)来指定配置文件。例如:

bash 复制代码
redis-server /path/to/redis.conf

或者,如果Redis服务器已经启动,并且你想要应用新的配置,可以先停止Redis服务器,然后使用新的配置文件重新启动。
4. 验证配置:

启动Redis服务器后,可以使用redis-cli工具连接到Redis服务器,并通过CONFIG GET命令来验证配置项是否已正确应用。例如:

bash 复制代码
redis-cli CONFIG GET requirepass

注意事项

  • 在修改配置文件之前,建议先备份原始配置文件,以防万一配置错误导致Redis无法启动。
  • 某些配置项(如bind、requirepass)的修改可能会影响到Redis的访问权限和安全性,因此在修改这些配置项时需要格外小心。
  • Redis的配置文件支持包含其他配置文件,这可以通过include指令来实现。这有助于将配置分散到多个文件中,使管理更加方便。

通过以上步骤,您可以根据自己的需求对Redis进行配置,以满足特定的使用场景。

1.设置内存分配策略

命令:

  1. echo 1 > /proc/sys/vm/overcommit_memory
    注意

执行该命令需要使用root账户。

2.开发Redis端口

Redis默认占用6379端口,需要在防火墙中设置开放对此端口的访问。步骤如下。

(1)编辑防火墙配置文件。

命令:

1.vim /etc/sysconfig/iptables

(2)添加如下规则。

命令:

  1. -A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

(3)重新加载规则。

命令:

  1. service iptables restart

3.设置Redis配置文件

在安装Redis时,将Redis配置文件redis.conf复制至/usr/local/redis-3.2.8/etc目录下,编程此文件中的配置指令可控制Redis运行时的行为。

命令:

  1. vim/usr/local/redis-3.2.8/etc/redis.conf
  • 设置Redis服务可以监听的请求IP地址。
      使用bind配置指令可以设置监昕一个或多个四地址的请求,多个IP地址用空格分隔,配置方式如下。
  1. bind 127.0.01 ::1

在redis.conf中bind的默认配置为bind 127.0.0.1,表示Redis仅能监听来自本机的IPv4请求,若将其修改为bind 0.0.0.0或使用"#"将bind指令注释掉,则可监听所有IP地址的请求。

  • 设置Redis监听的端口。
    使用port配置指令可以设置Redis监昕的端口,默认是6379.
  • 设置Redis是否作为守护进程运行。

使用daemonize配置指令可以设置Redis是否作为守护进程(即后台服务)运行。在redis.conf中该指令默认设置为daemonize no,即在默认情况下,Redis不作为守护进程,而是作为会话进程运行。在这种情况下,执行Redis启动命令后不会返回到命令提示符,且不能关闭会话,否则Redis服务会停止。如果需要Redis作为守护进程于后台运行,则将其修改为daemonize yes即可。

  • 设置Redis的日志文件路径(编辑redis.conf文件)。
    使用logfile配置指令可以指定Redis的日志文件路径,需要指定到文件名。配置方式如下。
  1. logfile "/usr/local/redis-3.2.8/log/redis.log"
  • 设置Redis数据库的数量。

    使用databases配置指令可以设置Redis数据库的数量,默认设置的数量是16,对应的dbid范围是0~15。连接Redis时可以通过dbid选择要使用的数据库。在不同数据库中可以使用相同名称的key。

    Redis中不同的可选数据库是以命名空间的形式管理的,所有数据库实际上都存储在同一个数据文件中。实际上,Redis划分数据库主要用于在必要的情况下分隔同一应用中存储的key,而不是为了在Redis中区分多个不相关的应用。

  • 设置Redis的工作目录。

    使用dir配置指令可以设置Redis的工作目录,即Redis的数据文件的存储目录。在redis.conf中默认设置为dir./,即在Redis安装目录下。可将其修改至其他路径,配置方式如下。

  1. dir/data/redisdata/
  • 设置Redis的访问密码
      使用requirepass配置指令可以设置Redis的访问密码。在redis.conf中该指令默认为注释状态,即访问Redis服务默认不需要密码。删除该指令前的"#"和空格解除注释,即可设置访问密码,配置方式如下。
  1. requirepass 123456

4.2.4 启动Redis

通过以上的学习,已经安装好了Redis,接下来将学习如何启动Redis服务及如何使用Redis自带的客户端连接Redis。

1. 启动

启动Redis服务需要执行/usr/local/redis-3.2.8/bin目录下的redis-sercer命令。为了便于观察启动/停止Redis服务时的日志信息,可以另外开启一个会话连接至Redis所在的服务器,并在此会话中跟踪Redis日志内容的变化。

命令:

  1. tail -f /usr/local/redis-3.2.8/log/redis.log

回到之前安装、配置Redis的会话窗口中,执行/usr/local/redis-3.2.8/bin目录下的redis-server命令,启动Redis服务。

命令:

  1. cd /usr/local/redis-3.2.8/
  2. ./bin/redis-server ./etc/redis.conf

2.启动Redis客户端

使用redis-server命令启动Redis服务后,即可使用redis-cli命令启动Redis客户端访问Redis服务。

语法

  1. redis-cli [选项]
选项 说明
-h<hostname> 服务器主机地址,默认为127.0.0.1
-p<post> 服务端口,默认为6379
-a<password> Redis服务访问密码
-n<dbid> 所要连接的数据库的id,默认为0

4.3 Redis常用命令

启动Redis客户端后,即可在其中执行Redis的各种操作命令。

4.3.1 Redis常用命令的介绍

auth命令

在访问受密码保护(通过在redis.conf中设置requirepass指令实现)的Redis服务时,客户端首先需要进行密码认证,否则无权执行其他Redis命令。

auth命令用于在受密码保护的Redis服务器中请求进行身份认证。

语法:

  1. auth password

如果password与配置文件中的密码匹配,则服务器将回复"OK"状态代码并开始接收命令,否则将返回错误。

set命令

如前文所述,Redis是以key-value的格式来存储数据的,而set命令即被用来设置key以保存value(string 类型)。

语法

  1. set key value [ex seconds | px milliseconds ] [nx | xx]

set命令的参数介绍如下。

  • ex seconds:设置指定的过期时间seconds,seconds是以秒为单位的数字。
  • px milliseconds:设置指定的过期时间milliseconds,milliseconds是以毫秒为单位的数字。
  • nx:仅在key不存在时设置该key。
  • xx:仅在key已存在是设置该key。

如果set正确执行,则返回字符串"OK" "如果因为用户指定了nx或xx选项但未满足条件而未执行set操作,则返回空回复nil"

注意

如果key已经保存了一个值,则set命令执行成功时,无论其类型如何,都会被覆盖。

get命令

语法

1.get key

获取key对应的value。如果key不存在,则返回特殊值nil。如果存储在key中的值不是字符串,则返回错误,因为get仅处理字符串值。

exists命令

判断指定的key是否存在。从Redis3.0.3开始,可以指定多个key,而不仅是单个key。

语法:

  1. exists key1 [key2 ...]
      仅指定一个key时,如果key存在则返回1,不存在则返回0.当指定多个key时,它返回存在的key的总数。

keys命令

语法

  1. keys pattern
    返回和pattern(模式)匹配的所有key。
    支持的常用模式如下。
  • hello:匹配单个字符,如hello、hallo、hxllo等。
  • hello:匹配任意字符,如hello、heeeello等。
  • h[ae]llo:包含一个指定字符,如hello或hallo。
  • h[^ae]llo:包含除指定字符外的一个字符,如hbllo、hello等,但不包含hallo和hello。
  • h[a-c]llo:匹配指定范围内的一个字符,如hallo、hbllo和hello。

如需匹配以上模式中的特殊字符,则需使用\转义,如要匹配*字符,应使用*。

del命令

语法

  1. del key1 [key2 ...]

删除指定的key,返回已删除的key的数量。如果key不存在,则忽略该key。

rename命令

语法

  1. rename key newkey

将key重命名为newkey,当key不存在肘返回错误。如果newkey已经存在,则会被覆盖(此时rename执行隐式del操作)。

expire命令

语法

  1. expire key timeout

在key上设置超时时间timeout,时间以秒为单位,若key超时将被自动删除。若设置成功则返回1。

若key不存在则返回0。

注意

(1)如果设置一个非正的timeout参数,将导致key被删除。

(2)对已经设置了超时时间的key调用expire命令,该key的超时时间将更新为新值。

(3)删除key或覆盖key的内容会清除该key的超时设置,如del、set操作。

(4)如果使用rename命令重命名key,则相关的剩余生存时间将转移到新key。

ttl命令

语法

  1. ttl key

以秒为单位返回key的剩余生存时间。对于Redis 2.8及以上版本,如果key未设置超时时间(即永久有效)则返回-1,如果key不存在(或已超时而被删除)则返回2。而对于Redis 2.6及以下版本,当未设置超时时间和key不存在时均返回-1.

persist命令

语法

  1. persist key

删除key上现有的超时设置,使key变为永久有效。如果超时设置被删除,则返回1;如果key不存在或没有关联的超时设置,则返回0。

select命令

select命令用于选择具有指定dbid的Redis逻辑数据库。

语法:

  1. select dbid

flushdb命令

语法:

  1. flushdb

该命令用于删除当前所选数据库中的所有key。

flushall命令

语法:

  1. flushall

该命令用于删除所有数据库中的key,而不仅仅是当前选定的数据库中的key。

quit命令

语法:

  1. quit

该命令要求服务器关闭连接。一旦所有待处理的回复都返回客户端,连接就会关闭。

4.4 Redis图形客户端

在Java中编写一个完整的Redis图形客户端通常涉及多个步骤,包括用户界面设计、后端逻辑处理以及Redis客户端库的集成。由于Java本身不直接支持图形用户界面(GUI)的创建(像Python的Tkinter或JavaScript的HTML/CSS那样),我们通常会使用Java的图形界面库,如Swing或JavaFX。

下面,我将提供一个简化的示例,说明如何使用Java Swing库和Jedis(一个流行的Java Redis客户端)来创建一个基本的Redis图形客户端。这个客户端将允许用户输入键和值,并发送SET和GET命令到Redis服务器。

首先,确保你已经添加了Jedis依赖到你的项目中。如果你使用Maven,可以在pom.xml中添加以下依赖:

xml 复制代码
<dependency>  
    <groupId>redis.clients</groupId>  
    <artifactId>jedis</artifactId>  
    <version>最新版本</version> <!-- 请替换为最新的Jedis版本 -->  
</dependency>

接下来是Java Swing的Redis图形客户端代码示例:

java 复制代码
import redis.clients.jedis.Jedis;  
  
import javax.swing.*;  
import java.awt.*;  
import java.awt.event.ActionEvent;  
import java.awt.event.ActionListener;  
  
public class RedisGUI extends JFrame {  
  
    private JTextField keyTextField;  
    private JTextField valueTextField;  
    private JTextArea resultArea;  
    private Jedis jedis;  
  
    public RedisGUI() {  
        super("Redis Graphical Client");  
        initUI();  
        connectToRedis();  
    }  
  
    private void initUI() {  
        setLayout(new BorderLayout());  
  
        JPanel inputPanel = new JPanel(new GridLayout(2, 2));  
        inputPanel.add(new JLabel("Key:"));  
        keyTextField = new JTextField(20);  
        inputPanel.add(keyTextField);  
        inputPanel.add(new JLabel("Value:"));  
        valueTextField = new JTextField(20);  
        inputPanel.add(valueTextField);  
  
        JButton setButton = new JButton("SET");  
        setButton.addActionListener(new ActionListener() {  
            @Override  
            public void actionPerformed(ActionEvent e) {  
                String key = keyTextField.getText();  
                String value = valueTextField.getText();  
                jedis.set(key, value);  
                resultArea.append("SET " + key + " " + value + "\n");  
            }  
        });  
  
        JButton getButton = new JButton("GET");  
        getButton.addActionListener(new ActionListener() {  
            @Override  
            public void actionPerformed(ActionEvent e) {  
                String key = keyTextField.getText();  
                String value = jedis.get(key);  
                if (value == null) {  
                    resultArea.append("GET " + key + " -> NULL\n");  
                } else {  
                    resultArea.append("GET " + key + " -> " + value + "\n");  
                }  
            }  
        });  
  
        JPanel buttonPanel = new JPanel();  
        buttonPanel.add(setButton);  
        buttonPanel.add(getButton);  
  
        resultArea = new JTextArea(10, 40);  
        JScrollPane scrollPane = new JScrollPane(resultArea);  
  
        add(inputPanel, BorderLayout.NORTH);  
        add(buttonPanel, BorderLayout.CENTER);  
        add(scrollPane, BorderLayout.SOUTH);  
  
        pack();  
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        setLocationRelativeTo(null);  
    }  
  
    private void connectToRedis() {  
        jedis = new Jedis("localhost", 6379); // 默认连接本地Redis服务器  
    }  
  
    public static void main(String[] args) {  
        SwingUtilities.invokeLater(new Runnable() {  
            @Override  
            public void run() {  
                new RedisGUI().setVisible(true);  
            }  
        });  
    }  
}

这个示例创建了一个简单的窗口,包含用于输入键和值的文本字段,以及两个按钮(SET和GET)来发送Redis命令。结果将显示在窗口底部的文本区域中。

请注意,这个示例假设Redis服务器正在本地机器上运行,并且监听默认的6379端口。如果你需要连接到远程Redis服务器或不同的端口,请相应地修改connectToRedis方法中的Jedis构造函数参数。

此外,这个示例没有处理Redis连接异常或命令执行异常,这些在生产环境中应该是必须要考虑的。你可以通过添加try-catch块来捕获和处理这些异常。

4.5 在Java应用中访问Redis

  • maxTotal:最大活动连接数,默认为8。若设置为1,则表示不限制。
  • maxIdle:最大空闲连接数,默认为8。
  • minIdle:最小空闲连接数,默认为0。
  • maxWaitMillis:表示从池中获取一个资源时的最大等待时间,单位是毫秒,-1表示永不超时。如果超时等待时间,将抛出NoSuchElementException,进而引发JedisConnectionException。
  • testOnBorrow:表示从池中获取一个资源时是否提前进行验证操作。若该参数设置为true,则得到的资源均是可用的。
相关推荐
hao_wujing13 分钟前
攻击模型的恶意行为检测
网络·数据库·php
秃头摸鱼侠1 小时前
MySQL查询语句(续)
数据库·mysql
MuYiLuck1 小时前
【redis实战篇】第八天
数据库·redis·缓存
睡觉待开机1 小时前
6. MySQL基本查询
数据库·mysql
�FENG2 小时前
Redis 安装配置和性能优化
redis·持久化
大熊猫侯佩2 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(三)
数据库·swiftui·swift
大熊猫侯佩2 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(二)
数据库·swiftui·swift
大熊猫侯佩2 小时前
用异步序列优雅的监听 SwiftData 2.0 中历史追踪记录(History Trace)的变化
数据库·swiftui·swift
大熊猫侯佩2 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(一)
数据库·swiftui·swift
Ares-Wang2 小时前
负载均衡LB》》HAproxy
运维·数据库·负载均衡