redis部署 直接安装 包管理器安装 安装
启动 1 2 3 sudo systemctl start redissudo systemctl enable redissudo systemctl status redis
测试连接-1
配置文件 修改访问地址、增加密码、持久化存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 vim /etc/redis.conf bind 0.0.0.0requirepass regen save 900 1 save 300 10 save 60 10000 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. 持久化选项选择(生产环境常见方案) 生产环境中,通常会选择以下几种持久化配置方案:
只启用 AOF(推荐) :
大多数生产环境使用 AOF 持久化,因为它能提供更好的数据可靠性。
设置为 每秒同步 (appendfsync everysec
)是常见的做法,既能提供足够的数据持久性,又不会对性能产生过大影响。
只启用 RDB :
如果应用的可容忍数据丢失时间较长,并且需要高性能,可以选择只启用 RDB。
配置较长的 save
间隔,比如每 5 分钟保存一次快照(save 300 10
)。
同时启用 RDB 和 AOF :
为了在保证数据可靠性的同时兼顾性能,很多生产环境会选择同时启用 RDB 和 AOF。
通过合理配置 AOF 重写策略 (auto-aof-rewrite-percentage
和 auto-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 redisimport timedef main (): r = redis.Redis(host='192.168.72.11' , port=6379 , password='regen' , decode_responses=True ) r.set ('session' , '1234567890' ) 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" ) time.sleep(5 ) ttl = r.ttl('session' ) print (f"TTL for 'session' after 5 seconds: {ttl} seconds" ) if __name__ == "__main__" : main()
离线包安装 准备离线包:rhelpkg | redis
1 2 dnf install redis-7.0.5-1.el8.x86_64.rpm
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
192.168.72.5
准备工作 准备六个容器的data目录以及挂载的配置文件。
目录 两个虚拟机的目录结构一样。
配置文件 配置文件需要修改相当一部分,主要是允许集群模式、端口。
1 2 3 4 5 6 7 8 9 bind 0.0.0.0requirepass regen port 7001 cluster-announce-ip 192.168.72.5 cluster-announce-port 7001 cluster-announce-bus-port 17001
起容器 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 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 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
测试集群 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, ClusterNodefrom redis.exceptions import RedisErrorimport loggingdef main (): logging.basicConfig( level=logging.INFO, format ='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) try : logger.info("Connecting to Redis Cluster..." ) 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 ) ] 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 ) def print_cluster_info (): try : 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() test_data = { "user:1001" : "Alice" , "product:2002" : "Phone" , "order:3003" : "Completed" } for key, value in test_data.items(): rc.set (key, value, ex=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()
问题 一个容器掉了,重新起来无法加入。
1 redis-cli --cluster fix 192.168.72.6:7001 -a redis