von Marc-David Militz
Forum: MongoDB Theorie
# mongod.conf
net:
maxIncomingConnections: 999999
Dabei gilt es zu beachten, dass MongoDB standardmäßig einen dedizierten Arbeitsthread für jede eingehende Verbindung erstellt. Um diese Standardeinstellung testen, muss man jedoch darauf hinweisen, dass eine verwandte Einstellung in einem Worker-Pool-Modell geändert werden muss.
https://docs.mongodb.com/manual/reference/configuration-options/#net.serviceExecutor
Dies ermöglicht vermutlich eine größere Anzahl eingehender Verbindungen und die Verwendung weniger Threads. Beachten Sie, dass diese Option auch dann als experimentell gekennzeichnet ist, wenn sie offiziell dokumentiert ist:
net:
serviceExecutor: adaptive
Für die Tests werden wir einen Thread pro Verbindung erstellen, daher wurde auch die folgende Konfiguration benötigt ...
# Connections are files because in Unix everything is a file.
echo "ec2-user soft nofile 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard nofile 9999999" | sudo tee -a /etc/security/limits.conf
# nproc is really number of threads.
echo "ec2-user soft nproc 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard nproc 9999999" | sudo tee -a /etc/security/limits.conf
# Threads need memory from the stack.
echo "ec2-user soft stack 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard stack 9999999" | sudo tee -a /etc/security/limits.conf
Weitere Informationen finden Sie in der MongoDB-Dokumentation zu den ulimit-Einstellungen.
https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
Doch einen Augenblick noch, es gibt noch mehr! Das Erstellen von Threads verwendet mmap, um Speicher zuzuweisen.
http://man7.org/linux/man-pages/man2/mmap.2.html
Und auf der Kernel-Ebene gibt es eine Einstellung für die maximale Anzahl von mmapped Speicherblöcken pro Prozess, die ebenfalls erhöht werden muss:
echo 9999999 > /proc/sys/vm/max_map_count
# If you want to persist across reboots
echo "vm.max_map_count=9999999" | sudo tee -a /etc/sysctl.conf
Schließlich wurden, auf dem Benchmark-Client, TCP / IP auf Einschränkungen festgestellt. Im TCP-Protokoll wird ein Socket mit dem Tupel (lokale Adresse, lokaler Port, entfernte Adresse, entfernter Port) identifiziert, und dieses Tupel muss pro Socket eindeutig sein. Die Portnummern reichen von 1 bis 65535, daher kann man von einem einzelnen Benchmark-Client nur 65535 ausgehende Verbindungen erstellen. Um mit mehr Verbindungen zu arbeiten, gibt es nur die Möglichkeit mehr als einen Client-Host oder mindestens mehr als eine IP-Adresse für den Client zu haben. Auf der Serverseite ist der Port natürlich der bekannte mongod Port 27017.
Etwas überraschend war die Erkenntnis, dass Linux standardmäßig nicht einmal die gesamte Palette von 65k-Ports nutzen würde, die TCP ermöglicht. Auch das musste konfiguriert werden:
echo 1024 65530 > /proc/sys/net/ipv4/ip_local_port_range
# If you want to persist across reboots
echo "net.ipv4.ip_local_port_range = 1024 65530" | sudo tee -a /etc/sysctl.conf
Die beiden Zahlen sind die min. Und max. Werte für ausgehende Ports. Beachten Sie, dass diese Konfiguration auf einem Server NICHT erforderlich ist, sondern nur auf dem Benchmark-Client.
# This assumes a fresh Linux host from standard Amazon Linux 2 images.
# Adaptable to Centos/RHEL too.
sudo su
sed -i .orig 's/net\:/net\:\n maxIncomingConnections: 999999/' /etc/mongod.conf
# Connections are files because in Unix everything is a file.
echo "ec2-user soft nofile 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard nofile 9999999" | sudo tee -a /etc/security/limits.conf
# nproc is really number of threads.
echo "ec2-user soft nproc 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard nproc 9999999" | sudo tee -a /etc/security/limits.conf
# Threads need memory from the stack.
echo "ec2-user soft stack 9999999" | sudo tee -a /etc/security/limits.conf
echo "ec2-user hard stack 9999999" | sudo tee -a /etc/security/limits.conf
# Threads allocate memory with mmap
echo 9999999 > /proc/sys/vm/max_map_count
# If you want to persist across reboots
echo "vm.max_map_count=9999999" | sudo tee -a /etc/sysctl.conf
# Needed for outgoing connections (on client)
echo 1024 65530 > /proc/sys/net/ipv4/ip_local_port_range
echo "net.ipv4.ip_local_port_range = 1024 65530" | sudo tee -a /etc/sysctl.conf
# Checks EC2 instance type but doesn't do anything about it
curl http://169.254.169.254/latest/meta-data/instance-type