Sur un reseau de 500 utilisateurs, la memoire n'est jamais un probleme. L'IRCd utilise 20-50 Mo et vous n'y pensez pas. A 5 000 utilisateurs, ca monte a 200-400 Mo. A 20 000, vous commencez a surveiller. A 50 000+, la gestion memoire devient un skill essentiel. Chaque octet par connexion, multiplie par des dizaines de milliers, finit par compter.
Combien consomme un IRCd
# Estimation par composant (approximatif) :
# Par connexion utilisateur :
# - Structure client : 2-5 Ko
# - Send queue (buffer sortant) : 8-64 Ko (configurable)
# - Receive queue : 8 Ko (configurable)
# - TLS state (si TLS) : 30-50 Ko
# - Hostname/IP/cloak : 0.5-1 Ko
# Total par connexion : 50-120 Ko avec TLS
# Par canal :
# - Structure canal : 1-2 Ko
# - Liste des membres : ~100 octets par membre
# - Ban list : ~200 octets par ban
# - Topic : variable
# Total par canal : 1-50 Ko (depend de la taille)
# Estimation globale :
# 1 000 users, 200 canaux : 80-120 Mo
# 5 000 users, 1 000 canaux : 300-500 Mo
# 10 000 users, 2 000 canaux : 600 Mo - 1 Go
# 50 000 users, 10 000 canaux : 3-5 Go
# Le facteur dominant est la send queue.
# Avec une sendq de 1 Mo par connexion et 10 000 users,
# la sendq seule peut consommer jusqu'a 10 Go
# (si tous les buffers sont pleins — rare en pratique).
Facteurs de consommation
- Send queue : Le plus gros consommateur. Chaque connexion a un buffer de sortie. Si un client est lent a recevoir, le buffer se remplit. Configurable et critique.
- TLS : Chaque connexion TLS consomme 30-50 Ko supplementaires pour l'etat TLS (session, cles, buffers). Avec 10 000 connexions TLS, c'est 300-500 Mo juste pour TLS.
- Nombre de canaux par utilisateur : Chaque inscription a un canal consomme de la memoire. Un utilisateur dans 20 canaux consomme plus qu'un utilisateur dans 2 canaux.
- Historique/buffer : Certains modules stockent l'historique des messages en memoire. Le module
historyd'InspIRCd ou les buffer de ZNC peuvent consommer beaucoup. - Ban lists : Les canaux avec des centaines de bans accumulent de la memoire. Un canal avec 500 bans consomme ~100 Ko juste en bans.
Send queues
# La send queue est le buffer de sortie par connexion.
# Quand le serveur a un message a envoyer a un client,
# il le met dans la send queue. Si le client ne lit pas
# assez vite, la queue se remplit.
# UnrealIRCd :
class clients {
sendq 1M; # Max 1 Mo par connexion
recvq 8192; # Max 8 Ko de buffer entrant
};
# Si la sendq atteint la limite, le client est
# deconnecte ("SendQ exceeded").
# Compromis :
# sendq trop petit (64 Ko) :
# Les clients sur des connexions lentes sont
# deconnectes trop souvent.
# sendq trop grand (5 Mo) :
# Un client lent accumule de la memoire.
# 10 000 clients lents x 5 Mo = 50 Go.
# Recommandation :
# Clients normaux : sendq 512K a 1M
# Operateurs : sendq 2M a 5M
# Serveurs links : sendq 20M (le trafic S2S est volumineux)
# InspIRCd :
# hardsendq : deconnexion si depasse
# softsendq : le serveur ralentit l'envoi
# La softsendq est un mecanisme de back-pressure
# qui previent le remplissage de la hardsendq.
# Surveiller les send queues :
# En tant qu'oper :
/STATS L
# Montre le SendQ actuel de chaque connexion
# Les gros SendQ indiquent des clients lents
Canaux et modes
# Limiter le nombre de canaux par utilisateur :
# Chaque canal rejoint = memoire supplementaire
# UnrealIRCd :
set {
max-channels-per-user 20; # Par defaut
# Reduire a 10 pour economiser la memoire
# sur les tres grands reseaux
};
# InspIRCd :
# Limiter la taille des ban lists :
# UnrealIRCd :
set {
maxbans 200; # Max 200 bans par canal
};
# InspIRCd :
# Redirect au lieu de ban
# Consomme moins qu'un ban classique
# Nettoyage periodique des canaux vides :
# Les canaux sans utilisateur sont automatiquement
# supprimes par l'IRCd (sauf si ChanServ les garde).
# Verifiez que ChanServ n'habite pas des centaines
# de canaux inutilises.
# Anope :
# Module inhabit : ChanServ reste dans le canal
# Consomme de la memoire pour chaque canal habite
# Desactivez sur les reseaux avec beaucoup de canaux :
module {
name = "chanserv"
inhabit = no # ChanServ ne reste pas dans les canaux
};
Impact des modules
Les modules ajoutent de la memoire, parfois de maniere significative :
- Modules de logging : Stockent des donnees en memoire avant ecriture. Impact faible mais constant.
- Modules d'historique : Stockent N derniers messages par canal en RAM. Impact potentiellement enorme : 100 canaux x 200 messages x 500 octets = 10 Mo.
- Modules DNSBL : Cache des resultats DNS. Impact modere (quelques Mo).
- Modules IRCv3 : Metadata supplementaires par message (tags, msgid). Impact faible par message mais s'additionne.
# Mesurer l'impact memoire d'un module :
# 1. Relever la memoire avant chargement
/STATS z # UnrealIRCd : stats memoire
# 2. Charger le module
/LOADMODULE nom_module
# 3. Relever la memoire apres
/STATS z
# Ou via le systeme :
ps aux | grep ircd
# Colonne RSS = memoire residente en Ko
# Modules a eviter sur les grands reseaux :
# - history (si pas necessaire)
# - tout module qui stocke des donnees par canal/user
# sans limite configurable
# Modules legers :
# - cloaking, sasl, cap : overhead negligeable
# - conn_waitpong : quelques octets par connexion pending
Tuning OS
# Linux sysctl pour un IRCd a forte charge :
# Limites de file descriptors :
fs.file-max = 200000
# Chaque connexion = 1 file descriptor
# Ajoutez aussi dans /etc/security/limits.conf :
# ircd soft nofile 100000
# ircd hard nofile 100000
# Memoire reseau :
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Backlog de connexions :
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
# Recyclage TIME_WAIT :
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# Overcommit (important pour les gros IRCds) :
vm.overcommit_memory = 0 # Defaut, conservateur
# Ne mettez PAS 1 (toujours overcommit) — si la
# memoire reelle est epuisee, l'OOM killer tue l'IRCd.
# Transparent hugepages :
# Pour les gros process (1Go+), les hugepages
# reduisent l'overhead de gestion memoire.
# Activer : echo always > /sys/kernel/mm/transparent_hugepage/enabled
# Desactiver si ca cause des latences :
# echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
Diagnostic
# Commandes de diagnostic memoire :
# UnrealIRCd :
/STATS z
# Affiche : memoire allouee, nombre de structures,
# taille des caches internes.
# InspIRCd :
/STATS z
# Similaire.
# Systeme :
# Memoire du processus :
ps -o pid,rss,vsz,comm -p $(pidof unrealircd)
# RSS = memoire residente (reelle)
# VSZ = memoire virtuelle (inclut les pages non utilisees)
# Suivi dans le temps :
while true; do
echo "$(date +%H:%M) $(ps -o rss= -p $(pidof unrealircd)) Ko"
sleep 60
done >> /tmp/ircd_mem.log
# Si la memoire croit continuellement sans se stabiliser,
# c'est un memory leak. Les causes courantes :
# - Module mal ecrit qui ne libere pas la memoire
# - Ban lists qui grossissent sans nettoyage
# - Clients zombies avec des send queues pleines
# Valgrind (pour debugger les leaks) :
# NE PAS utiliser en production — divise les
# performances par 10-20x.
valgrind --tool=massif --pages-as-heap=yes \
/home/ircd/unrealircd/bin/unrealircd -F
Questions frequentes
Combien de RAM pour 10 000 utilisateurs ?
Comptez 1-2 Go avec TLS. Sans TLS (deconseille), 500 Mo-1 Go. Prevoyez une marge de 50% pour les pics (netsplit rejoin, floods). Un serveur avec 4 Go de RAM gere confortablement 10 000 utilisateurs IRC avec TLS.
Faut-il du swap pour un IRCd ?
Oui, comme marge de securite. Mais si l'IRCd utilise le swap regulierement, c'est un signal d'alarme — ca signifie que la RAM est insuffisante et les performances seront degradees. Le swap doit etre la pour prevenir un OOM kill, pas pour fonctionner normalement.
Un IRCd utilise-t-il plusieurs coeurs CPU ?
La plupart des IRCds sont mono-thread (UnrealIRCd, InspIRCd). Ils n'utilisent qu'un seul coeur. Le CPU est rarement le facteur limitant pour IRC — la memoire et le reseau sont plus souvent les goulots d'etranglement. Un seul coeur moderne gere facilement 50 000+ utilisateurs IRC.