1 鮮花預訂配送系統概述
1.1 項目背景
鮮花預訂系統是一個實時處理用戶訂單、庫存管理和配送跟蹤的平臺。系統需要處理大量并發訂單,實時更新鮮花庫存狀態,并跟蹤配送進度。傳統關系型數據庫難以應對高并發的訂單處理和實時庫存更新需求,因此采用Redis作為核心數據庫,利用其高性能和豐富的數據結構特性,結合哨兵模式實現高可用性,確保系統穩定運行。
1.2 項目功能
實時訂單處理:快速接收和處理用戶鮮花預訂訂單
庫存管理:實時更新鮮花庫存狀態,防止超賣
配送跟蹤:記錄和更新配送員位置信息
高可用保障:哨兵模式自動故障轉移,避免服務中斷
數據持久化:RDB快照+AOF日志確保訂單和庫存數據可恢復
1.3 技術選型
數據庫:Redis 5.0.7(主從復制 + 哨兵模式)
容器化:Docker部署Redis和哨兵
數據持久化:RDB(定時快照) + AOF(實時日志)
數據結構:使用Hash、Sorted Set、List等多種Redis數據類型
編程語言:Python(用于示例代碼和測試)
2 項目的部署
2.1? 服務器配置
服務器角色 | IP地址 | 操作系統 | 用途 |
Redis主節點 | 10.1.1.11 | Centos7 | 處理讀寫請求,數據持久化 |
Redis從節點 | 10.1.1.142 | Centos7 | 復制主節點數據,分擔讀壓力 |
Redis從節點 | 10.1.1.148 | Centos7 | 復制主節點數據,分擔讀壓力 |
哨兵節點 | 三臺服務器都部署 | 監控主從狀態,自動故障轉移 |
2.2 網絡配置:
確保三臺服務器之間網絡互通,可以互相ping通。檢查防火墻設置,確保Redis端口(6379)和哨兵端口(26379)開放。
# 開放Redis端口
sudo firewall-cmd --permanent --add-port=6379/tcp
sudo firewall-cmd --permanent --add-port=26379/tcp
sudo firewall-cmd --reload
# 驗證網絡連通性(主節點ping從節點)
ping 10.1.1.142 -c 3
ping 10.1.1.148 -c 3
?
3.docekr部署redis和哨兵
3.1 在主節點(10.1.1.11)上部署Redis主節點:
創建Redis配置文件redis-master.conf
cat > /data/redis/conf/redis-master.conf <<'EOF' port 6379 bind 0.0.0.0 protected-mode no daemonize no dir /data appendonly yes appendfilename "appendonly.aof" appendfsync everysec save 900 1 save 300 10 save 60 10000 requirepass 123456 masterauth 123456 maxmemory 2gb maxmemory-policy allkeys-lru EOF |
啟動redis主節點容器:
docker run -d --name redis-master \
? -p 6379:6379 \
? -v /data/redis/conf:/usr/local/etc/redis \
? -v /data/redis/data:/data \
? redis:5.0.7 \
? redis-server /usr/local/etc/redis/redis-master.conf
3.2 在從節點(10.1.1.142和10.1.1.148)上部署Redis從節點:
創建Redis配置文件redis-slave.conf
cat > /data/redis/conf/redis-slave.conf <<'EOF' port 6379 bind 0.0.0.0 protected-mode no daemonize no dir /data appendonly yes appendfilename "appendonly.aof" appendfsync everysec save 900 1 save 300 10 save 60 10000 replicaof 10.1.1.11 6379 requirepass 123456 masterauth 123456 maxmemory 2gb maxmemory-policy allkeys-lru EOF |
在10.1.1.142和10.1.1.148上分別啟動Redis從節點容器:????????????????????????????????????????
docker run -d --name redis-slave \
? -p 6379:6379 \
? -v /data/redis/conf:/usr/local/etc/redis \
? -v /data/redis/data:/data \
? redis:5.0.7 \
? redis-server /usr/local/etc/redis/redis-slave.conf
3.3 在所有節點上部署哨兵:
創建哨兵配置文件sentinel.conf
cat > /data/redis/conf/sentinel.conf <<'EOF' port 26379 bind 0.0.0.0 protected-mode no daemonize no logfile "/var/log/redis/sentinel.log" dir "/tmp" sentinel monitor mymaster 10.1.1.11 6379 2 sentinel auth-pass mymaster 123456 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1 EOF |
在所有三臺服務器上啟動哨兵容器
4. 集群驗證:
4.1 檢查主從復制:
在主節點
docker exec -it redis-master redis-cli -a 123456 info replication
Redis 主從復制已成功部署并正常運行,10.1.1.11是主節點,offset值相同表示主從數據完全同步,lag=1?表示復制延遲極低(理想狀態)
4.2 檢查哨兵的狀態:
docker exec -it redis-sentinel redis-cli -p 26379 info sentinel
哨兵高可用集群已成功部署并正常運行
4.3 故障轉移測試:
停止主節點容器docker stop redis-master
觀察哨兵日志docker logs redis-sentinel | grep "failover"
節點驗證:
docker exec -it redis-slave redis-cli -a 123456 info replication
檢查新主節點的數據是否與原主節點一致(如訂單、庫存數據是否完整)
docker exec -it redis-slave redis-cli -a 123456 smembers "orders"
5.功能驗證
連接redis數據庫編寫python腳本(僅顯示核心代碼)
import redis from redis.sentinel import Sentinel def test_flower_system(): ??? # 連接 Redis Sentinel 并啟用自動解碼 ??? sentinel = Sentinel( ??????? sentinels=[('10.1.1.11', 26379), ('10.1.1.142', 26379), ('10.1.1.148', 26379)], ??????? socket_timeout=0.1, ??????? password='123456' ??? ) ??? # 主節點連接(讀寫操作) ??? master = sentinel.master_for( ??????? service_name='mymaster', ??????? socket_timeout=0.1, ??????? password='123456', ??????? decode_responses=True ??? ) ??? # 從節點連接(只讀操作) ??? slave = sentinel.slave_for( ??????? service_name='mymaster', ??????? socket_timeout=0.1, ??????? password='123456', ??????? decode_responses=True ??? )??? if __name__ == "__main__": ??? test_flower_system() |
6.navicat連接redis
進入redis已經可以看到表格了
7.web頁面
Vi app.py (此處只顯示個別核心代碼)
app = Flask(__name__) # 連接 Redis Sentinel sentinel = Sentinel( ??? sentinels=[('10.1.1.11', 26379), ('10.1.1.142', 26379), ('10.1.1.148', 26379)], ??? socket_timeout=0.1, ??? password='123456' ) # 主節點連接(讀寫操作) master = sentinel.master_for( ??? service_name='mymaster', ??? socket_timeout=0.1, ??? password='123456', ??? decode_responses=True ) # 從節點連接(只讀操作) slave = sentinel.slave_for( ??? service_name='mymaster', ??? socket_timeout=0.1, ??? password='123456', ??? decode_responses=True ) # 初始化數據(如果不存在) def init_data(): ??? if not slave.exists("flower:1"): ??????? master.hset("flower:1", mapping={ ??????????? "name": "紅玫瑰", ??????????? "price": 99, ??????????? "stock": 50, ??????????? "description": "鮮艷奪目,象征愛情", ??????????? "image": "https://picsum.photos/id/152/300/300" ??????? }) ??????? master.zadd("hot_sales", { ??????????? "flower:1": 100, ??????????? "flower:2": 80, ??????????? "flower:3": 120 ??????? }) ??????? master.geoadd("delivery_locations", (116.4074, 39.9042, "driver:001")) ??????? master.geoadd("delivery_locations", (116.4174, 39.9142, "driver:002")) ??????? print("數據初始化完成") if __name__ == '__main__': ??? init_data() ??? app.run(debug=True, host='0.0.0.0', port=5000) |
Vi /templates/index.html
退回上一級目錄,運行app.py文件,python app. py
8.數據持久化驗證:
8.1配置說明:
# RDB 快照配置(定時觸發)
save 900 1????? # 900秒內至少1次修改則觸發快照
save 300 10???? # 300秒內至少10次修改
save 60 10000?? # 60秒內至少10000次修改
# AOF 日志配置
appendonly yes?????????????? # 啟用AOF
appendfilename "appendonly.aof"? # AOF文件名
appendfsync everysec???????? # 每秒同步一次(平衡性能與安全)
dir /data?????????????????? # 持久化文件存儲目錄
8.2 RDB快照測試
docker exec -it redis-master redis-cli -a 123456 save
ls /data/redis/data/dump.rdb
8.3 AOF日志測試
docker exec -it redis - master redis - cli - a 123456
# 假設要存儲一個字符串set mykey myvalue
# 假設要存儲一個哈希表hset myhash field1 value1
用ls /data/redis/data/appendonly.aof?查看 AOF 文件是否生成。
如果存在,查看文件內容,能看到記錄的寫操作指令。