En esta guía, se explican las prácticas recomendadas que se deben tener en cuenta cuando se desarrollan aplicaciones según el Protocolo de RTB.
Administra conexiones
Mantén las conexiones activas
Establecer una conexión nueva aumenta las latencias y requiere muchos más recursos en ambos extremos que reutilizar una existente. Si cierras menos conexiones, puedes reducir la cantidad de conexiones que se deben volver a abrir.
En primer lugar, cada conexión nueva requiere un recorrido de red adicional para establecerse. Debido a que establecemos conexiones a pedido, la primera solicitud en una conexión tiene una fecha límite efectiva más corta y es más probable que se agote el tiempo de espera que las solicitudes posteriores. Cualquier tiempo de espera adicional aumenta la tasa de error, lo que puede provocar que se reduzca la velocidad de tu oferta.
En segundo lugar, muchos servidores web crean un subproceso de trabajo dedicado para cada conexión establecida. Esto significa que, para cerrar y volver a crear la conexión, el servidor debe cerrar y descartar un subproceso, asignar uno nuevo, hacerlo ejecutable y compilar el estado de la conexión antes de procesar la solicitud. Eso es mucha carga innecesaria.
Evita cerrar conexiones
Para comenzar, ajusta el comportamiento de la conexión. La mayoría de los valores predeterminados del servidor están diseñados para entornos con una gran cantidad de clientes, cada uno de los cuales realiza una pequeña cantidad de solicitudes. En el caso de la RTB, por el contrario, un pequeño grupo de máquinas envía solicitudes en nombre de una gran cantidad de navegadores, en términos relativos. En estas condiciones, tiene sentido volver a usar las conexiones tantas veces como sea posible. Te recomendamos que configures lo siguiente:
- Tiempo de espera de inactividad a 2.5 minutos.
- Es la cantidad máxima de solicitudes en una conexión al valor más alto posible.
- Cantidad máxima de conexiones al valor más alto que puede admitir tu RAM, y asegúrate de verificar que la cantidad de conexiones no se acerque demasiado a ese valor.
En Apache, por ejemplo, esto implicaría configurar KeepAliveTimeout
en 150, MaxKeepAliveRequests
en cero y MaxClients
en un valor que depende del tipo de servidor.
Una vez que se ajuste el comportamiento de la conexión, también debes asegurarte de que el código del ofertante no cierre conexiones innecesariamente. Por ejemplo, si tienes código de frontend que muestra una respuesta predeterminada de "sin oferta" en caso de errores de backend o tiempos de espera, asegúrate de que el código muestre su respuesta sin cerrar la conexión. De esta manera, evitas la situación en la que, si tu oferta se sobrecarga, las conexiones comienzan a cerrarse y aumenta la cantidad de tiempos de espera, lo que hace que se reduzca la oferta.
Mantén el equilibrio de las conexiones
Si Authorized Buyers se conecta a los servidores de tu oferta a través de un servidor proxy, es posible que las conexiones se desbalanceen con el tiempo, ya que, como solo se conoce la dirección IP del servidor proxy, Authorized Buyers no puede determinar qué servidor de oferta recibe cada texto destacado. Con el tiempo, a medida que Authorized Buyers establece y cierra conexiones, y se reinician los servidores del ofertante, la cantidad de conexiones asignadas a cada uno puede ser muy variable.
Cuando algunas conexiones se usan mucho, es posible que otras conexiones abiertas permanezcan inactivas porque no se necesitan en ese momento. A medida que cambia el tráfico de los compradores autorizados, las conexiones inactivas pueden volverse activas y las activas pueden inactivarse. Esto puede provocar cargas irregulares en los servidores de oferta si las conexiones están agrupadas de forma incorrecta. Google intenta evitar esto cerrando todas las conexiones después de 10,000 solicitudes para reequilibrar automáticamente las conexiones activas con el tiempo. Si aún notas que el tráfico se desequilibra en tu entorno, puedes seguir estos pasos:
- Selecciona el backend por solicitud en lugar de una vez por conexión si usas proxies de frontend.
- Especifica una cantidad máxima de solicitudes por conexión si usas un proxy para las conexiones a través de un balanceador de cargas o firewall de hardware, y la asignación se corrige una vez que se establecen las conexiones. Ten en cuenta que Google ya especifica un límite superior de 10,000 solicitudes por conexión, por lo que solo debes proporcionar un valor más estricto si aún encuentras conexiones activas que se agrupan en tu entorno. En Apache, por ejemplo, configura
MaxKeepAliveRequests
en 5,000. - Configura los servidores del ofertante para que supervisen sus tasas de solicitudes y cierren algunas de sus propias conexiones si, de forma constante, controlan demasiadas solicitudes en comparación con sus pares.
Controla la sobrecarga con facilidad
Lo ideal es que las cuotas se establezcan lo suficientemente altas como para que tu oferta pueda recibir todas las solicitudes que pueda controlar, pero no más. En la práctica, mantener las cuotas en niveles óptimos es una tarea difícil, y las sobrecargas ocurren por varios motivos: un backend se cae durante las horas pico, cambia una combinación de tráfico para que se requiera más procesamiento para cada solicitud o se establece un valor de cuota demasiado alto. Por lo tanto, vale la pena considerar cómo se comportará tu oferta con demasiado tráfico entrante.
Para adaptarse a los cambios temporales de tráfico (hasta una semana) entre regiones (especialmente entre Asia y EE.UU. Oeste, y EE.UU. Este y EE.UU. Oeste), recomendamos un margen del 15% entre el máximo de 7 días y las QPS por ubicación de mercado.
En términos de comportamiento bajo cargas pesadas, los ofertantes se dividen en tres categorías generales:
- El ofertante "responde a todo"
Si bien es sencillo de implementar, este ofertante tiene el peor rendimiento cuando se sobrecarga. Simplemente, intenta responder a cada solicitud de oferta que llega, sin importar nada, y pone en cola las que no se pueden publicar de inmediato. La situación que se produce suele ser algo como lo siguiente:
- A medida que aumenta la tasa de solicitudes, también lo hacen las latencias, hasta que todas las solicitudes comienzan a agotar el tiempo de espera.
- Las latencias aumentan rápidamente a medida que las tasas de textos destacados se acercan al máximo
- Se activa el control de límite, lo que reduce drásticamente la cantidad de textos destacados permitidos.
- Las latencias comienzan a recuperarse, lo que reduce la limitación
- El ciclo vuelve a comenzar.
El gráfico de latencia de este ofertante se asemeja a un patrón de sierra muy pronunciado. Como alternativa, las solicitudes en cola hacen que el servidor comience a paginar la memoria o haga algo más que cause una ralentización a largo plazo, y las latencias no se recuperan hasta que terminan las horas pico, lo que genera tasas de llamadas de atención deprimidas durante todo el período pico. En cualquier caso, se realizan o responden menos textos destacados que si la cuota se hubiera establecido en un valor más bajo.
- El ofertante con "error de sobrecarga"
Este ofertante acepta textos destacados hasta una tasa determinada y, luego, comienza a mostrar errores para algunos textos destacados. Esto se puede hacer a través de tiempos de espera internos, inhabilitando la fila de conexiones (controlada por
ListenBackLog
en Apache), implementando un modo de descarte probabilístico cuando la utilización o las latencias sean demasiado altas, o algún otro mecanismo. Si Google observa una tasa de error superior al 15%, comenzaremos a reducir la velocidad. A diferencia del ofertante que responde a todo, este ofertante "corta sus pérdidas", lo que le permite recuperarse de inmediato cuando disminuyen las tasas de solicitudes.El gráfico de latencia de este ofertante se asemeja a un patrón de sierra suave durante las sobrecargas, localizado alrededor de la tasa máxima aceptable.
- El ofertante que no realiza ofertas en sobrecarga
Este ofertante acepta textos destacados hasta una tasa determinada y, luego, comienza a mostrar respuestas de "sin oferta" para cualquier sobrecarga. Al igual que el ofertante de "error de sobrecarga", esto se puede implementar de varias maneras. La diferencia es que no se muestra ningún indicador a Google, por lo que nunca reducimos el tamaño de los textos destacados. Las máquinas del frontend absorben la sobrecarga, lo que solo permite que el tráfico que pueden controlar continúe hasta los backends.
El gráfico de latencia de este ofertante muestra una meseta que (de manera artificial) deja de ser paralela a la tasa de solicitudes en horas pico y una disminución correspondiente en la fracción de respuestas que contienen una oferta.
Te recomendamos que combines el "error de sobrecarga" con el enfoque de "sin oferta en sobrecarga" de la siguiente manera:
- Aprovisiona en exceso los frontends y configúralos para que generen errores en caso de sobrecarga para maximizar la cantidad de conexiones a las que pueden responder de alguna forma.
- Cuando se produce un error de sobrecarga, las máquinas de frontend pueden usar una respuesta predeterminada de "sin oferta" y no es necesario analizar la solicitud.
- Implementa la verificación de estado de los backends, de modo que, si ninguno tiene suficiente capacidad disponible, muestre una respuesta de "sin oferta".
Esto permite absorber parte de la sobrecarga y les brinda a los backends la oportunidad de responder exactamente tantas solicitudes como puedan controlar. Puedes considerar esto como "sin oferta en sobrecarga", con máquinas de frontend que recurren a "error en sobrecarga" cuando los recuentos de solicitudes son significativamente más altos de lo esperado.
Si tienes un ofertante que "responde a todo", considera transformarlo en un ofertante de "error de sobrecarga" ajustando el comportamiento de la conexión para que, en efecto, se niegue a sobrecargarse. Si bien esto hace que se muestren más errores, reduce los tiempos de espera y evita que el servidor entre en un estado en el que no pueda responder a ninguna solicitud.
Considera el intercambio de tráfico
Otra forma de reducir la latencia o la variabilidad de la red es establecer un vínculo con Google. El enrutamiento entre pares ayuda a optimizar la ruta que sigue el tráfico para llegar a tu oferta. Los extremos de conexión permanecen iguales, pero los vínculos intermedios cambian. Consulta la guía de peering para obtener más detalles. El motivo para considerar el peering como una práctica recomendada se puede resumir de la siguiente manera:
En Internet, los vínculos de tránsito se eligen principalmente a través del "enrutamiento de papas calientes", que encuentra el vínculo más cercano fuera de nuestra red que puede llevar un paquete a su destino y enruta el paquete a través de ese vínculo. Cuando el tráfico atraviesa una sección de la red troncal que pertenece a un proveedor con el que tenemos muchas conexiones de intercambio de datos, es probable que el vínculo elegido esté cerca de donde comienza el paquete. Más allá de ese punto, no tenemos control sobre la ruta que sigue el paquete al ofertante, por lo que es posible que se reenvíe a otros sistemas autónomos (redes) en el camino.
En cambio, cuando existe un acuerdo de intercambio de tráfico directo, los paquetes siempre se envían a través de un vínculo de intercambio de tráfico. Independientemente de dónde se origine el paquete, este atraviesa los vínculos que Google posee o alquila hasta que llega al punto de intercambio compartido, que debe estar cerca de la ubicación del ofertante. El viaje inverso comienza con un salto corto a la red de Google y permanece en la red de Google durante el resto del recorrido. Mantener la mayor parte del viaje en la infraestructura administrada por Google garantiza que el paquete tome una ruta de baja latencia y evite mucha variabilidad potencial.
Envía un DNS estático
Recomendamos que los compradores siempre envíen un solo resultado de DNS estático a Google y que confíen en Google para que controle la entrega del tráfico.
Estas son dos prácticas comunes de los servidores DNS de los ofertantes cuando intentan cargar el equilibrio o administrar la disponibilidad:
- El servidor DNS entrega una dirección, o un subconjunto de direcciones, en respuesta a una consulta y, luego, alterna esta respuesta de alguna manera.
- El servidor DNS siempre responde con el mismo conjunto de direcciones, pero alterna el orden de las direcciones en la respuesta.
La primera técnica es deficiente en el balanceo de cargas, ya que hay mucha almacenamiento en caché en varios niveles de la pila, y es probable que los intentos de omitir el almacenamiento en caché tampoco obtengan los resultados preferidos, ya que Google le cobra al ofertante el tiempo de resolución de DNS.
La segunda técnica no logra el balanceo de cargas, ya que Google selecciona de forma aleatoria una dirección IP de la lista de respuestas de DNS, por lo que no importa el orden de la respuesta.
Si un ofertante realiza un cambio en el DNS, Google respetará el TTL(tiempo de actividad) que se configuró en sus registros DNS, pero el intervalo de actualización seguirá siendo incierto.