Lista de comprobación de rendimiento y escalabilidad de Queue Storage
Microsoft ha creado muchos procedimientos de demostrada eficacia para desarrollar aplicaciones de alto rendimiento con Queue Storage. Esta lista de comprobación identifica los procedimientos clave que pueden seguir los desarrolladores para optimizar su rendimiento. Tenga presente estos procedimientos tanto para diseñar su aplicación como a lo largo de todo el proceso.
Azure Storage tiene objetivos de escalabilidad y rendimiento en lo que se refiere a capacidad, tasa de transacciones y ancho de banda. Para más información sobre los objetivos de escalabilidad de Azure Storage, consulte Objetivos de escalabilidad y rendimiento para cuentas de almacenamiento estándar y Objetivos de escalabilidad y rendimiento de Queue Storage.
Lista de comprobación
En este artículo se organizan los procedimientos de eficacia probada a la hora de mejorar el rendimiento en una lista de comprobación que puede seguir al desarrollar su aplicación en Queue Storage.
Objetivos de escalabilidad
Si su aplicación se aproxima o supera cualquiera de estos objetivos de escalabilidad, puede notar que aumenta la limitación o las latencias de las transacciones. Cuando Azure Storage limita su aplicación, el servicio empieza a devolver códigos de error 503 (Server Busy
) o 500 (Operation Timeout
). Evitar estos errores, mediante la permanencia en los límites de los objetivos de escalabilidad, es una parte importante de la mejora del rendimiento de la aplicación.
Para más información acerca de los objetivos de escalabilidad de Queue Storage, consulte Objetivos de escalabilidad y rendimiento de Azure Storage en cuentas de almacenamiento.
Número máximo de cuentas de almacenamiento
Si se aproxima al número máximo de cuentas de almacenamiento permitido para una combinación de suscripción/región concreta, ¿usa varias cuentas de almacenamiento para la partición para aumentar la entrada, la salida, las operaciones de E/S por segundo o la capacidad? En este escenario, Microsoft recomienda aprovechar las ventajas del aumento de los límites de las cuentas de almacenamiento para reducir el número de cuentas de almacenamiento necesarias para la carga de trabajo, siempre que sea posible. Póngase en contacto con el soporte técnico de Azure para solicitar el aumento de los límites de la cuenta de almacenamiento.
Objetivos de capacidad y transacción
Si su aplicación se aproxima a los objetivos de escalabilidad para una sola cuenta de almacenamiento, plantéese la adopción de uno de los siguientes enfoques:
- Si los objetivos de escalabilidad de las colas no son suficientes para su aplicación, use varias colas y distribuya los mensajes entre ellas.
- Reconsidere la carga de trabajo que hace que su aplicación se aproxime al objetivo de escalabilidad o lo supere. ¿Puede designarla de forma diferente para que use menos ancho de banda o capacidad, o menos transacciones?
- Si su aplicación debe superar uno de los objetivos de escalabilidad, cree varias cuentas de almacenamiento y realice particiones de los datos de su aplicación entre esas cuentas. Si usa este patrón, entonces debe asegurarse de designar la aplicación de forma que pueda agregar más cuentas de almacenamiento en el futuro para equilibrio de carga. Las propias cuentas de almacenamiento no tienen ningún costo aparte del de su uso en términos de datos almacenados, transacciones realizadas o datos transferidos.
- Si la aplicación se aproxima a los objetivos de ancho de banda, considere la posibilidad de comprimir los datos en el cliente para reducir el ancho de banda necesario para enviar los datos a Azure Storage. Aunque comprimir datos puede ahorrar ancho de banda y mejorar el rendimiento de la red, también puede tener efectos negativos en el rendimiento. Evalúe el impacto en el rendimiento de los requisitos de procesamiento adicionales para la compresión y descompresión de datos en el cliente. Tenga en cuenta que el almacenamiento de los datos comprimidos puede dificultar la solución de problemas, ya que es muy probable que sea más complicado ver los datos con herramientas estándar.
- Si la aplicación se acerca a los objetivos de escalabilidad, asegúrese de que usa un retroceso exponencial para los reintentos. Es recomendable que intente evitar llegar a los objetivos de escalabilidad mediante la implementación de las recomendaciones que se describen en este artículo. Sin embargo, el uso de un retroceso exponencial para los reintentos impide que la aplicación vuelva a intentarlo rápidamente, lo que podría empeorar la limitación. Para más información, consulte la sección Errores debidos al tiempo de expiración y a que el servidor está ocupado.
Redes
Las restricciones de red físicas de la aplicación pueden tener un impacto considerable en el rendimiento. En las siguientes secciones se describen algunas de las limitaciones que pueden observar los usuarios.
Capacidad de red del cliente
El ancho de banda y la calidad del vínculo de red juegan roles importantes en el rendimiento de la aplicación, como se describe en las secciones siguientes.
Throughput
Para el ancho de banda, el problema suele residir en las capacidades del cliente. Las instancias de Azure mayores tienen NIC con mayor capacidad, por lo que debe plantearse la posibilidad de usar una instancia mayor o más máquinas virtuales si necesita aumentar los límites de red de una sola máquina. Si accede a Azure Storage desde una aplicación local, se aplica la misma regla: conozca las capacidades de red del dispositivo cliente y la conectividad de red con la ubicación de Azure Storage y mejórelas según sea necesario, o diseñe la aplicación para que funcione dentro de sus capacidades.
Calidad del vínculo
Como siempre que se usa la red, tenga en cuenta que las condiciones de la red generan errores y la pérdida de paquetes reduce el rendimiento efectivo. El uso de Wireshark o de Monitor de red puede ayudar a diagnosticar este problema.
Location
En cualquier entorno distribuido, la ubicación del cliente cerca del servidor ofrece el mejor rendimiento. Para acceder a Azure Storage con la mínima latencia, la mejor ubicación para el cliente es dentro de la misma región de Azure. Por ejemplo, si tiene una aplicación web de Azure que usa Azure Storage, coloque ambas en una sola región, como Oeste de EE. UU. o Sudeste de Asia. La colocalización reduce la latencia y el costo, ya que el uso del ancho de banda dentro de una sola región es gratuito.
Si las aplicaciones cliente acceden a Azure Storage, pero no están hospedadas en Azure, como por ejemplo, las aplicaciones de dispositivos móviles o los servicios empresariales locales, la colocación de la cuenta de almacenamiento en una región próxima a los clientes puede reducir la latencia. Si los clientes están distribuidos en sitios distantes (por ejemplo, algunos en Norteamérica y otros en Europa), considere la posibilidad de usar una cuenta de almacenamiento por región. Este enfoque es más sencillo de implementar si los datos que almacena la aplicación son específicos de usuarios individuales y no se requiere la replicación de datos entre cuentas de almacenamiento.
SAS y CORS
Supongamos que necesita autorizar código, como JavaScript, que se ejecuta en el explorador web de un usuario o en una aplicación de teléfono móvil para acceder a los datos de Azure Storage. Un enfoque consiste en crear una aplicación de servicio que actúe como proxy. El dispositivo del usuario se autentica con el servicio, que a su vez autoriza el acceso a los recursos de Azure Storage. De esta forma, puede evitar la exposición de sus claves de cuenta de almacenamiento en dispositivos no seguros. Sin embargo, este enfoque supone una importante sobrecarga para la aplicación de servicio, ya que todos los datos transferidos entre el dispositivo del usuario y Azure Storage deben pasar por la aplicación de servicio.
El uso de firmas de acceso compartido (SAS) le permite evitar el uso de una aplicación de servicio como proxy para Azure Storage. Mediante SAS se puede permitir que el dispositivo del usuario realice solicitudes directamente en Azure Storage mediante un token de acceso limitado. Por ejemplo, si un usuario desea cargar una foto en la aplicación, la aplicación de servicio puede generar una SAS y enviarla al dispositivo del usuario. El token de SAS puede conceder permiso para escribir en un recurso de Azure Storage durante un intervalo de tiempo especificado, después del cual expirará el token. Para obtener más información sobre las firmas de acceso compartido, consulte Otorgar acceso limitado a recursos de Azure Storage con firmas de acceso compartido (SAS).
Por lo general, los exploradores web no permiten que haya código JavaScript en una página hospedada por un sitio web de un dominio que realiza operaciones concretas, como operaciones de escritura, en otro dominio. Esta directiva, que se conoce como directiva de mismo origen, impide que un script malintencionado de una página acceda a los datos de otra página web. Sin embargo, la directiva de mismo origen puede ser una limitación al compilar una solución en la nube. El uso compartido de recursos entre orígenes (CORS) es una característica del explorador que permite al dominio de destino comunicarle al explorador en el que confía solicitudes que se originan en el dominio de origen.
Por ejemplo, supongamos que una aplicación web que se ejecuta en Azure realiza una solicitud de un recurso en una cuenta de Azure Storage. La aplicación web es el dominio de origen y la cuenta de almacenamiento es el dominio de destino. Puede configurar CORS para que cualquiera de los servicios de Azure Storage comunique al explorador web que Azure Storage confía en las solicitudes del dominio de origen. Para más información sobre CORS, consulte Soporte técnico del uso compartido de recursos entre orígenes (CORS) para Azure Storage.
Tanto SAS como CORS pueden evitar una carga innecesaria en la aplicación web.
Configuración de .NET
Para proyectos que usan .NET Framework, esta sección enumera algunas configuraciones rápidas que puede usar para realizar mejoras de rendimiento significativas. Si usa un lenguaje distinto de .NET, compruebe si se aplican conceptos similares en el lenguaje elegido.
Aumento del límite de conexiones predeterminado
Nota:
Esta sección se aplica a los proyectos que usan .NET Framework, ya que la agrupación de conexiones se controla mediante la clase ServicePointManager. .NET Core introdujo un cambio significativo en la administración del grupo de conexiones, donde la agrupación de conexiones se produce en el nivel HttpClient y el tamaño del grupo no está limitado de forma predeterminada. Esto significa que las conexiones HTTP se escalan automáticamente para satisfacer la carga de trabajo. Se recomienda usar la versión más reciente de .NET, siempre que sea posible, para aprovechar las mejoras de rendimiento.
Con los proyectos que utilizan .NET Framework, puede usar el siguiente código para aumentar el límite de conexiones predeterminado (que normalmente es 2 en un entorno de cliente o 10 en un entorno de servidor) a 100. Normalmente, debe establecer el valor en aproximadamente el número de subprocesos usados por su aplicación. Establezca el límite de conexiones antes de abrir cualquier conexión.
ServicePointManager.DefaultConnectionLimit = 100; //(Or More)
Para más información sobre los límites del grupo de conexiones en .NET Framework, consulte Límites del grupo de conexiones de .NET Framework y el nuevo Azure SDK para .NET.
En el caso de otros lenguajes de programación, consulte la documentación del lenguaje en cuestión para determinar cómo establecer el límite de conexiones.
Aumento del número mínimo de subprocesos
Si usa llamadas sincrónicas junto con tareas asincrónicas, puede que quiera aumentar el número de subprocesos del grupo de subprocesos:
ThreadPool.SetMinThreads(100,100); //(Determine the right number for your application)
Para más información, consulte el método ThreadPool.SetMinThreads.
Paralelismo sin enlazar
Aunque el paralelismo puede ser excelente para el rendimiento, tenga cuidado al usar el paralelismo sin enlazar, lo que significa que no se aplica ningún límite en cuanto al número de subprocesos o solicitudes paralelas. Asegúrese de limitar las solicitudes paralelas para cargar o descargar datos, para acceder a varias particiones de la misma cuenta de almacenamiento o para acceder a varios elementos de la misma partición. Si el paralelismo está sin enlazar, la aplicación puede superar las funcionalidades del dispositivo cliente o los objetivos de escalabilidad de la cuenta de almacenamiento, lo que puede provocar latencias y limitaciones mayores.
Herramientas y bibliotecas cliente
Para obtener el mejor rendimiento posible, utilice siempre las herramientas y bibliotecas de cliente más recientes que proporciona Microsoft. Las bibliotecas cliente de Azure Storage están disponibles para varios lenguajes. Azure Storage también admite PowerShell y la CLI de Azure. Microsoft desarrolla de forma activa estas herramientas y bibliotecas de cliente pensando en el rendimiento, las mantiene actualizadas con las versiones de servicio más recientes y se asegura de que controlan internamente muchos de los procedimientos de rendimiento de eficacia probada. Para más información, consulte la documentación de referencia de Azure Storage.
Control de errores del servicio
Azure Storage devuelve un error cuando el servicio no puede procesar una solicitud. Conocer los errores que puede devolver Azure Storage en un escenario dado resulta útil para optimizar el rendimiento.
Errores debidos al tiempo de expiración y a que el servidor está ocupado
Azure Storage puede limitar la aplicación si se aproxima a los límites de escalabilidad. En algunos casos, es posible que Azure Storage no pueda controlar una solicitud debido a alguna condición transitoria. En ambos casos, el servicio puede devolver un error 503 (Server Busy
) o 500 (Timeout
). Estos errores también pueden producirse si el servicio reequilibra las particiones de datos para permitir un mayor rendimiento. Normalmente, la aplicación cliente debería reintentar la operación que provoca cualquiera de estos errores. Sin embargo, si Azure Storage está limitando la aplicación porque está superando los objetivos de escalabilidad, o incluso si el servicio no ha podido atender la solicitud por alguna otra razón, intentarlo una y otra vez puede empeorar el problema. Se recomienda usar una directiva de reintentos de retroceso exponencial y las bibliotecas cliente se comportan así de forma predeterminada. Por ejemplo, su aplicación podría reintentarlo al cabo de 2 segundos, luego 4 segundos, después 10 segundos, luego 30 segundos y, después, dejarlo completamente. De esta forma, la aplicación reduce considerablemente su carga en el servicio, en lugar de exagerar el comportamiento que puede provocar la limitación.
Los errores de conectividad se pueden reintentar inmediatamente porque no se derivan de la limitación y se espera que sean transitorios.
Errores que no se pueden reintentar
Las bibliotecas cliente controlan los reintentos sabiendo qué errores se pueden reintentar y cuáles no. Sin embargo, si va a llamar directamente a la API de REST de Azure Storage, hay algunos errores que no debe reintentar. Por ejemplo, un error 400 (Bad Request
) indica que la aplicación cliente ha enviado una solicitud que no se pudo procesar porque no tenía el formato esperado. El reenvío de esta solicitud genera la misma respuesta siempre, por lo que no tiene sentido reintentarla. Si llama directamente a la API de REST de Azure Storage, tenga en cuenta los posibles errores y si deben reintentarse.
Para más información sobre los códigos de error de Azure Storage, consulte Estado y códigos de error.
Deshabilitación del algoritmo de Nagle
El algoritmo de Nagle está ampliamente implementado en redes TCP/IP como medio de mejorar el rendimiento de la red. Sin embargo, no es óptimo en todas las situaciones (como por ejemplo, en entornos muy interactivos). El algoritmo de Nagle tiene un efecto negativo de las solicitudes a Azure Table Storage y se debe deshabilitar si es posible.
Tamaño del mensaje
El rendimiento y la escalabilidad de las colas se reducen a medida que aumenta el tamaño de los mensajes. Coloque solo la información que necesita el receptor en un mensaje.
Recuperación por lotes
Puede recuperar hasta 32 mensajes de una cola en una sola operación. La recuperación por lotes puede reducir el número de recorridos de ida y vuelta de la aplicación cliente, lo que es especialmente útil para entornos con alta latencia, como por ejemplo, dispositivos móviles.
Intervalo de sondeo de la cola
La mayoría de aplicaciones sondean los mensajes de una cola, que puede ser uno de los principales orígenes de las transacciones de la aplicación. Seleccione el intervalo de sondeo con cuidado: un sondeo demasiado frecuente puede provocar que la aplicación alcance los objetivos de escalabilidad para la cola. No obstante, a 200 000 transacciones por 0,01 USD (en el momento de redactar este documento), un solo procesador que sondeara una vez cada por segundo durante un mes costaría menos de 15 centavos, así que el costo de sondeo no suele ser un factor que afecte a la elección del intervalo de sondeo.
Para obtener información actualizada sobre el costo, consulte Precios de Azure Storage.
Realización de una operación de actualización de mensaje
Puede recordar la operación de actualización de mensaje para aumentar el tiempo de expiración de la invisibilidad o para actualizar la información del estado de un mensaje. Este enfoque puede ser más eficaz que tener un flujo de trabajo que pasa un trabajo de una cola a la siguiente a medida que se completa cada uno de los pasos del trabajo. La aplicación puede guardar el estado del trabajo en el mensaje y, después, continuar trabajando, en lugar de volver a poner en cola el mensaje para el próximo paso del trabajo cada vez que se completa un paso. Tenga en cuenta que cada operación de actualización de mensaje cuenta para el objetivo de escalabilidad.
Arquitectura de la aplicación
Use colas para que la arquitectura de la aplicación sea escalable. A continuación se enumeran algunas formas de usar colas para que la aplicación sea más escalable:
- Puede usar colas para crear trabajos pendientes para el procesamiento y aliviar las cargas de la aplicación. Por ejemplo, podría poner en cola solicitudes de usuarios para realizar un trabajo que requiere muchos recursos de procesador, como, por ejemplo, cambiar el tamaño de las imágenes cargadas.
- Puede usar colas para desacoplar partes de la aplicación para poder escalarlas por separado. Por ejemplo, un front-end web podría poner resultados de encuesta de usuarios en una cola para analizarlos y almacenarlos posteriormente. Podría agregar más instancias de rol de trabajo para procesar los datos de cola según sea necesario.