Exploring the roots and future of Internet Relay Chat

Reglage memoire d'un IRCd pour les grands reseaux

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 history d'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
Conseil : Surveillez les connexions avec un SendQ systematiquement eleve. Ce sont souvent des bots mal programmes, des clients derriere un proxy lent, ou des attaques de type slowloris. Deconnectez les chroniques pour liberer la memoire.

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
Attention : Un IRCd qui consomme de plus en plus de memoire sans se stabiliser a un memory leak. Ne le redemarrez pas periodiquement comme "solution" — identifiez et corrigez la cause. Les redemarrages programes masquent le probleme et deconnectent tous les utilisateurs.

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.