Éste es el séptimo artículo de mi serie de posts sobre DevOps. Si no has leído los anteriores, te recomiendo que lo hagas antes de seguir leyendo para conocer, por ejemplo, cómo el pensamiento Lean ha influido en el movimiento DevOps o las implicaciones que tiene el cambio de tamaño de los paquetes de trabajo en el flujo de entrega de valor al cliente.
Es precisamente cuando hablamos de flujo de entrega de valor cuando un nuevo elemento empieza a aplicar en nuestro sistema. En este caso hablamos de la Teoría de las limitaciones, también conocida como teoría de restricciones o por su nombre en inglés Theory of Constraints – TOC. Es decir, en el momento en el que establecemos que el desarrollo de proyectos de software encaja en un modelo basado en la entrega de valor y que es en realidad un problema de gestión de flujo, otras técnicas de gestión cobran sentido y aplican al desarrollo de software.
Dicha teoría la formuló Eliyahu M. Goldratt a través de un libro llamado “La meta”. No voy a entrar demasiado en el contenido del libro, pero sí recomiendo su lectura. Su formato de novela hace que sea muy sencillo de leer y su contenido resulta muy revelador. Hay que tener en cuenta que dicha novela inspiró el libro “The Phoenix Project” de Gene Kim, texto de referencia dentro del mundo DevOps. De hecho, este libro es una “traslación” de “La meta” (cuyo ámbito es la fabricación) al mundo IT. Cualquiera que lea este libro relacionado con el mundo IT se sentirá inmediatamente identificado y pensará que el libro está escrito para él.
A continuación, haré una breve descripción de la Teoría de las Limitaciones, y a lo largo de este post explicaré por qué la Teoría de las Limitaciones es tan importante para el mundo DevOps.
La Teoría de las Limitaciones
La teoría en sí es muy simple. A grosso modo, lo que establece es que en un sistema de entrega de valor siempre existirá una limitación, que es la que está ralentizando el flujo.
Existen muchos “dichos populares” que implícitamente avalan esta teoría. Por ejemplo, “la cadena se rompe por el eslabón más débil”, “la manada va tan lenta como el más lento de los miembros de la misma”, etc.
En la práctica, de lo que nos está hablando es de la existencia de cuellos de botella dentro del sistema que están limitando nuestra entrega de valor, que por otra parte pueden ser gestionados con la aplicación de esta teoría. Para ello establece lo que se conocen como los “Five Focusing Steps“. Estos 5 pasos, que explicaremos más adelante, son los siguientes:
La formulación es muy sencilla pero lo realmente importante es que aplicada de manera sistemática nos lleva a un proceso de mejora continua ya que siempre habrá que ir buscando la limitación y mejorarla. Debido a que un pilar fundamental de DevOps es la una cultura de mejora continua se comprende el entusiasmo que provoca en los seguidores de DevOps.
» Lo importante de la Teoría de la Limitaciones es que, aplicada de manera sistemática, nos lleva a un proceso de mejora continua. »
Aplicación práctica de la Teoría de las Limitaciones
A continuación, voy a examinar los 5 pasos (siempre desde mi punto de vista personal):
1. Identificación del cuello de botella
El primer paso del procedimiento es identificar el cuello de botella. Siempre hay que medir el throughput (rendimiento) y el tiempo de ciclo de nuestro sistema y preguntarnos por qué no tenemos más throughput o por qué el tiempo de ciclo no es menor. La simple formulación de esta pregunta nos ayudará a pensar en qué punto de nuestro flujo de entrega de valor puede estar el cuello de botella.
Como ya vimos en un post anterior, el uso de Value Stream Maps en DevOps es fundamental. Y en este punto de mejora resulta fundamental tener claro dicho Value Stream Map, ya que nos ayudará en gran medida a identificar donde está el cuello de botella. Y si se da el caso de que apoyamos nuestro Value Stream Map en un sistema Kanban la identificación del mismo será aún más sencilla; del mismo modo que en un proceso de fabricación el inventario de piezas se amontonará delante del cuello de botella, en nuestro sistema Kanban las historias de usuario/tareas/solicitudes se amontonarán en la columna del cuello de botella. Por poner un ejemplo, en un sistema “tradicional” de desarrollo de software veremos que se acumulan en la columna de despliegue a producción. Ya sabemos dónde comenzar a buscar.
2. Explotar el cuello de botella
He de decir que personalmente no me gusta mucho el término ya que no deja muy claro a qué se refiere.
Básicamente consiste en identificar y evaluar la capacidad máxima del cuello de botella, analizar qué es lo que hace que no se esté produciendo a esa capacidad y tomar decisiones para que lo haga. Nos sorprenderemos cuando veamos que en multitud de ocasiones realmente no se está trabajando al límite (máximo) de capacidad, y en otras el problema puede estar determinado por desperdicios como tiempos de espera, bugs o falta de coordinación.
Hay que remarcar que las acciones que se lleven a cabo en este paso no buscan aumentar la capacidad del cuello la botella, sino ver por qué no está produciendo el throughput ideal según los recursos del mismo.
Algo de suma importancia en este punto es no aplicar acciones de elevación de la capacidad del cuello de botella ya que el objetivo es el uso óptimo de lo actual. Ocurre con frecuencia que los managers inexpertos buscan la solución más fácil, que es la elevación, y toman medidas inadecuadas. En el caso de personas intentarán añadir más personal al equipo, sin tener en cuenta que esta acción de elevación implica un aumento de coste y no siempre resuelve el problema. Por otro lado y como dice la ley de Brooks, “añadir más personas a un proyecto en retraso lo retrasará aún más” con lo que la acción no solo no resolverá el problema, sino que lo empeorará.
Por su parte, el desarrollador inexperto actuará del mismo modo ante un problema semejante. Si hay un cuello de botella en la memoria RAM inmediatamente pedirá más RAM (elevación). Normalmente esto no soluciona nada ya que no se ha resuelto el problema del cuello de botella, y lo correcto será buscar la causa raíz (que puede estar en una mala programación).
Volviendo al ejemplo anterior del cuello de botella detectado en la fase de despliegue se podría observar falta de coordinación entre el equipo de Dev y Ops derivados del trabajo en silos que lleva a tiempos de espera, despliegues complejos y con errores, despliegues manuales, entregas muy grandes, etc. De hecho, si nos fijamos estos elementos son los desperdicios identificados cuando se habló de Lean.
Una vez analizado por qué nuestro cuello de botella no está rindiendo al máximo de su capacidad deberíamos tomar decisiones que corrijan esto. Por ejemplo, podemos:
- Hacer que el equipo de Dev y Ops trabajen juntos eliminado los silos.
- Reducir el tamaño de las entregas.
- Mantener un flujo continuo usando técnicas de buffering.
- Estandarizar las entregas.
- etc.
Es importante hacer notar que no estamos aplicando ninguna acción de elevación que aumentaría la capacidad del cuello de botella. Eso se hará más adelante.
3. Subordinar todo a las decisiones del paso anterior
Este es el punto crucial ya que implica cambios en el sistema y toma de decisiones algunas veces difíciles de llevar a cabo. Lo que se debe hacer es implementar las decisiones que se han tomado en el paso anterior y subordinar el resto a dichas decisiones. Esto parece muy radical pero hay que tener muy en cuenta lo siguiente: cualquier mejora hecha en un paso posterior al cuello de botella no mejorará el flujo en absoluto porque seguirá ralentizado por el mismo y cualquier mejora realizada en un paso anterior lo que único que va a hacer es saturar más aún el cuello de botella y va a empeorar más la situación.
En este punto interesa analizar el sistema como un sistema holístico, buscando la mejora del flujo en su conjunto y no optimizaciones locales ya que las mejoras que realicemos en el cuello de botella mejorarán de manera directa el flujo completo del sistema.
Por ejemplo, una de las decisiones que tomamos en el punto anterior fue que el equipo de Dev y Ops trabajen juntos. Esto puede hacer que el trabajo particular de ambos equipos por separado se vea afectado por la nueva forma de trabajar e incluso empeore, pero al mejorar el flujo en el cuello de botella habremos conseguido que la velocidad de entrega de valor aumente considerablemente.
4. Elevar el cuello de botella
Cuando ya hemos conseguido optimizar el funcionamiento del cuello de botella es el momento de ampliar su capacidad si lo que queremos es aumentar el throughput del sistema.
Por ejemplo, podemos llegar al punto en nuestro proceso de despliegue en el que al ser un despliegue manual no consigamos aumentar el throughput y pensemos que automatizando ese proceso lo lograríamos. Es decir, la automatización es una acción de elevación y como tal debería abordarse después de las acciones de explotación del cuello de botella. Si lo hiciéramos antes seguramente automatizaríamos procesos no optimizados en absoluto y, aunque podríamos obtener mejora, no sería del todo beneficiosa y puede incluso que el beneficio no compense el coste. Hay que tener en cuenta que las acciones de elevación suelen ser más costosas ya que requieren más recursos y por lo tanto deberían ser las últimas en llevarse a cabo.
Si vemos que al hacer este tipo de acciones el throughput no aumenta eso es un indicador de que el cuello de botella se ha movido dentro de nuestro flujo de valor a otro punto con lo que pasamos directamente al paso 5 para identificar de nuevo el cuello de botella.
Por ejemplo, cuando mencionábamos el problema con la memoria RAM, una vez optimizado el sistema podríamos aumentar la memoria, pero si el sistema no mejora entonces el cuello de botella se habrá desplazado a otro punto (CPU, red, disco, etc…).
Si en nuestro proceso de despliegue llega un punto en que no mejora con la automatización, puede que el cuello de botella se haya desplazado, por ejemplo, a la parte de negocio y que no se consigan generar ideas/peticiones al ritmo que el sistema es capaz de hacer entregas.
5. Volver al punto 1 evitando la inercia del sistema
Una vez aplicados los pasos anteriores, lo más habitual es que el cuello de botella se haya desplazado a otro punto del sistema, por lo que solo queda comenzar de nuevo con la búsqueda del nuevo cuello de botella.
Como se observa este procedimiento ejecutado de manera sistemática lleva a un proceso de mejora continua en el que se busca aumentar el throughput y disminuir el tiempo de ciclo constantemente. Esto es de especial relevancia para no caer en la inercia y seguir haciendo las cosas de la misma manera y cometiendo los mismos errores.
También en esta fase se realizan reuniones de retrospective para inspeccionar qué es lo que funciona y lo que no y ver cómo mejorar encaja perfectamente en esta búsqueda de la mejora continua. De hecho, una opción muy efectiva para realizar una retrospectiva es preguntarse por la limitación actual del flujo, qué acciones de explotación y/o elevación tomar y ejecutarlas durante el siguiente sprint, evaluando el resultado en la siguiente retrospectiva.
Teoría de las Limitaciones y DevOps
En los párrafos anteriores he descrito los pasos de la teoría de las limitaciones incluyendo ejemplos que buscaban establecer un paralelismo con la dinámica de implementación DevOps en un sistema.
Realmente la aparición y desarrollo del movimiento DevOps sigue la secuencia descrita por la teoría. Con la adopción del agilismo por parte de los desarrolladores y el aumento del número de entregas y la velocidad de desarrollo lo que se produjo fue un desplazamiento de la limitación hacia el lado de operaciones.
Al analizar por qué no se entregaba valor a la velocidad en la que los equipos de desarrollo generaban valor parecía evidente que había un cuello de botella en el proceso de despliegue. Analizar dicho cuello botella y que se tomaran decisiones para explotar el mismo fue lo que promovió la aparición del movimiento DevOps.
La medida más clara parecía que si el equipo de Dev y Ops trabajaban juntos, el sistema conseguiría mejorar el throughput, tal y como ha sucedido en la realidad. De hecho, se han tomado decisiones y se han subordinado otras para poder llevar a cabo las mismas. Por ejemplo, se ha tenido que eliminar la decisión de que los equipos de Dev y Ops estuvieran separados (motivado en el pasado por la búsqueda de mayor seguridad en los sistemas), con el objetivo de mejorar el throughput.
Solamente cuando las acciones de explotación ya no daban más capacidad es cuando han empezado a surgir otros elementos como la automatización del proceso de despliegue, de aprovisionamiento, etc. Esto es lo que ha hecho que la productividad se haya disparado y podamos ver ahora números increíbles no hace tanto tiempo. Ahora los diez despliegues por día de Flickr parecen pocos comparados con los números de Amazon, con un despliegue cada 11,6 segundos por término medio.
Inevitablemente, el cuello de botella se ha movido a otra parte del proceso y es esa la razón por la que ahora aparecen nuevas iniciativas, como por ejemplo DevSecOps, donde entra en juego la seguridad. Lo que se ha visto es que la nueva limitación se ha desplazado a la parte de seguridad y se están empezando a aplicar las mismas acciones que funcionaron con éxito. ¿Por qué no se integra el equipo de seguridad con Dev y Ops? ¿Por qué no se hace seguridad continua? ¿Por qué no automatizamos el proceso de aseguramiento de la seguridad?
Lo mismo se podría decir del Testing. Cada vez más se busca el Testing continuo y automatizado para poder satisfacer las demandas de velocidad en la entrega de valor.
En definitiva, de forma consciente o no, se está siguiendo el procedimiento descrito por la Teoría de las Limitaciones. Las empresas que lo ejecutan de manera consciente y sistemática son las que consiguen una mejora continua sostenida en el tiempo y las que efectivamente están implementado DevOps al adoptar una cultura de mejora continua que enlaza con el tercer camino de la metodología DevOps de Cultura de aprendizaje y experimentación continua.
Como Conclusión
En este artículo he realizado una breve introducción a la teoría de las limitaciones y su aplicación en el mundo DevOps. No he pretendido hacer una descripción detallada de la misma sino explicar de manera sencilla los conceptos de dicha teoría y ver cómo han influido en el desarrollo del movimiento DevOps, que es lo que nos atañe.
Hay otros modelos que favorecen la creación de una cultura de mejora continua pero el uso de la Teoría de las Limitaciones es muy sencillo e intuitivo, de ahí su éxito durante años en el ámbito de fabricación y ahora en el mundo IT y DevOps.
En cualquier caso, sacar las conclusiones expuestas e interpretar la Teoría de las Limitaciones desde un punto de vista práctico ha requerido muchas horas de trabajo. Si quieres aprovechar la experiencia de Xeridia en este ámbito, ponte en contacto con nosotros ahora.
Emiliano Sutil es Project Manager en Xeridia