redis部署

直接安装

包管理器安装

安装

1
dnf instal redis

image-20250814083618308

启动

1
2
3
sudo systemctl start redis
sudo systemctl enable redis
sudo systemctl status redis

image-20250814083718570

测试连接-1

1
2
redis-cli
ping

image-20250814083907972

配置文件

​ 修改访问地址、增加密码、持久化存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vim /etc/redis.conf
# 修改访问地址:69行左右
bind 0.0.0.0
# 增加密码:507行左右
requirepass regen
# 持久化存储
# RDB持久化(默认会开启):218行左右
save 900 1
save 300 10
save 60 10000

# AOF持久化:700行左右
appendonly yes

RDB

在指定的间隔时间自动将内存中的数据快照保存到磁盘。

AOF

记录所有写操作,以便在 Redis 重启时重新执行。

1. RDB 持久化

RDB(Redis 数据库快照)会在指定的时间间隔内自动保存内存中的数据到磁盘。它是通过保存数据快照的方式进行持久化,适用于那些对实时性要求不高的场景。

优点:

  • 性能好:因为快照是定期的,不会对每次写操作都产生额外开销。
  • 恢复速度快:RDB 文件较小,加载快。
  • 适合备份:可以定期进行 RDB 快照备份,方便恢复。

缺点:

  • 丢失数据:如果 Redis 崩溃,在最近一次快照保存之前的数据会丢失(即不适合实时性要求极高的应用)。
  • 不适合高频写操作:快照是周期性的,如果写入频繁,生成快照可能会导致性能下降。

适用场景:

  • 适用于数据可以丢失一部分的应用场景,例如缓存系统、会话存储等。
  • 适用于数据量较大且更新不频繁的系统。

2. AOF 持久化

AOF(Append Only File)会记录 Redis 的每一个写操作,并将它们追加到磁盘上的文件中。Redis 重启时会通过执行 AOF 文件中的操作来恢复数据。

优点:

  • 数据安全:AOF 可以提供较高的数据持久性,即使 Redis 崩溃,丢失的数据量较少。可以通过设置同步频率控制丢失的数据量。
  • 适合高可靠性需求:如果数据丢失不可接受,AOF 是一个不错的选择。

缺点:

  • 性能开销大:每次写操作都会追加到 AOF 文件,频繁写操作会增加磁盘 I/O,影响性能。
  • AOF 文件较大:随着时间的推移,AOF 文件会不断增大,可能需要定期进行压缩(重写操作)。

适用场景:

  • 适用于对数据丢失容忍度低的场景,如金融系统、订单系统、聊天记录等。
  • 适合对数据一致性和持久性有较高要求的应用。

3. RDB + AOF(同时启用)

在一些场景下,为了提高数据的持久性和恢复速度,生产环境中会同时启用 RDB 和 AOF。这种方式结合了 RDB 的性能优势和 AOF 的数据可靠性优势。

适用场景:

  • 高可用性:同时启用 RDB 和 AOF 可以在 Redis 崩溃时既能快速恢复数据,又能减少数据丢失。
  • 适合对数据安全性和恢复速度都有较高要求的生产环境。

配置:

  • 可以启用 RDB 和 AOF,同时配置 RDB 的快照频率和 AOF 的同步策略,以权衡性能和数据安全性。

4. 持久化选项选择(生产环境常见方案)

生产环境中,通常会选择以下几种持久化配置方案:

  1. 只启用 AOF(推荐)
    • 大多数生产环境使用 AOF 持久化,因为它能提供更好的数据可靠性。
    • 设置为 每秒同步appendfsync everysec)是常见的做法,既能提供足够的数据持久性,又不会对性能产生过大影响。
  2. 只启用 RDB
    • 如果应用的可容忍数据丢失时间较长,并且需要高性能,可以选择只启用 RDB。
    • 配置较长的 save 间隔,比如每 5 分钟保存一次快照(save 300 10)。
  3. 同时启用 RDB 和 AOF
    • 为了在保证数据可靠性的同时兼顾性能,很多生产环境会选择同时启用 RDB 和 AOF。
    • 通过合理配置 AOF 重写策略auto-aof-rewrite-percentageauto-aof-rewrite-min-size)来避免 AOF 文件无限增大。

5. 持久化配置建议

在生产环境中,推荐的做法通常是:

  • 启用 AOF 持久化,使用 appendfsync everysec 来平衡性能和持久化。
  • 如果可以容忍少量数据丢失并且对性能有较高需求,可以只启用 RDB
  • 同时启用 RDB 和 AOF,通过定期压缩 AOF 文件和适当的 RDB 快照间隔来优化性能。

测试连接-2

1
2
3
4
[root@localhost ~]# redis-cli
127.0.0.1:6379> auth regen
OK
127.0.0.1:6379>

python连接测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import redis
import time

def main():
# 连接 Redis,注意如果设置了密码请加 password 参数
r = redis.Redis(host='192.168.72.11', port=6379, password='regen', decode_responses=True)
# 写入键值对
r.set('session', '1234567890')

# 设置过期时间为 10 秒
r.expire('session', 100)


# 读取键值
value = r.get('session')
print(f"Got value for 'session': {value}")

# 查看剩余过期时间
ttl = r.ttl('session')
print(f"TTL for 'session': {ttl} seconds")

# 等几秒再查一次 TTL
time.sleep(5)
ttl = r.ttl('session')
print(f"TTL for 'session' after 5 seconds: {ttl} seconds")

if __name__ == "__main__":
main()

image-20250814085735227

离线包安装

准备离线包:rhelpkg | redis

1
2
dnf install redis-7.0.5-1.el8.x86_64.rpm 

image-20250814090538494

image-20250814090602832

docker部署

​ 一般不用docker部署,redis使用的是内存来增加访问速度。

1
2
3
4
5
6
7
docker run -d \
--name redis-server \
-p 6379:6379 \
-v /root/redis/redis-home/data:/data \
-v /root/redis/redis-home/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest \
redis-server /usr/local/etc/redis/redis.conf

redsi集群部署

​ 资源有限,采用docker的方式进行集群。网络模式采用host。

每台虚拟机起三个redis容器进行集群。

192.168.72.5

image-20250814091019410

192.168.72.5

image-20250814091032933

准备工作

​ 准备六个容器的data目录以及挂载的配置文件。

目录

​ 两个虚拟机的目录结构一样。

image-20250814091217132

配置文件

​ 配置文件需要修改相当一部分,主要是允许集群模式、端口。

1
2
3
4
5
6
7
8
9

bind 0.0.0.0
requirepass regen
port 7001
# 以下是集群的配置
cluster-announce-ip 192.168.72.5
cluster-announce-port 7001
# * cluster-announce-tls-port
cluster-announce-bus-port 17001 # cluster-announce-port+10000

起容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 192.168.72.6 节点
docker run -d --name redis7001 --network host \
-v /root/redis/redis-cluster/node1/data:/data \
-v /root/redis/redis-cluster/node1/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf

docker run -d --name redis7002 --network host \
-v /root/redis/redis-cluster/node2/data:/data \
-v /root/redis/redis-cluster/node2/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf

docker run -d --name redis7003 --network host \
-v /root/redis/redis-cluster/node3/data:/data \
-v /root/redis/redis-cluster/node3/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf


# 192.168.72.5 节点
docker run -d --name redis7004 --network host \
-v /root/redis/redis-cluster/node1/data:/data \
-v /root/redis/redis-cluster/node1/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf

docker run -d --name redis7005 --network host \
-v /root/redis/redis-cluster/node2/data:/data \
-v /root/redis/redis-cluster/node2/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf

docker run -d --name redis7006 --network host \
-v /root/redis/redis-cluster/node3/data:/data \
-v /root/redis/redis-cluster/node3/redis.conf:/usr/local/etc/redis/redis.conf \
redis:latest redis-server /usr/local/etc/redis/redis.conf

创建集群

创建集群

1
2
3
4
5
6
redis-cli --cluster create \
192.168.72.6:7001 192.168.72.6:7002 192.168.72.6:7003 \
192.168.72.5:7001 192.168.72.5:7002 192.168.72.5:7003 \
--cluster-replicas 1 \
-a redis \
--cluster-yes

查看集群

1
redis-cli -c -p 7001  -a redis cluster nodes

image-20250814130336862

测试集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from redis.cluster import RedisCluster, ClusterNode
from redis.exceptions import RedisError
import logging

def main():
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

try:
logger.info("Connecting to Redis Cluster...")

# 1. 节点配置(根据您实际的集群节点)
startup_nodes = [
ClusterNode(host="192.168.72.6", port=7001),
ClusterNode(host="192.168.72.5", port=7001),
ClusterNode(host="192.168.72.6", port=7002)
]

# 2. 集群连接配置
rc = RedisCluster(
startup_nodes=startup_nodes,
password="redis",
decode_responses=True,
socket_connect_timeout=5,
socket_timeout=5,
read_from_replicas=False,
max_connections_per_node=10
)

# 3. 获取集群信息的完美方法
def print_cluster_info():
try:
# 方法1:使用原生命令获取最原始信息
nodes_info = rc.execute_command("CLUSTER NODES")
cluster_info = rc.execute_command("CLUSTER INFO")

logger.info("\n=== Cluster Nodes ===")
for line in str(nodes_info).split('\n'):
if line.strip():
logger.info(line.strip())

logger.info("\n=== Cluster Status ===")
for line in str(cluster_info).split('\n'):
if line.strip():
logger.info(line.strip())

except Exception as e:
logger.warning(f"Info partial: {str(e)}")

print_cluster_info()

# 4. 测试数据操作
test_data = {
"user:1001": "Alice",
"product:2002": "Phone",
"order:3003": "Completed"
}

# 写入测试数据
for key, value in test_data.items():
rc.set(key, value, ex=60) # 60秒过期

# 验证数据分布
logger.info("\n=== Data Distribution ===")
for key in test_data:
node = rc.get_node_from_key(key)
logger.info(f"{key.ljust(12)} = {rc.get(key).ljust(10)} (served by {node.host}:{node.port})")

logger.info("\nRedis Cluster test fully successful!")

except RedisError as e:
logger.error(f"Redis Error: {str(e)}")
except Exception as e:
logger.error(f"Unexpected Error: {str(e)}")

if __name__ == "__main__":
main()

image-20250814130550824

问题

一个容器掉了,重新起来无法加入。

1
redis-cli --cluster fix 192.168.72.6:7001 -a redis