Una pregunta favorita sobre cualquier sistema distribuido de un especialista no técnico es "¿Cuántos tps hay en su blockchain?". Sin embargo, el número dado en respuesta generalmente tiene poco en común con lo que el interlocutor quisiera escuchar. De hecho, quería preguntar "¿su blockchain se ajustará a los requisitos de mi negocio", y estos requisitos no son un número, sino muchas condiciones: aquí está la tolerancia a fallas de la red, los requisitos de finalidad, tamaño, naturaleza de las transacciones y muchos otros parámetros. Por lo tanto, la respuesta a la pregunta "cuántos tps" es poco probable que sea simple, y casi nunca estará completa. Un sistema distribuido con docenas y cientos de nodos que realizan cálculos bastante complejos puede estar en una gran cantidad de estados diferentes relacionados con el estado de la red, el contenido de blockchain, fallas técnicas, problemas económicos, ataques a la red y muchas otras razones. Las etapas en las que son posibles los problemas de rendimiento difieren de los servicios tradicionales, y el servidor de red blockchain es un servicio de red que combina la funcionalidad de una base de datos, un servidor web y un cliente torrent, lo que lo hace extremadamente difícil en términos del perfil de carga para todos los subsistemas : procesador, memoria, red, almacenamiento
Sucedió que las redes descentralizadas y las blockchains son un software bastante específico e inusual para los desarrolladores de software centralizado. Por lo tanto, me gustaría destacar aspectos importantes del desempeño y la sostenibilidad de las redes descentralizadas, enfoques para medirlas y encontrar cuellos de botella. Consideraremos varios problemas de rendimiento que limitan la velocidad de proporcionar un servicio a los usuarios de blockchain y observaremos las características específicas de este tipo de software.
Etapas de solicitud de servicio al cliente de Blockchain
Para hablar honestamente sobre la calidad de cualquier servicio más o menos complejo, debe tener en cuenta no solo los valores promedio, sino también los máximos / mínimos, las medianas y los percentiles. Teóricamente, podemos hablar de 1000 tps en alguna cadena de bloques, pero si 900 transacciones se ejecutaron a una velocidad tremenda y 100 se "congelaron" durante varios segundos, entonces el tiempo promedio recolectado para todas las transacciones no es una medida honesta para un cliente que en unos segundos no pudo completar la transacción. Los "pozos" temporales causados por la falta de rondas de consenso o la separación de la red pueden arruinar en gran medida un servicio que mostró un excelente rendimiento en bancos de pruebas.
Para identificar dicho cuello de botella, y es necesario comprender bien las etapas en las que la cadena de bloques real puede tener dificultades para atender a los usuarios. Describamos el ciclo de entrega y procesamiento de una transacción, así como la obtención de un nuevo estado de blockchain desde el cual el cliente puede verificar que su transacción ha sido procesada y tomada en cuenta.
- la transacción se forma en el cliente
- la transacción se firma en el cliente
- el cliente selecciona uno de los nodos y le envía su transacción
- el cliente se suscribe a las actualizaciones de la base de datos de estado de los nodos, esperando la aparición de los resultados de la ejecución de su transacción
- un nodo propaga una transacción a través de una red p2p
- varios o un BP (productor de bloques) procesará las transacciones acumuladas, actualizando la base de datos de estado
- BP forma un nuevo bloque, procesando el número requerido de transacciones
- BP distribuye nuevo bloque a través de la red p2p
- el nuevo bloque se entrega al nodo al que accede el cliente
- el nodo actualiza la base de datos de estado
- el nodo ve la actualización relacionada con el cliente y le envía una notificación de transacción
Ahora echemos un vistazo más de cerca a estos pasos y describamos posibles problemas de rendimiento en cada paso. A diferencia de los sistemas centralizados, también consideramos la ejecución de código en clientes de red. Muy a menudo, al medir tps, el tiempo de procesamiento de las transacciones se recopila de los nodos y no del cliente; esto no es del todo sincero. Al cliente no le importa cuán rápido el nodo procesó su transacción, lo más importante para él es el momento en que la información confiable sobre esta transacción, incluida en la cadena de bloques, está disponible para él. Es esta métrica que es esencialmente el tiempo que lleva completar una transacción. Esto significa que diferentes clientes, incluso enviando la misma transacción, pueden recibir tiempos completamente diferentes, que dependen del canal, la carga y la proximidad del nodo, etc. Por lo tanto, es absolutamente necesario medir este tiempo en los clientes, ya que es este parámetro el que debe optimizarse.
Preparación de transacciones en el lado del cliente
Comencemos con los dos primeros puntos: la transacción es formada y firmada por el cliente. Curiosamente, esto también podría ser el cuello de botella del rendimiento de blockchain desde el punto de vista del cliente. Esto es inusual para los servicios centralizados, que toman todos los cálculos y operaciones de datos por sí mismos, y el cliente simplemente prepara una solicitud corta que puede solicitar una gran cantidad de datos o cálculos, obteniendo un resultado final. En blockchains, el código del cliente se está volviendo cada vez más poderoso, y el núcleo de blockchain se está volviendo cada vez más liviano, y es costumbre dar tareas informáticas masivas al software del cliente. Hay clientes en blockchains que pueden preparar una sola transacción durante un tiempo bastante largo (estoy hablando de varias pruebas de merkle, pruebas sucintas, firmas de umbral y otras operaciones complejas en el lado del cliente). Un buen ejemplo de verificación en cadena fácil y preparación difícil de una transacción en un cliente es la prueba de pertenecer a una lista basada en Merkle-tree, aquí hay un artículo .
Además, no olvide que el código del cliente no solo envía transacciones a la cadena de bloques, sino que primero solicita el estado de la cadena de bloques, y esta actividad puede afectar la carga de la red y los nodos de la cadena de bloques. Por lo tanto, al tomar medidas, será razonable emular el comportamiento del código del cliente de la manera más completa posible. Incluso si su blockchain tiene clientes livianos regulares que ponen una firma digital simple en la transacción más simple para transferir algún activo, cada año aún hay cálculos más masivos en el cliente, los algoritmos criptográficos se fortalecen, y esta parte del procesamiento puede convertirse en un cuello de botella pesado en El futuro. Por lo tanto, tenga cuidado y no se pierda la situación cuando en una transacción que dura 3.5s, 2.5s se gastan en preparar y firmar la transacción, y 1.0s- en enviar a la red y esperar una respuesta. Para evaluar los riesgos de este cuello de botella, debe recopilar métricas de las máquinas cliente, y no solo de los nodos de blockchain.
Enviar una transacción y monitorear su estado
El siguiente paso es enviar la transacción al nodo blockchain seleccionado y recibir el estado de su adopción en el grupo de transacciones. Esta etapa es similar a un acceso normal a la base de datos, el nodo debe escribir la transacción en el grupo y comenzar a distribuir información al respecto a través de la red p2p. El enfoque para evaluar el rendimiento aquí es similar a evaluar el rendimiento de los microservicios de API web tradicionales, y las transacciones en blockchains pueden actualizarse y cambiar activamente su estado. En general, la actualización de la información de la transacción en algunas cadenas de bloques puede ocurrir varias veces, por ejemplo, al cambiar entre las horquillas de una cadena o cuando BP informa sobre su intención de incluir una transacción en un bloque. Las limitaciones en el volumen de este grupo y la cantidad de transacciones en él pueden afectar el rendimiento de la cadena de bloques. Si el grupo de transacciones está obstruido al tamaño máximo posible, o no cabe en la RAM, el rendimiento de la red puede caer drásticamente. Las cadenas de bloques no tienen protección centralizada contra el flujo de mensajes basura, y si la cadena de bloques admite transacciones de alto volumen y tarifas bajas, esto puede conducir a un desbordamiento del grupo de transacciones; este es otro posible cuello de botella de rendimiento.
En blockchains, el cliente envía la transacción a cualquier nodo de blockchain que le guste, el hash de la transacción generalmente es conocido por el cliente antes de enviarlo, por lo que todo lo que necesita hacer es obtener una conexión y después de la transferencia esperar hasta que blockchain cambie su estado, activando su transacción. Tenga en cuenta que al medir "tps" puede obtener resultados completamente diferentes para diferentes formas de conectarse a un nodo blockchain. Este puede ser un HTTP RPC o WebSocket normal, lo que le permite implementar el patrón de "suscripción". En el segundo caso, el cliente recibirá una notificación antes, y el nodo gastará menos recursos (principalmente memoria y tráfico) en respuestas sobre el estado de la transacción. Entonces, al medir "tps", debe considerar la forma en que los clientes se conectan a los nodos. Por lo tanto, para evaluar los riesgos de este cuello de botella, el punto de referencia de la cadena de bloques debe ser capaz de emular a los clientes con solicitudes WebSocket y HTTP RPC, en recursos compartidos correspondientes a redes reales, así como cambiar la naturaleza de las transacciones y su tamaño.
Para evaluar los riesgos de este cuello de botella, también debe recopilar métricas de las máquinas cliente, y no solo de los nodos de blockchain.
Transmisión de transacciones y bloques a través de una red p2p
En blockchains, la red peer-to-peer (p2p) se usa para transferir entre participantes y bloques de transacciones. Las transacciones se distribuyen a través de la red, comenzando con uno de los nodos, hasta que alcanzan los bloques pares de productores que empaquetan las transacciones en bloques y, utilizando el mismo p2p, distribuyen nuevos bloques en todos los nodos de la red. La base de la mayoría de las redes p2p modernas son varias modificaciones del protocolo Kademlia. Aquí hay una breve descripción general de este protocolo, y aquí hay un artículo con varias mediciones en la red BitTorrent, según el cual puede comprender que este tipo de red es más complicado y menos predecible que una red de servicio centralizada configurada de forma rígida. Además, aquí hay un artículo sobre la medición de varias métricas interesantes para los nodos Ethereum.
En resumen, cada par en dichas redes mantiene su propia lista dinámica de otros pares que solicitan bloques de información a los que se dirige el contenido. Al recibir la solicitud, el igual proporciona la información necesaria o transmite la solicitud al siguiente par pseudoaleatorio de la lista y, después de recibir la respuesta, la pasa al solicitante y la almacena en caché durante un tiempo, dando este bloque de información la próxima vez antes. Por lo tanto, la información popular aparece en una gran cantidad de cachés en una gran cantidad de pares, y la información impopular se desplaza gradualmente. Los pares realizan un seguimiento de quién transmitió cuánta información a quién, y la red intenta estimular a los distribuidores activos al aumentar su calificación y proporcionarles un mayor nivel de servicio, eliminando automáticamente a los participantes inactivos de las listas de pares.
Por lo tanto, la transacción ahora debe distribuirse a través de la red para que los productores de bloques puedan verla e incluirla en el bloque. Noda "distribuye" activamente una nueva transacción a todos y escucha a la red, esperando el bloqueo, en cuyo índice aparecerá la transacción necesaria para notificar al cliente en espera. El tiempo hasta que la red se envía información entre sí sobre nuevas transacciones y bloques en las redes p2p depende de una gran cantidad de factores: la cantidad de nodos honestos que trabajan cerca (desde el punto de vista de la red), el "calentamiento" de la memoria caché de estos nodos, el tamaño de los bloques, las transacciones, la naturaleza de los cambios , geografía de la red, número de nodos y muchos otros factores. Las mediciones integrales de las métricas de rendimiento en dichas redes es un asunto complejo, es necesario evaluar simultáneamente el tiempo de procesamiento de las solicitudes tanto en clientes como en pares (nodos de blockchain). Los problemas en cualquiera de los mecanismos p2p, la extrusión y el almacenamiento en caché incorrectos de datos, la gestión ineficiente de las listas de pares activos y muchos otros factores pueden causar demoras que afectan la eficiencia de toda la red en su conjunto, y este cuello de botella es el más difícil de analizar, probar y interpretación de los resultados.
Procesar la cadena de bloques y actualizar la base de datos de estado
La parte más importante del trabajo de blockchain es el algoritmo de consenso, su aplicación a los nuevos bloques recibidos de la red y el procesamiento de transacciones con el registro de los resultados en la base de datos estatal. Agregar un nuevo bloque a la cadena y la posterior selección de la cadena principal debería funcionar lo más rápido posible. Sin embargo, en la vida real, "debería" no significa "funciona", y puede, por ejemplo, imaginar una situación en la que dos largas cadenas competidoras cambian constantemente entre ellas, cambiando los metadatos de miles de transacciones en el grupo en cada conmutador, y retrocediendo constantemente el estado de la base de datos estatal. Este paso, en términos de determinar el cuello de botella, es más simple que la capa p2p de la red, porque La ejecución de la transacción y el algoritmo de consenso están estrictamente determinados, y medir cualquier cosa aquí es más fácil.
Lo principal es no confundir la degradación aleatoria del rendimiento de esta etapa con problemas de red: los nodos dan bloques e información sobre la cadena principal más lentamente y para un cliente externo puede parecer una red lenta, aunque el problema se encuentra en un lugar completamente diferente.
Para optimizar el rendimiento en esta etapa, es útil recopilar y monitorear las métricas de los propios nodos e incluir las relacionadas con las actualizaciones de la base de datos de estado: la cantidad de bloques procesados en el nodo, su tamaño, cantidad de transacciones, cantidad de interruptores entre horquillas de cadena, cantidad de bloques no válidos , tiempo de ejecución de la máquina virtual, tiempo de confirmación de datos, etc. Esto no confundirá los problemas de red con errores en los algoritmos de procesamiento de la cadena.
Una máquina virtual que ejecuta transacciones puede ser una fuente útil de información que puede optimizar el funcionamiento de la cadena de bloques. El número de asignaciones de memoria, el número de instrucciones de lectura / escritura y otras métricas relacionadas con la eficiencia de la ejecución del código de contrato pueden proporcionar mucha información útil a los desarrolladores. Al mismo tiempo, los contratos inteligentes son programas, lo que significa que, en teoría, pueden consumir cualquiera de los recursos: CPU / memoria / red / almacenamiento, por lo que el procesamiento de transacciones es un paso bastante incierto, que además cambia mucho al cambiar de versión y cuando cambiando el código de contratos. Por lo tanto, las métricas relacionadas con el procesamiento de transacciones también son necesarias para optimizar eficazmente el rendimiento de blockchain.
Cliente que recibe notificación de inclusión de transacción en blockchain
Esta es la etapa final de recibir un servicio de blockchain por parte de un cliente, en comparación con otras etapas, no hay grandes gastos generales, pero aún vale la pena considerar la posibilidad de que un cliente reciba una respuesta de volumen de un nodo (por ejemplo, un contrato inteligente que devuelve una matriz de datos). En cualquier caso, este momento es el más importante para quien hizo la pregunta "¿Cuántos tps hay en tu blockchain?", Porque En este momento, el momento de recibir el servicio es fijo.
En este lugar, siempre hay un envío del tiempo completo que el cliente tuvo que esperar una respuesta de la cadena de bloques, es esta vez que el usuario esperará la confirmación en su aplicación, y es su optimización la tarea principal de los desarrolladores.
Conclusión
Como resultado, es posible describir los tipos de operaciones realizadas en blockchains y dividirlos en varias categorías:
- transformaciones criptográficas, construcción de evidencia
- Redes de igual a igual, transacciones y replicación de bloques
- procesamiento de transacciones, ejecución de contratos inteligentes
- aplicando cambios en blockchain a la base de datos del estado, actualizando transacciones y bloqueando datos
- solicitudes de solo lectura para indicar la base de datos, la API del nodo blockchain, los servicios de suscripción
En general, los requisitos técnicos para los nodos de las cadenas de bloques modernas son extremadamente serios: son CPU rápidos para la criptografía, una gran cantidad de RAM para almacenar y acceder rápidamente a la base de datos estatal, la interacción de la red utilizando una gran cantidad de conexiones abiertas simultáneamente y un almacenamiento voluminoso. Tales requisitos elevados y la abundancia de varios tipos de operaciones conducen inevitablemente al hecho de que los recursos de los nodos pueden no ser suficientes, y luego cualquiera de los pasos anteriores puede convertirse en el próximo cuello de botella para el rendimiento general de la red.
Al desarrollar y evaluar el rendimiento de blockchains, deberá tener en cuenta todos estos puntos. Para hacer esto, debe recopilar y analizar métricas al mismo tiempo de clientes y nodos de red, buscar correlaciones entre ellos, evaluar el tiempo que se presta el servicio a los clientes, tener en cuenta todos los recursos principales: CPU / memoria / red / almacenamiento, comprender cómo se usan y afectarse mutuamente. Todo esto hace que comparar las velocidades de varias cadenas de bloques en forma de "cuántos TPS" sea una tarea extremadamente ingrata, ya que hay una gran cantidad de configuraciones y condiciones diferentes. En grandes sistemas centralizados, grupos de cientos de servidores, estos problemas también son complejos y también requieren la recopilación de una gran cantidad de métricas diferentes, pero en blockchains, debido a redes p2p, máquinas virtuales que ejecutan contratos, la economía interna, el número de grados de libertad es mucho mayor, lo que hace que la prueba incluso en varios servidores no muestra y muestra solo valores extremadamente aproximados, que casi no tienen conexión con la realidad.
Por lo tanto, al desarrollar una cadena de bloques en el núcleo, para evaluar el rendimiento y responder la pregunta "¿ha mejorado en comparación con la última vez?", Utilizamos un software bastante complicado, orquestamos el lanzamiento de la cadena de bloques con docenas de nodos y lanzamos automáticamente el punto de referencia y recopilamos métricas, sin esta información es extremadamente difícil de depurar Protocolos que funcionan con muchos participantes.
Entonces, después de haber recibido la pregunta "¿cuántos TPS hay en tu blockchain?", Ofrécele a la persona con la que estás hablando y averigua si está listo para familiarizarse con una docena de gráficos y también escucha las tres cajas de problemas de rendimiento de blockchain y tus sugerencias para resolverlos ...