[Python-es] Zen para un backend en alta disponibilidad y alta carga

J. Pablo Martín Cobos goinnn en gmail.com
Jue Abr 23 05:40:03 EDT 2020


Buenas Ismael,

Respondo entre líneas,

El mié., 22 abr. 2020 a las 21:19, Ismael de Esteban (<ismael en null.net>)
escribió:

> Gracias por la guía. Está genial.
>

Muchas gracias. Era algo que siempre estaba sobre la mesa... pero que
faltaba plasmarlo por escrito... y de paso ya pues compartirlo con la
comunidad.


> Con ese stack, ante un pico de carga, a mí me ha funcionado parar las
> colas de tareas en background ya que estas seguían haciendo peticiones a
> las bases de datos -que es generalmente el recurso más dificil de escalar
> rápidamente-. Por tanto encender y apagar algunas colas debería ser un
> comando relativamente a mano.
> Sí que hay que tener en cuenta la cantidad de tareas encoladas que puedes
> almacenar si haces esto para no perder ninguna.
>

En nuestro caso en más de 3 años no nos ha pasado nunca que las colas
lleguen a atascarse... la mayoría de las tareas tardan *como mucho* décimas
de segundos (lo normal es menos incluso)... aunque tenemos algunas de
segundos, minutos e incluso horas. Las que pueden tardar minutos u horas
son tipo cron... con lo que no atascan la cola solo la ocupan parcialmente.


>
> Feature Switching a mi entender es una setting donde activas o desactivas
> una funcionalidad. A mí me gusta implementarlo con un porcentaje en lugar
> de un booleano para poder así hacer *Canary Releases* o *Blue-Green*
> deployments. Hay que tener en cuenta que si la feature tiene determinadas
> migraciones, no se va a poder hacer rollback. Pero no conozco ninguna
> librería que ayude a implementarlas.
>
>

Nosotros esto no lo hacemos para ganar alta disponibilidad. Lo hacemos por
clientes, unos clientes ven una cosa y otros otras.

Si que es verdad que algunas funcionalidades se pueden habilitar y
deshabilitar globalmente por un administrador. Y es verdad que este podría
deshabilitarlas por alta carga... pero no está pensado para eso, sino por
otros motivos propios de nuestra lógica de negocio.

Muchas gracias de nuevo!

Abrazo,


> Un saludo!
>
>
> *Sent:* Wednesday, April 22, 2020 at 11:38 AM
> *From:* "J. Pablo Martín Cobos" <goinnn en gmail.com>
> *To:* "La lista de python en castellano" <python-es en python.org>
> *Subject:* Re: [Python-es] Zen para un backend en alta disponibilidad y
> alta carga
> Buenas Javi,
>
> Muchas gracias por tu respuesta. Respondo entre líneas,
>
> El mar., 21 abr. 2020 a las 21:46, lasizoillo (<lasizoillo en gmail.com>)
> escribió:
>
>>
>>
>> El mar., 21 abr. 2020 a las 20:37, J. Pablo Martín Cobos (<
>> goinnn en gmail.com>) escribió:
>>
>>>
>>> Alguno más se ánima al debate?
>>>
>>
>> Con las tareas asíncronas o en segundo plano como las llamas se pueden
>> hacer virguerías.
>>
>
> No es que lo llame yo... es por ejemplo como se define celery :-P
>
> "Tasks can execute asynchronously (in the *background*) or synchronously
> (wait until ready)."
>
> http://www.celeryproject.org/
>
>
>
>> Aunque a veces eso de los timeouts se queda corto. Planteo un escenario:
>>
>
> Los timeouts solo son un punto de todo lo planteado, si fueran lo único
> que hay que hacer sería el único punto ;-)
>
>
> https://goinnn.github.io/zen-of-high-load-and-high-availability-backend/index-es.html
>
>
>
>>
>> Tengo un sistema de colas de trabajo que ataca a una pila de servicios
>> externos, pongamos 40. Normalmente todo va como un tiro y se come muchos
>> trabajos por segundo, pero por si acaso pongo un timeout de 5 segundos a
>> las tareas. Si por debajo todo usa la misma cola, en plan configuración por
>> defecto de celery, voy a llegar a un punto en el que todas las peticiones
>> con timeout están haciendo de tapón y no dejando entrar a las que cuando
>> entren irán rápidas porque no fallan. Al final hay un número de workers
>> limitado y están mayormente ociosos esperando al timeout. Posibles
>> soluciones:
>> - Segregar las colas de tareas en diferentes colas de mensajes. Las
>> afectadas se encolarán por el tema de los timeouts y las otras seguirán
>> yendo rápido como si nada pasase.
>> - El worker implementa el patrón circuit breaker y mientras dura la
>> avería ese tipo de tareas se encolan a lo dead letters, se descartan o se
>> ejecutan con un plan b que no implique el sistema afectado. Solo se
>> producen timeouts hasta abrir el circuito, luego no se producen más
>> timeouts.
>> - ??? (pon aquí la solución que se te ocurra, porque hay muchas formas de
>> mejora)
>>
>
> Totalmente, lo ideal son varias colas.... y es más varios workers. Dado
> que aunque tengas varias colas una cola puede llegar a bloquear a otra cola
> si está en el mismo worker (al menos en celery).
>
> El propósito era tener una guía simple... sin profundizar. Ya que cuando
> más profundizas menos genérico es, y a un número más reducido de sistemas
> se puede aplicar.
>
>
>>
>>
>> Pero no siempre se puede dejar al usuario sin confirmación o hacer las
>> cosas "en segundo plano". Si hay fallos de usabilidad puedes tener al
>> usuario repitiendo la operación todo loco. Si le dices "tu operación estará
>> en unos segundos" lo tendrás haciendo polling cada segundo. Es posible que
>> si un caso de uso va regulero el usuario haga reintentos (como podría estar
>> haciendo tu sistema de colas de trabajo con las tareas que te dan timeout)
>> y haciendo que el sistema pase de regulero a muy malito. Para este tipo de
>> cosas puede venir bien el concepto de "feature switching": lo que va
>> regulero lo deshabilitas hasta que tengas el sistema sano otra vez.
>>
>
> Totalmente de acuerdo, no siempre se puede... pero si la mayoría de los
> casos... por ejemplo nuestras a peticiones a tercero se hacen entorno al
> 90% en segundo plano. Y tan solo un 10% en primer plano (servidor web).
>
> Aunque si que hay maneras de poder hacerlo siempre, aunque más complejas.
> Por ejemplo: si te comunicas con el backend a través de un socket... el
> primer plano podría decirle al segundo plano que hiciera X y cuando esté
> hecha el segundo plano podría responderle al frontend mediante dicho
> socket...
>
>
>>
>> Por resumirlo en un rollo de esos zen:
>>
>> - Lo que ahora va mal y en el instante siguiente va mal probablemente
>> seguirá mal: ponlo en cuarentena y no vuelvas a intentarlo en un rato.
>> - Las cosas pueden fallar, pon barreras para que cuando se estropeen no
>> te estropeen el resto. Por ejemplo usa diferentes colas para diferentes
>> tipos de tareas.
>> - A veces es mejor dejar de hacer algo que hacelo mal, usa "feature
>> switching" para esos momentos en los que las cosas no van finas.
>>
>
> No conozco "feature switching" ¿tienes algún enlace al respecto?
>
>
>>
>> Un saludo,
>>
>> Javi
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>
>
>
> Muchas gracias Javi!
>
> Abrazo,
>
> --
> Pablo Martín Cobos
> Ingeniero informático
> Desarrollador Python/Django
> 652 53 37 36
> goinnn en gmail.com
> _______________________________________________ Python-es mailing list
> Python-es en python.org https://mail.python.org/mailman/listinfo/python-es
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>


-- 
Pablo Martín Cobos
Ingeniero informático
Desarrollador Python/Django
652 53 37 36
goinnn en gmail.com
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20200423/8ccd3099/attachment.html>


Más información sobre la lista de distribución Python-es