第四章 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", "johndoe@example.com");  
  
            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,则得到的资源均是可用的。
相关推荐
Azoner6 分钟前
postgresql安装部署(linux)
数据库·postgresql
PyAIGCMaster31 分钟前
文本模式下成功。ubuntu P104成功。
服务器·数据库·ubuntu
xo1988201138 分钟前
鸿蒙人脸识别
redis·华为·harmonyos
drebander43 分钟前
MySQL 查询优化案例分享
数据库·mysql
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581361 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
YashanDB3 小时前
【YashanDB知识库】XMLAGG方法的兼容
数据库·yashandb·崖山数据库
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍11基于XML的SQL注入(XML-Based SQL Injection)
数据库·安全·web安全·漏洞挖掘·sql注入·hw·xml注入
风间琉璃""4 小时前
bugkctf 渗透测试1超详细版
数据库·web安全·网络安全·渗透测试·内网·安全工具