暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

融合Redis缓存的PostgreSQL高可用架构

武林萌主 2025-04-09
157

一、方案概述

事实上,这是一个基本思路,即在依托外部组件增强postgreSQL高可用性,而非单纯依赖冗余故障切换与恢复。在此基础上,可以扩展负载均衡、备份与其它容灾方案。本方案通过Redis缓存层与PostgreSQL数据库的异步写入机制,解决传统高可用架构的局限性。当PostgreSQL主节点故障时,Redis缓存层继续提供写入和部分查询服务,确保业务连续性;PostgreSQL恢复后,通过异步写入保障数据一致性。

二、技术架构

客户端应用 → Redis缓存 -(异步写入/CDC)→ PostgreSQL数据库

  • Redis缓存层:业务数据先写入Redis,提供快速读写能力。
  • 异步写入机制:后台程序将Redis数据异步写入PostgreSQL。
  • 故障恢复:中断恢复后,Redis数据自动同步至数据库,保障数据一致性。

三、实验环境

1. 缓存服务器

  • 操作系统:RockyLinux 8+
  • 软件:Redis 7.4.2、Python 3.9.2、redis-py、psycopg2-binary

2. 数据库服务器

  • 操作系统:RockyLinux 8+
  • 软件:PostgreSQL 17.0

四、实验步骤

(一)异步写入实验

1. PostgreSQL建表


CREATE TABLE users ( id TEXT PRIMARY KEY, name TEXT, age INT, email TEXT );

2. Redis数据写入

# Redis CLI HSET user:u123 name "wangsan" age 30 email "wangsan@gmail.com" HGETALL user:u123

3. 异步写入脚本(r2p.py


import redis import psycopg2 # Redis连接 r = redis.Redis(host='localhost', port=6379, decode_responses=True) # PostgreSQL连接 pg = psycopg2.connect( dbname='postgres', user='postgres', password='yourpassword', host='192.168.1.10', port=5432 ) pg.autocommit = True cur = pg.cursor() # 异步写入逻辑 for key in r.scan_iter("user:*"): user_id = key.split(":")[1] user_data = r.hgetall(key) cur.execute(""" INSERT INTO users (id, name, age, email) VALUES (%s, %s, %s, %s) ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, age = EXCLUDED.age, email = EXCLUDED.email """, ( user_id, user_data.get("name"), int(user_data.get("age")) if user_data.get("age") else None, user_data.get("email") )) cur.close() pg.close()

4. 执行同步

python3 r2p.py

5. 验证数据

SELECT * FROM users;

结论: 数据可正常持续写入

(二)模拟数据库停服

1. 持续写入Redis数据


# gen_redisdata.py import redis import random import time r = redis.Redis(host='localhost', port=6379, decode_responses=True) def generate_data(user_id): return { "name": random.choice(["wangsan", "lixiang", "haizi"]), "age": random.randint(18, 80), "email": f"user{user_id}@gmail.com" } def insert_data(): user_id = 1 while True: data = generate_data(user_id) r.hset(f"user:u{user_id}", mapping=data) print(f"Inserted: user:u{user_id} -> {data}") user_id += 1 time.sleep(2) if __name__ == "__main__": insert_data()

2. 模拟PostgreSQL停服

pg_ctl stop -D /var/lib/pgsql/data

3. 验证Redis持续写入

观察gen_redisdata.py输出,确认Redis正常写入。

结论: PostgreSQL中断时,Redis正常工作对外服务

(三)模拟数据库恢复

1. 恢复PostgreSQL服务

pg_ctl restart -D /var/lib/pgsql/data

2. 执行异步写入

python3 r2p.py

3. 验证数据一致性

  • 查询Redis数据:

    HGETALL user:u248

  • 查询PostgreSQL数据:

    SELECT * FROM users WHERE id = 'u248';

4. 统计数据一致性

  • PostgreSQL:

    SELECT COUNT(*) FROM users;

  • Redis:

    redis-cli DBSIZE

结论: PostgreSQL恢复后,数据可全量同步,保持数据一致。

五、总结

本方案通过Redis缓存层与PostgreSQL的异步写入机制,缓解了传统高可用架构的局限性:

  1. 业务连续性:Redis缓存层在PostgreSQL故障时提供写入和查询服务。
  2. 数据一致性:PostgreSQL恢复后,异步写入机制保障数据一致性。
  3. 适用场景:适用于高并发订单、日志、埋点等可异步处理场景。

后期优化建议

  1. 结合Redis AOF持久化与Kafka副本机制,增强数据可靠性。
  2. 引入缓存容量管理策略,避免缓存溢出。
  3. 使用定时任务(如crontab)定期执行异步写入脚本。
文章转载自武林萌主,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论