前言:
笔者使用的是云服务器是阿里云的ECS服务器
这个服务器内核是Alibaba Cloud Linux 3。
使用的命令行工具为Alibaba Could Manager
命令行工具连接服务器这里就不多说了,如果没有用过的小伙伴可以去看阿里云的官方文档,很详细。
下面我们开始安装
1.确保系统已经更新到最新的软件包列表。运行以下命令:
sudo yum update
2.安装Redis。运行以下命令:
sudo yum install redis
3.安装完成后,启动Redis服务:
sudo systemctl start redis
4.设置Redis开机自启动:
sudo systemctl enable redis
5.检查Redis是否正在运行:
sudo systemctl status redis
如果正在运行,你可以看到类似如下的输出
redis.service - Redis persistent key-value database
Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2024-01-04 12:00:00 UTC; 1min ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Main PID: 1234 (redis-server)
CGroup: /system.slice/redis.service
└─1234 /usr/bin/redis-server 127.0.0.1:6379
你已经成功安装和启动了Redis。此时我们就可以使用redis-cli命令连接到Redis服务器并执行相关操作。
但是我们还需要配置一些信息(这里只做最简单的配置)
我们需要确认一下redis的监听ip端口等信息,如果我们有外部客户端程序需要访问的话,我们需要确认我们的redis配置中设置了可以监听到该程序的访问。
我们可以使用
ps aux | grep redis
ps:这个命令是"process status"的缩写,用于提供有关当前运行进程的信息。
aux:选项a和u用于显示所有用户的所有运行进程的信息(a),以用户友好的格式显示(u)。x选项显示与终端无关的进程。
|(管道):它将左侧命令的输出作为右侧命令的输入。
grep redis:grep命令用于在输入中搜索特定的模式或文本。在这种情况下,它搜索包含"redis"关键字的行。
因此,当你运行ps aux | grep redis时,实际上是在要求系统显示所有运行进程的信息,然后过滤输出,只显示包含"redis"关键字的行。这通常用于检查系统上是否当前正在运行Redis服务器进程,并获取有关该进程的信息。
这个命令看一下
我们会发现他监听的是本地的6379端口,没有监听其他端口,所以肯定需要修改。
使用 Vim 编辑器打开 redis.conf 文件
一般来说在linux中redis.conf文件默认会在etc/redis/目录下,或者就在etc/目录下,这个需要我们自己去找一下。
然后我们找到bind配置
使用vim编辑器进入的小伙伴,可以先按下ESC,然后输入/bind就可以快速检索bind的所在位置
bind 127.0.0.1 -::1
这个配置表示 Redis 只会监听本地回环地址(localhost),即 127.0.0.1 和 ::1(IPv6 的本地回环地址)。这样的配置意味着 Redis 只能通过本地访问,外部网络无法连接到 Redis 服务器。
127.0.0.1: 这是 IPv4 的本地回环地址,只允许本地计算机访问 Redis。
::1: 这是 IPv6 的本地回环地址,同样只允许本地计算机访问 Redis。
所以我们需要改为
bind 0.0.0.0
这样 Redis 将会监听所有可用的网络接口,允许来自本地和外部网络的连接。(注意这个配置是重启后生效的)
所以我们需要使用
sysmctl restart redis
重启一下redis
这样我们就重新设置了redis的监听ip和端口
其实到这里一般开发中我们就已经可以使用redis了,可以不去设置用户名和密码。
我们使用redis的客户端程序(我这里使用的是Another Redis Desktop Manager)去连接是可以连接上的。
补充:
如果有小伙伴就配置完上面信息就去使用,可能会存入的数据隔一段时间就消失了的情况(ps:并没有设置过期时间。)笔者在使用时就出现了这种情况。下面我们就逐步排查并解决这个问题。
首先redis数据存入隔一段时间就消失常见的有两个原因
第一就是我们存入数据的时候就设置了过期时间
第二就是我们没有持久化设置,导致出现了问题
比如说你用java语言时使用了
redisTemplate.opsForValue().set(key, value, timeout, timeUnit)
类似这样的代码显示的设置了TTL。
这个也很好排查,直接在redis客户端使用
TTL key(你自己数据的key值)
就可以查看对应key的过期时间了,如果是-1那就证明并没有设置过期时间,redis默认应该持久化保存。
那么下面我们排除第二种情况
查看redis的持久化设置情况,可以有以下几种途径
1.在配置文件中查找包含关键字save的行
以我上文陈述的redis配置(我的redis配置文件存储在etc/redis.conf)为例:
从配置文件的存储路径下进去,
cd /etc
然后使用vim编辑器打开redis.conf
vim redis.conf
我使用的这个版本的阿里云Linux服务器自带vim编辑器,所以不需要下载,如果有小伙伴显示vim命令无效,可能需要额外下载一下vim编辑器,这个自己去网上搜一下就行。
我们需要在配置文件中找到有关持久化的配置
我们使用
/sava
这个vim编辑的字符串搜索功能来搜索save配置。
我们可以使用n来跳转到下一个匹配项。
我们看到下面的描述
这个翻译一下:
# save <seconds> <changes>
#
# 如果在给定的秒数和对数据库的写入操作达到了给定的次数,Redis 将保存数据库快照。
#
# 快照功能可以通过单个空字符串参数完全禁用,示例如下:
#
# save ""
#
# 除非另有说明,默认情况下 Redis 将保存数据库快照:
# * 在 3600 秒(一小时)内,如果至少有 1 个键发生了变化
# * 在 300 秒(5 分钟)内,如果至少有 100 个键发生了变化
# * 在 60 秒内,如果至少有 10000 个键发生了变化
#
# 你可以通过取消注释以下三行来显式设置这些值。
#
# save 3600 1
# save 300 100
# save 60 10000
那就说明默认redis是设置了持久化配置的。
如果还不放心,我们可以进入redis客户端
redis-cli
然后使用命令
CONFIG GET save
如果你和我一样有下面的输出,那就证明持久化配置是设置了的。
顺便说一下,我们在配置文件中查找appendonly
appendonly no
说明这个redis的AOF持久化是没有开启的。但是redis是有两种持久化方式的。redis默认开启的是RDB持久化。
此外,我们可以通过使用Redis的INFO命令可以获取有关Redis服务器的各种信息,包括持久化信息
redis-cli
INFO persistence
这些输出的含义我也列举在这里:
loading:指示系统当前是否正在加载数据。值为0表示没有正在进行的加载过程。
current_cow_size:表示当前的写时复制(Copy-on-Write,COW)大小。写时复制是内存管理中使用的一种策略。
current_cow_size_age:当前写时复制大小的年龄。
current_fork_perc:当前分叉的百分比。
current_save_keys_processed:当前保存操作期间处理的键数。
current_save_keys_total:当前保存操作期间要保存的键总数。
rdb_changes_since_last_save:上次保存以来的更改次数。
rdb_bgsave_in_progress:指示当前是否正在进行后台保存操作。
rdb_last_save_time:上次保存操作的时间戳。
rdb_last_bgsave_status:上次后台保存操作的状态(例如,"ok"表示成功)。
rdb_last_bgsave_time_sec:上次后台保存操作所用的时间(以秒为单位)。
rdb_current_bgsave_time_sec:正在进行的后台保存操作所用的当前时间(以秒为单位)。
rdb_last_cow_size:上次保存操作期间写时复制的大小。
aof_enabled:指示是否启用了追加模式文件(Append-Only File,AOF)(1表示启用,0表示禁用)。
aof_rewrite_in_progress:指示当前是否正在进行AOF重写操作。
aof_rewrite_scheduled:指示是否已安排进行AOF重写。
aof_last_rewrite_time_sec:上次AOF重写操作所用的时间(以秒为单位)。
aof_current_rewrite_time_sec:正在进行的AOF重写操作所用的当前时间(以秒为单位)。
aof_last_bgrewrite_status:上次后台AOF重写操作的状态。
aof_last_write_status:上次AOF写操作的状态。
aof_last_cow_size:上次AOF重写操作期间写时复制的大小。
module_fork_in_progress:指示当前是否正在进行模块分叉操作。
module_fork_last_cow_size:上次模块分叉操作期间写时复制的大小。
好了,那么两种情况都排查完毕,但是很遗憾,如果你是和我一样使用,阿里云服务器(ECS云服务器)使用yum安装redis的最新版的redis,这个问题就还没解决。
笔者最后是在redis的日志里面发现的问题。
我们可以去配置文件里面看一下日志文件的输出位置
发现redis的日志在/var/log/redis/redis.log
我们直接打开
vim /var/log/redis/redis.log
我们会发现
好家伙,这么多error
这些日志信息表明在Redis进行后台快照持久化时出现了问题。以下是对日志的解读:
1changes in 3600 seconds. Saving…:
表示在最近的 3600 秒内有 1 次写操作,Redis触发了执行快照持久化。Background saving started by pid 49970:
表示Redis开始了由进程号(pid)为49970的进程执行的后台快照持久化操作。49970:C 07 Jan 2024 03:39:03.083 # Failed opening the RDB file crontab(in server root dir /etc) for saving: Permission
denied:
这里指出了问题,表示在将快照保存到RDB文件时,Redis尝试在根目录(/etc)下创建名为 “crontab” 的RDB文件,但由于权限问题导致失败。#Background saving error:表示后台保存遇到错误。
类似的日志条目重复了,表明在后续的尝试中,仍然无法保存快照。
原来如此
这个问题的根本原因是Redis进程没有足够的权限在指定的目录(/etc)下创建文件。通常情况下,Redis执行后台快照持久化时,会在Redis服务器的工作目录或配置文件中指定的目录中创建RDB文件。
下面我们来解决这个问题
1.首先我们确认一下我们redis的工作目录
确认工作目录: 检查Redis配置文件中的 dir 配置项,确认Redis服务器的工作目录。理论上:这个目录应该有足够的写权限供Redis创建RDB文件。
以防外一,我们可以使用客户端去看一下我们的服务器是不是真的有这个文件夹
2.查看 Redis 进程运行在哪个用户和用户组下:
我们使用
ps aux | grep redis
这将列出所有包含 “redis” 关键字的进程。注意查看 Redis 服务的主进程(通常是 redis-server)的用户和用户组信息
通过第一行我们发现:
Redis 进程运行在 redis 用户下。在 ps 输出中,第一列是用户列,而 104034 行中的 redis 表示该进程是以 redis 用户身份运行的。
注意:
第二行中的 root 表示 grep 进程,用于查找包含 “redis” 关键字的进程。这是由你在终端执行的 ps aux | grep redis 命令本身生成的。并不是redis进程。
所以我们已经找到redis运行的用户名了
下面我们去找一下该用户名所属的用户组
id redis
这将显示有关 redis 用户的详细信息,其中包括用户ID(UID)、用户组ID(GID)、附属的用户组等。其中,groups 部分会列出 redis 用户所属的所有用户组。
说明redis运行的用户组是redis,用户名也是redis
下面我们只需要设置权限就可以了
3.调整权限: 确保Redis进程有足够的权限在工作目录中进行写操作。可以使用 chown 和 chmod 命令来调整目录的所有者和权限。
sudo chown redis:redis /var/lib/redis
sudo chmod 770 /var/lib/redis
上述命令假设Redis运行在 redis 用户和 redis 组下,确保适应你的实际情况。
这里说一下这个770是哈
在 chmod 命令中,三个数字 770 用于表示文件或目录的权限。
每个数字代表一组权限,分别是:
第一个数字表示所有者(Owner)的权限。 第二个数字表示所属组(Group)的权限。 第三个数字表示其他用户(Others)的权限。
每个数字由三个比特(或位)组成,分别代表读(Read)、写(Write)、和执行(Execute)权限。在 770 中,二进制表示为 111 111 000,分别对应于所有者、所属组和其他用户的权限。
所有者(Owner)的权限为 111,即读、写和执行权限。 所属组(Group)的权限为 111,即读、写和执行权限。
其他用户(Others)的权限为 000,即没有任何权限。 这意味着对于该文件或目录:所有者和所属组都有读、写和执行的权限。 其他用户没有任何权限。 在上述情况中,770
通常用于确保文件或目录只对所有者和所属组具有完全的访问权限,而其他用户没有权限。这种权限设置通常用于安全性考虑,以限制对敏感数据的访问。
4.最后不要忘记重启redis
systemctl restart redis