Created
July 28, 2024 09:14
-
-
Save corporatepiyush/a9a1d55a5c13d703aa85e06633dd0a65 to your computer and use it in GitHub Desktop.
Memory allocation control for Linux OS process and managing overflow with swap files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Configuration | |
NODE_APP="your-app.js" | |
CGROUP_NAME="nodejs_group" | |
MEMORY_LIMIT="4G" | |
SWAP_SIZE="8G" | |
SWAPFILE="/swapfile" | |
SWAPPINESS=60 | |
ZSWAP_ENABLED=1 | |
ZSWAP_COMPRESSOR="lz4" | |
ZSWAP_MAX_POOL_PERCENT=20 | |
# Function to log messages | |
log() { | |
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | |
} | |
# Check if running as root | |
if [ "$(id -u)" != "0" ]; then | |
log "This script must be run as root" | |
exit 1 | |
fi | |
# Function to convert sizes to bytes | |
to_bytes() { | |
local size=$1 | |
case ${size: -1} in | |
G|g) echo $((${size::-1} * 1024 * 1024 * 1024)) ;; | |
M|m) echo $((${size::-1} * 1024 * 1024)) ;; | |
K|k) echo $((${size::-1} * 1024)) ;; | |
*) echo $size ;; | |
esac | |
} | |
# Setup cgroup | |
setup_cgroup() { | |
log "Setting up cgroup..." | |
if mount | grep "cgroup2" > /dev/null; then | |
# cgroup v2 | |
mkdir -p /sys/fs/cgroup/$CGROUP_NAME | |
echo "+memory" > /sys/fs/cgroup/$CGROUP_NAME/cgroup.subtree_control | |
echo $(to_bytes $MEMORY_LIMIT) > /sys/fs/cgroup/$CGROUP_NAME/memory.max | |
log "Cgroup v2 created with memory limit: $MEMORY_LIMIT" | |
else | |
# cgroup v1 | |
cgcreate -g memory:$CGROUP_NAME | |
echo $(to_bytes $MEMORY_LIMIT) > /sys/fs/cgroup/memory/$CGROUP_NAME/memory.limit_in_bytes | |
log "Cgroup v1 created with memory limit: $MEMORY_LIMIT" | |
fi | |
} | |
# Setup swap space with compression | |
setup_swap() { | |
log "Setting up swap space with compression..." | |
# Enable zswap | |
if [ -d "/sys/module/zswap" ]; then | |
echo $ZSWAP_ENABLED > /sys/module/zswap/parameters/enabled | |
echo $ZSWAP_COMPRESSOR > /sys/module/zswap/parameters/compressor | |
echo $ZSWAP_MAX_POOL_PERCENT > /sys/module/zswap/parameters/max_pool_percent | |
log "zswap enabled with compressor: $ZSWAP_COMPRESSOR, max pool: $ZSWAP_MAX_POOL_PERCENT%" | |
else | |
log "zswap module not available. Proceeding without swap compression." | |
fi | |
if [ -f $SWAPFILE ]; then | |
log "Swapfile already exists. Skipping creation." | |
else | |
log "Creating swapfile..." | |
if ! fallocate -l $SWAP_SIZE $SWAPFILE; then | |
log "Failed to create swapfile. Trying dd method..." | |
if ! dd if=/dev/zero of=$SWAPFILE bs=1G count=${SWAP_SIZE%G} status=progress; then | |
log "Failed to create swapfile" | |
return 1 | |
fi | |
fi | |
chmod 600 $SWAPFILE | |
if ! mkswap $SWAPFILE; then | |
log "Failed to set up swap area" | |
return 1 | |
fi | |
fi | |
if swapon $SWAPFILE; then | |
log "Swap space activated: $SWAP_SIZE" | |
else | |
log "Failed to activate swap space" | |
return 1 | |
fi | |
# Set swappiness | |
if sysctl -w vm.swappiness=$SWAPPINESS; then | |
log "Swappiness set to $SWAPPINESS" | |
else | |
log "Failed to set swappiness" | |
return 1 | |
fi | |
return 0 | |
} | |
# Run Node.js application | |
run_node_app() { | |
log "Starting Node.js application..." | |
if mount | grep "cgroup2" > /dev/null; then | |
# cgroup v2 | |
systemd-run --unit=nodejs_app --scope -p MemoryMax=$(to_bytes $MEMORY_LIMIT) node $NODE_APP | |
else | |
# cgroup v1 | |
cgexec -g memory:$CGROUP_NAME node $NODE_APP | |
fi | |
} | |
# Main execution | |
setup_cgroup | |
if ! setup_swap; then | |
log "Failed to set up swap. Exiting." | |
exit 1 | |
fi | |
run_node_app | |
# Cleanup (uncomment if needed) | |
# log "Cleaning up..." | |
# swapoff $SWAPFILE | |
# rm $SWAPFILE | |
# if mount | grep "cgroup2" > /dev/null; then | |
# rmdir /sys/fs/cgroup/$CGROUP_NAME | |
# else | |
# cgdelete memory:$CGROUP_NAME | |
# fi | |
log "Script completed." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment