This commit is contained in:
Your Name
2025-07-24 16:13:07 +08:00
parent 07244800f7
commit 605d06ba5c
+222 -1
View File
@@ -283,7 +283,12 @@ in
};
# Cluster management utilities
environment.systemPackages = [ pkgs.redis ];
environment.systemPackages = [
pkgs.redis
(pkgs.writeShellScriptBin "redis-cluster-rebuild" ''
exec /etc/redis-cluster-rebuild.sh "$@"
'')
];
# Create helper scripts
environment.etc."redis-cluster-info.sh" = {
@@ -306,5 +311,221 @@ in
'';
mode = "0755";
};
environment.etc."redis-cluster-rebuild.sh" = {
text = ''
#!/bin/bash
set -e
# Configuration from NixOS
MASTERS=${toString cfg.masters}
REPLICAS_PER_MASTER=${toString cfg.replicasPerMaster}
BASE_PORT=${toString cfg.basePort}
ANNOUNCE_IP="${cfg.announceIp}"
echo "Redis Cluster Rebuild Script"
echo "============================"
echo "Masters: $MASTERS"
echo "Replicas per master: $REPLICAS_PER_MASTER"
echo "Base port: $BASE_PORT"
echo "Announce IP: $ANNOUNCE_IP"
echo ""
# Function to stop all Redis services
stop_redis_services() {
echo "Stopping Redis services..."
# Stop cluster init service first
systemctl stop redis-cluster-init.service 2>/dev/null || true
# Stop all master services
for i in $(seq 0 $((MASTERS - 1))); do
echo " Stopping redis-master-$i..."
systemctl stop redis-master-$i.service 2>/dev/null || true
done
# Stop all replica services
for master_idx in $(seq 0 $((MASTERS - 1))); do
for replica_idx in $(seq 0 $((REPLICAS_PER_MASTER - 1))); do
echo " Stopping redis-replica-$master_idx-$replica_idx..."
systemctl stop redis-replica-$master_idx-$replica_idx.service 2>/dev/null || true
done
done
echo "All Redis services stopped."
}
# Function to clean Redis data directories
clean_redis_data() {
echo "Cleaning Redis data directories..."
# Remove main Redis data directory
if [ -d "/var/lib/redis" ]; then
echo " Removing /var/lib/redis..."
rm -rf /var/lib/redis
fi
# Remove any cluster configuration files from working directories
for i in $(seq 0 $((MASTERS - 1))); do
local port=$((BASE_PORT + i))
rm -f /var/lib/redis*/nodes-$port.conf 2>/dev/null || true
rm -f /tmp/nodes-$port.conf 2>/dev/null || true
rm -f ./nodes-$port.conf 2>/dev/null || true
done
# Remove replica cluster config files
for master_idx in $(seq 0 $((MASTERS - 1))); do
for replica_idx in $(seq 0 $((REPLICAS_PER_MASTER - 1))); do
local port=$((BASE_PORT + MASTERS + master_idx * REPLICAS_PER_MASTER + replica_idx))
rm -f /var/lib/redis*/nodes-$port.conf 2>/dev/null || true
rm -f /tmp/nodes-$port.conf 2>/dev/null || true
rm -f ./nodes-$port.conf 2>/dev/null || true
done
done
echo "Redis data directories cleaned."
}
# Function to start Redis services
start_redis_services() {
echo "Starting Redis services..."
# Start all master services
for i in $(seq 0 $((MASTERS - 1))); do
echo " Starting redis-master-$i..."
systemctl start redis-master-$i.service
done
# Start all replica services
for master_idx in $(seq 0 $((MASTERS - 1))); do
for replica_idx in $(seq 0 $((REPLICAS_PER_MASTER - 1))); do
echo " Starting redis-replica-$master_idx-$replica_idx..."
systemctl start redis-replica-$master_idx-$replica_idx.service
done
done
echo "All Redis services started."
}
# Function to wait for Redis services to be ready
wait_for_redis() {
echo "Waiting for Redis services to be ready..."
# Wait for masters
for i in $(seq 0 $((MASTERS - 1))); do
local port=$((BASE_PORT + i))
echo " Waiting for master on port $port..."
for attempt in $(seq 1 30); do
if ${pkgs.redis}/bin/redis-cli -p $port ping >/dev/null 2>&1; then
echo " Master on port $port is ready."
break
fi
if [ $attempt -eq 30 ]; then
echo " ERROR: Master on port $port failed to start!"
exit 1
fi
sleep 1
done
done
# Wait for replicas
for master_idx in $(seq 0 $((MASTERS - 1))); do
for replica_idx in $(seq 0 $((REPLICAS_PER_MASTER - 1))); do
local port=$((BASE_PORT + MASTERS + master_idx * REPLICAS_PER_MASTER + replica_idx))
echo " Waiting for replica on port $port..."
for attempt in $(seq 1 30); do
if ${pkgs.redis}/bin/redis-cli -p $port ping >/dev/null 2>&1; then
echo " Replica on port $port is ready."
break
fi
if [ $attempt -eq 30 ]; then
echo " ERROR: Replica on port $port failed to start!"
exit 1
fi
sleep 1
done
done
done
echo "All Redis services are ready."
}
# Function to create the cluster
create_cluster() {
echo "Creating Redis cluster..."
# Build master nodes list
MASTER_NODES=""
for i in $(seq 0 $((MASTERS - 1))); do
local port=$((BASE_PORT + i))
MASTER_NODES="$MASTER_NODES $ANNOUNCE_IP:$port"
done
echo " Master nodes:$MASTER_NODES"
echo " Creating cluster with $REPLICAS_PER_MASTER replicas per master..."
${pkgs.redis}/bin/redis-cli --cluster create $MASTER_NODES --cluster-replicas $REPLICAS_PER_MASTER --cluster-yes
echo "Redis cluster created successfully!"
}
# Function to show cluster status
show_cluster_status() {
echo ""
echo "Cluster Status:"
echo "==============="
${pkgs.redis}/bin/redis-cli -p $BASE_PORT cluster nodes
echo ""
${pkgs.redis}/bin/redis-cli -p $BASE_PORT cluster info
}
# Main execution
case "''${1:-rebuild}" in
"stop")
stop_redis_services
;;
"clean")
clean_redis_data
;;
"start")
start_redis_services
wait_for_redis
;;
"create")
create_cluster
show_cluster_status
;;
"rebuild"|"")
echo "Full rebuild process starting..."
stop_redis_services
sleep 2
clean_redis_data
start_redis_services
wait_for_redis
sleep 3
create_cluster
show_cluster_status
echo ""
echo "Redis cluster rebuild completed successfully!"
;;
"status")
show_cluster_status
;;
*)
echo "Usage: $0 [stop|clean|start|create|rebuild|status]"
echo ""
echo "Commands:"
echo " stop - Stop all Redis services"
echo " clean - Remove Redis data directories"
echo " start - Start all Redis services"
echo " create - Create the cluster (services must be running)"
echo " rebuild - Full rebuild (stop, clean, start, create) [default]"
echo " status - Show cluster status"
exit 1
;;
esac
'';
mode = "0755";
};
};
}