Quizás con las conexiones modernas no se note demasiado, pero con un modem
de 56k si que se sigue notando. Me refiero a la siguiente curiosidad que
muchos sabrán y otros no y que me apetece contar: No estás utilizando la
red y empiezas a bajarte algo, y la conexión pronto llega, si el servidor
tiene el ancho de banda suficiente y la ruta entre él y tu equipo es
adecuada, a su "tope". Sin embargo, si según te estás bajando ese archivo
comienzas a bajarte otro, este segundo archivo comienza bajándose a un
ancho de banda bajísimo, ridículo, que aumenta progresiva y lentamente al
mismo tiempo que el ritmo de descarga del primer archivo disminuye. A
veces, si la primera descarga baja muy rapido y/o la luna está en cuarto
creciente, la segunda descarga empieza tan lento que simplemente no llega a
empezar: Salta algún timeout en algún lado y se cierra la conexión. ¿Por
qué ocurre todo esto?
La respuesta está en un control de congestión que se implementa en todas
las pilas TCP/IP. Pero como tantas otras cosas, tiene su historia.
En los albores de internet, no existía ningún tipo de control de congestión
verdadero. Simplemente se mandaban los paquetes a la máxima velocidad que
daba de si la interfaz de red. Si la interfaz del receptor era muy lenta y
no podía recibir todos los paquetes a esa velocidad, simplemente se perdían
los paquetes (la red no es como un embudo: si metes más informacion de la
que cabe no se "acumula", se pierde lo sobrante). El rápido emisor
reenviaba lo perdido, y continuaba mandando más, hasta el proximo
embotellamiento.
En los albores de internet esto funcionó bien, pero cuando creció internet
este problema se hizo muy grande. Sospecho (no lo he confirmado, pero mi
sentido arácnido me dice que mis sospechas son ciertas) que los orígenes
del problema vinieron de la propia expansión de internet: En un inicio
había pocos ordenadores conectados a internet, las redes eran financiadas
por caros proyectos de investigación y siempre estaban a la última y tenían
velocidades parecidas. Los embotellamientos no eran un gran problema. Pero
cuando internet creció, las diferencias de capacidad entre unas redes y
otras se acrecentaron. Y hubo que crear mayores redes de interconexión
entre las principales redes, que a veces tenían menor ancho de banda que
los equipos: Por mucho que un emisor y un receptor tuvieran una conexión de
X KB/s, si entre ellas había una red con X/2 KB/s, la conexión solo iba
poder ir a X/2 KB/s.
Esto hizo que en el 86 y en adelante empezaran a detectarse auténticos
colapsos de internet, pérdida masiva de paquetes. Era imposible enviar
datos a ciertos sitios y era imposible descargarse emacs de una vez, había
que bajarselo en trocitos. En aquellos tiempos las grandes interconexiones
de backbones de Internet iban a 56 Kbps. Cundió la duda: ¿Era TCP incapaz
de escalar a mayores velocidades? ¿Había que rehacer toda la tecnología?
¿Dónde estaba el fallo? La solución se dió en la reunión USENIX de 1989. Se
presentó una charla titulada "Congestión Avoidance and Control", que
presentaba una serie de algoritmos, que fueron implementados en forma de
parche en los sistemas operativos que controlaban los grandes núcleos de
internet - BSDs. Se hizo un RFC que ordenaba literalmente implementar este
sistema de congestión de control. Una de las personas que había escrito ese
documento se llamaba Van Jacobson. Ha trabajado toda la vida en TCP/IP, ha
escrito importantes documentos y ha colaborado tambien en varios RFCs. Los
que hayan utilizado alguna vez un modem, ¿han oido alguna vez manejando
pppd de una compresión de cabeceras IP apodada "VJ compression"? Pues las
iniciales VJ pertenecen, efectivamente, a Van Jacobson. Por cierto: Este
tipo aun trabaja en asuntos de TCP/IP, utiliza mucho con Linux, dice que
Linux tiene la pila TCP/IP más rápida y mejor del planeta -esto va por los
que dicen que Linux es un SO de juguete-, e incluso presentó una charla
sobre una proposición de diseño de la pila tcp/ip para aprovechar las
capacidades del hardware del futuro.
Pero me desvio. ¿En que consistía el sistema de control de congestión? Es
un sistema simple: La técnica se apodaba "slow-start". Se empezaba mandando
un paquete. Si el paquete llegaba correctamente -según el protocolo TCP, el
receptor debe confirmar con un ACK la llegada del paquete-, la próxima vez
se enviaban dos paquetes: Uno por el paquete por el que llegó el ACK, y
otro más que se añade. Si esos dos llegaban bien, la siguiente vez se
mandaban cuatro: dos por los ACKs, y otros dos que se añaden, uno por ACK.
Etc. Cada conexión guarda en una variable el número de paquetes enviados,
para saber cuantos necesitaba enviar la próxima vez. Asi, se comienza la
conexión progresivamente, hasta llegar al límite de la conexión entre los
dos equipos. Cuando se llegaba al límite -dejaban de llegar paquetes
correctamente al receptor-, entraba en juego el control de congestión: en
vez de incrementarse tan rápido se incrementaba más lentamente. ¿Y como se
detecta la congestión? Pues cuando ocurre un timeout (no llega un ACK para
un paquete en un tiempo limitado), se anota en una variable ssthresh
(independiente para cada conexión) la mitad de la otra variable, la que
controla el numero de paquetes que se envian, y se resetea la cantidad de
paquetes que puede enviar la conexión a uno, desde el principio. Mientras
la cantidad de paquetes sea menor que sshtresh, se sigue haciendo
"slow-start", cuando llega a sshtresh -la mitad del ancho de banda que nos
hizo llegar a un timeout anteriormente- se comienza a incrementar
lentamente: control de congestión.
Es decir, aunque matemáticamente sea algo más dificil de entender, hace lo
obvio: Manda paquetes hasta que ve que la conexión no da mas -se detecta un
timeoput- y entonces empieza a enviar menos y a dejar de aumentar
rapidamente el ritmo. A día de hoy existen algoritmos mucho más complejos y
muy diferentes, optimizados para diferentes situaciones -en redes wireless
hay muchas pérdidas de paquetes por razones distintas al ancho de banda, y
con el slow-start el rendimiento es subóptimo- pero todos tienen algo en
común con éste: El control de congestión.
¿Como se refleja esto en nuestras descargas, que es lo que motivó esta
entrada? Fácil: Cuando empezamos a descargar un solo archivo, la velocidad
aumenta rápidamente. Pero si estamos descargando un archivo y empezamos a
descargar otro, la situación es distinta: La conexión ya está
aproximadamente en su máximo. Eso provoca que la segunda conexión empiece a
perder paquetes al no caber más datos en la conexión. El servidor que envia
el segundo archivo, al detectar los timeouts provocados por las pérdidas,
baja la velocidad de la conexión para adaptarse, y la aumenta lentamente,
para controlar lo que él cree que es "congestión". Al mismo tiempo la
primera descarga, ante este pequeño incremento de ancho de banda por parte
de la segunda descarga, empieza a perder paquetes, con lo cual el servidor
del primer archivo baja un poco la velocidad de envio. Y así es como más o
menos las dos descargas empiezan a equilibrarse. A veces no llegan a
equilibrarse, todo depende de mil factores, pero el sistema básico es este.
http://diegocg.blogspot.com/2007/03...enzan.html
Leer las respuestas