Quelle est la pratique de limite sur la taille de paquet unique transmis sur socket de domaine?
Supposons qu'il y est un socket de domaine Unix créé pour un type de serveur-client. Le client envoie un de 10 go de mémoire tampon sur le support, et il est consommé par le serveur en même temps.
OS (Linux/BSD) de diviser les 10 GO de mémoire tampon dans nombre de paquets et d'envoyer les consommer, ou sont-ils envoyés à la fois?
Si il n'est pas possible d'envoyer de 10 go de mémoire tampon de socket de domaine d'un seul coup, alors qu'est-ce que la pratique de limite de taille d'un paquet unique?
Contraintes:
- Le programme sera exécuté sur Linux 2.6.32+ et FreeBSD 9+
- Taille de la mémoire tampon pour être envoyé varie de 3 octets à 10 go maximum.
- Il n'y a rien de "classique" pour un client qui envoie un de 10 go de mémoire tampon d'un seul coup. Typiquement, il va lire un peu de la source dans un tampon mesurée en KO, pas GO, et de l'envoyer en pièce par pièce.
- Savez-vous combien exactement j'ai pour briser les 10 GO de mémoire tampon? Chaque 1GB/1 MO?
- Howard, quel est le type de votre socket? Comment il a été créé et comment avez-vous send|recv de données?
- On dirait que c'est la réponse ici: stackoverflow.com/questions/4729315/...
Vous devez vous connecter pour publier un commentaire.
Il y a un certain nombre de facteurs qui vont déterminer le maximum de la taille d'un paquet peut être envoyé sur une socket Unix:
La
wmem_max
socket buffer de taille maximale paramètre du noyau, ce qui détermine la taille maximale de la mémoire tampon d'envoi qui peut être défini à l'aide desetsockopt (SO_SNDBUF)
. La valeur courante peut être lu à partir de/proc/sys/net/core/wmem_max
et peut être défini à l'aide desysctl net.core.wmem_max=VALUE
(ajouter le paramètre/etc/sysctl.conf
pour rendre le changement permanent dans l'ensemble des redémarrages). Remarque: ce paramètre s'applique à tous les sockets et des protocoles de prise, pas seulement pour les sockets Unix.Si plusieurs paquets sont envoyés à une socket Unix (à l'aide de SOCK_DATAGRAM), alors la quantité maximale de données qui peut être envoyée sans blocage dépend de la taille du tampon d'envoi socket (voir ci-dessus) et le nombre maximum de messages non-lus paquets sur la socket Unix (paramètre de noyau
net.unix.max_dgram_qlen
).Enfin, un paquet (SOCK_DATAGRAM) requiert la mémoire contiguë (comme par Quelle est la taille max de AF_UNIX datagramme message qui peut être envoyé dans linux?). Combien de mémoire contiguë est disponible dans le noyau dépend de nombreux facteurs (par exemple la charge d'e/S sur le système, etc...).
Afin de maximiser les performances de votre application, vous avez besoin d'un grand socket taille de la mémoire tampon (pour minimiser l'utilisateur/noyau contexte de l'espace de commutateurs due à la prise d'écriture appels système) et un grand socket Unix file d'attente (pour découpler le producteur et le consommateur autant que possible). Cependant, le produit de la socket taille du tampon d'envoi et de longueur de file d'attente ne doit pas être si grande que le noyau pour exécuter de mémoire contiguë domaines (causant des échecs d'écriture).
Les chiffres réels dépendent de la configuration de votre système et de son utilisation. Vous aurez besoin de déterminer les limites par des essais... commencer à dire avec
wmem_max
à 256 ko etmax_dgram_qlen
à 32 et de continuer à les doublerwmem_max
jusqu'à ce que vous remarquez des choses commencent à briser. Vous aurez besoin d'ajustermax_dgram_qlen
à l'équilibre de l'activité du producteur et du consommateur, dans une certaine mesure (bien que si le producteur est beaucoup plus rapide ou beaucoup plus lentement que la consommation, la taille de file d'attente n'aura pas beaucoup d'effet).Note de votre producteur devra spécifiquement le programme d'installation le support taille du tampon d'envoi à
wmem_max
octets avec un appel àsetsockopt (SO_SNDBUF)
et aura pour diviser les données enwmem_max
octet morceaux (et le consommateur devra remonter).Meilleure supposition: les limites pratiques seront autour de wmem_max ~8mo et unix_dgram_qlen ~32.
Il n'existe pas de "paquets" en soi avec des sockets de domaine. La sémantique de tcp "flux" ou udp "datagrammes" sont une sorte de simulation de w/je le noyau pour ressembler à l'utilisateur de l'espace des applications, mais c'est à peu près aussi loin qu'elle s'en va. Les mécaniciens ne sont pas aussi impliqués que les sockets réseau à l'aide de protocoles réseau. Ce qui vous intéresse vraiment ici c'est combien le noyau de la mémoire tampon pour vous.
À partir de votre programme, cela n'a pas vraiment d'importance. Pensez à la prise comme un tuyau ou une FIFO. Lorsque le tampon se remplit que vous allez à bloquer; si la socket est non-bloquant vous allez obtenir à court écrit (en supposant que les cours d'eau) ou de l'erreur EAGAIN. Cela est vrai quelle que soit la taille de la mémoire tampon. Cependant, vous devriez être en mesure de requête de la taille de la mémoire tampon avec
getsockopt
et à accroître sa taille avecsetsockopt
mais je doute que vous allez obtenir n'importe où près de 10 go.Sinon, vous pouvez regarder
sendfile
.Il y a deux idées ici. L'un est la taille du paquet envoyé si vous utilisez SOCK_DGRAM et l'autre est la taille de la mémoire tampon pour le socket de domaine. Cela dépend du jeu de variables avec le socket de domaine. La taille peut dépendre si c'est un fichier de la mémoire de socket.
Si vous parlez SOCK_DGRAM, il est facilement déterminée par l'expérience. Il semble beaucoup plus probable que vous parlez SOCK_STREAM, auquel cas il n'a tout simplement pas d'importance. SOCK_STREAM seront le tri extérieure vous. Il suffit d'écrire dans n'importe quelle taille que les morceaux que vous aimez: le plus grand mieux.