Actualización de Safe Network Dev 🇪🇸 01 septiembre 2022

Esta es una traducción automática. El original en inglés está aquí: Update 01 September, 2022

En lo que ha sido una buena semana en general para rastrear anomalías y errores molestos, le pedimos a @joshuef que explique cómo estamos abordando los problemas debido a la serialización de mensajes y el estrés que genera en la red. Una especie de :bombilla: esta…

Progreso general

@davidrusu ha estado solucionando un problema en el que los adultos se saltaban las pruebas anti-entropía antes de las divisiones, por lo que no siempre tenían la actualización necesaria. información de fecha sobre las secciones.

Mientras tanto, @bochaco está trabajando en una lista de mejoras con respecto a cómo almacenamos registros (datos mutables - CRDT), incluido el cambio de algunas API internas de la tienda. para evitar clonar algunos objetos, escribir operaciones individuales (en lugar de un archivo que podría ser sobrescrito por otro CRDT incompleto), eliminar algunos tipos de errores de almacenamiento no utilizados y agregar más información contextual a otros, y permitir el almacenamiento de comandos de edición de registro para todos los casos (ahora el orden de entrada de los comandos debería ser menos importante, es decir, no hay una condición de carrera para tener un CreateRegister Cmd antes de un EditRegister, que está en main).

Y @chriso ha estado mejorando el manejo de errores en sn_node, incluido el tipo de mensajes de error que se envían al cliente, para que sea más fácil para los usuarios. para ver que pasa

Serialización de mensajes

Hemos visto en el sondeo de @southside que la red parece estar bajo presión con PUT de datos más grandes. Sus pruebas de cargas de más de 2 GB han arrojado luz sobre un problema que mayyy sea parte del motivo… y podría ser simplemente demasiados mensajes.

Eso no significa que estemos enviando demasiados (aunque podríamos estar enviando menos). Pero parece que la tensión de formar mensajes, y la velocidad a la que lo hacemos, es demasiado alta.

Esto ha sido algo que hemos visto en heaptraces del uso de la memoria del nodo durante un tiempo, pero el camino a seguir para solucionarlo no estaba muy claro.

“Serializamos” cada mensaje en bytes, y dado que necesitamos crear un “MsgHeader” diferente para cada nodo, no había muchas formas de evitarlo.

Pero, ¿y si no lo hiciéramos?

Sin embargo, la insinuación de @southside volvió a plantear la pregunta y @joshuef, que ha estado molesto por la cantidad de memoria utilizada por la serialización desde hace un tiempo, decidió golpearse la cabeza contra eso nuevamente.

Y esta vez surgió otra idea. Anteriormente habíamos intentado eliminar la necesidad de Dst (destino, información sobre adónde debe ir el mensaje)… pero no podemos hacer eso y mantener vivos nuestros flujos Anti-Entropy. Así que eso no fue un comienzo.

Pero después de algunos intentos de actualizar el Dst Bytes en un mensaje pre-serializado, para evitar hacer todo ese trabajo nuevamente, nos dimos cuenta de que estábamos forzando una clavija cuadrada en un agujero redondo. Es decir, la limitación de proporcionar solo un ‘Bytes’ de un mensaje en realidad no tenía sentido para nosotros.

SOoooooooo…

Entonces, después de un poco de refactorización en qp2p, nuestro envoltorio de red, ahora podemos enviar tres conjuntos diferentes de Bytes a través de nuestras conexiones, y de estos, solo uno (nuestro Dst) realmente necesita cambiar si ¡Estás enviando el mismo mensaje a diferentes nodos!

Esto significa que en lugar de 7 veces el trabajo al enviar un mensaje a los ancianos de la sección, es 1x, ¡y reutilizamos los ‘Bytes’ para nuestro ‘MsgHeader’ y ‘Payload’! Solo necesita volver a codificar Dst cada vez.

Pulcro.

¡Pero espera hay mas!

Ahora, esta es una reducción decente en el costo computacional de enviar un mensaje ya. Pero también tiene otro efecto colateral en términos de memoria. Anteriormente, durante la serialización de MsgHeader, formamos nuestro conjunto one de Bytes copiando la carga útil (el mensaje real que estamos enviando… así que ~1 MB por fragmento), por lo que este es un trabajo de asignación de memoria, y significa cada mensaje tenía su propio conjunto único de ‘Bytes’ que representaban la misma ‘carga útil’. Entonces, enviar un fragmento a cuatro adultos tendría cinco copias de ese fragmento en la memoria. :frowning:

Pero ahora usamos una copia barata de Bytes (que es un tipo de puntero a los datos subyacentes…) ¡así que no se necesita duplicación de memoria! Entonces, enviar un fragmento a cuatro adultos solo debería necesitar una copia de los datos ahora :tada:

En fin

Así es como se ve main. Aquí vemos tres ejecuciones de las 250 pruebas de clientes (un PUT de 5 MB y 250 clientes al mismo tiempo que intentan obtener esos datos), y luego 10 ejecuciones del conjunto de pruebas sn_client estándar completo.

Y esto está en el PR pendiente:

Puede ver que los picos de estas pruebas parecen superarse más rápido y con menos memoria total (~900 MB frente a 1800 MB). Y con eso, nuestro nuevo punto de referencia mide el rendimiento de enviar un ‘WireMsg’ a 1,000 ‘Dsts’ diferentes.

  • rendimiento principal: 7.5792 MiB/s
  • Rendimiento de relaciones públicas: 265,25 MiB/s

Lo cual también es bastante agradable.

La rama aún no está fusionada, hay algunos arreglos finales por hacer antes de que la incorporemos, pero parece un cambio prometedor que puede ayudar a que los nodos se ejecuten en un hardware más eficiente (¡o con suerte permitir que @southside cargue más en sus redes de prueba locales!? :dedos cruzados: )


Enlaces útiles

No dude en responder a continuación con enlaces a las traducciones de esta actualización para desarrolladores y los moderadores las agregarán aquí.

Como proyecto de código abierto, siempre estamos buscando retroalimentación, comentarios y contribuciones de la comunidad, así que no sea tímido, únase y creemos la red segura juntos.