Articulo de referencia

Acorde (de igual a igual)

En informática , Chord es un protocolo y algoritmo para una tabla hash distribuida punto a punto . Una tabla hash distribuida almacena pares clave-valor asignando claves a difer...

En informática , Chord es un protocolo y algoritmo para una tabla hash distribuida punto a punto . Una tabla hash distribuida almacena pares clave-valor asignando claves a diferentes ordenadores (conocidos como "nodos"); cada nodo almacena los valores de todas las claves de las que es responsable. Chord especifica cómo se asignan las claves a los nodos y cómo un nodo puede descubrir el valor de una clave determinada localizando primero el nodo responsable de dicha clave.

Chord es uno de los cuatro protocolos originales de tabla hash distribuida , junto con CAN , Tapestry y Pastry . Fue presentado en 2001 por Ion Stoica , Robert Morris , David Karger , Frans Kaashoek y Hari Balakrishnan , y fue desarrollado en el MIT . [ 1 ] El artículo de Chord de 2001 [ 1 ] ganó un premio ACM SIGCOMM Test of Time en 2011. [ 2 ]

Investigaciones posteriores de Pamela Zave han demostrado que el protocolo Chord original (tal como se especifica en el documento SIGCOMM de 2001, [ 1 ] el informe técnico de 2001, [ 3 ] el documento PODC de 2002, [ 4 ] y el documento TON de 2003 [ 5 ] ) puede desordenar el anillo, producir varios anillos y romper el anillo. [ 6 ] Una versión corregida del protocolo evita estos errores, sin imponer una sobrecarga adicional. [ 7 ]

Descripción general

A los nodos y claves se les asigna unmetro{\displaystyle m}Identificador de bits mediante hash consistente . El algoritmo SHA-1 es la función de hash base para el hash consistente. El hash consistente es fundamental para la robustez y el rendimiento de Chord porque tanto las claves como los nodos (de hecho, sus direcciones IP ) se distribuyen uniformemente en el mismo espacio de identificadores con una posibilidad insignificante de colisión . Por lo tanto, también permite que los nodos se unan y abandonen la red sin interrupciones. En el protocolo, el término nodo se utiliza para referirse tanto al nodo en sí como a su identificador (ID) sin ambigüedad. Lo mismo ocurre con el término clave .

Utilizando el protocolo de búsqueda Chord, los nodos y las claves se organizan en un círculo de identificadores que tiene como máximo2metro{\displaystyle 2^{m}}nodos, que van desde0{\displaystyle 0}a2metro1{\displaystyle 2^{m}-1}. (metro{\displaystyle m}(debería ser lo suficientemente grande para evitar colisiones). Algunos de estos nodos se asignarán a máquinas o claves, mientras que otros (la mayoría) estarán vacíos.

Cada nodo tiene un sucesor y un predecesor . El sucesor de un nodo es el siguiente nodo en el círculo de identificadores en sentido horario. El predecesor es en sentido antihorario. Si hay un nodo para cada ID posible, el sucesor del nodo 0 es el nodo 1, y el predecesor del nodo 0 es el nodo 2.2metro1{\displaystyle 2^{m}-1}Sin embargo, normalmente existen "huecos" en la secuencia. Por ejemplo, el sucesor del nodo 153 puede ser el nodo 167 (y los nodos del 154 al 166 no existen); en este caso, el predecesor del nodo 167 será el nodo 153.

El concepto de sucesor también se puede utilizar para las claves. El nodo sucesor de una clavek{\displaystyle k}es el primer nodo cuyo ID es igual ak{\displaystyle k}o siguek{\displaystyle k}en el círculo identificador, denotado porsdodomissor(k){\displaystyle sucesor(k)}Cada clave se asigna a (se almacena en) su nodo sucesor, por lo que buscar una clavek{\displaystyle k}es consultarsdodomissor(k){\displaystyle sucesor(k)}.

Dado que el sucesor (o predecesor) de un nodo puede desaparecer de la red (debido a una falla o salida), cada nodo registra un arco de2r+1{\displaystyle 2r+1}nodos en medio de los cuales se encuentra, es decir, la lista der{\displaystyle r}nodos que lo preceden yr{\displaystyle r}nodos que le siguen. Esta lista da como resultado una alta probabilidad de que un nodo pueda localizar correctamente a su sucesor o predecesor, incluso si la red en cuestión sufre una alta tasa de fallos.

Detalles del protocolo

En una red Chord de 16 nodos, estos se disponen en círculo. Cada nodo está conectado a otros nodos a distancias de 1, 2, 4 y 8.
Una red Chord de 16 nodos. Se resaltan los "dedos" de uno de los nodos.

Consulta básica

El uso principal del protocolo Chord es consultar una clave de un cliente (generalmente también un nodo), es decir, encontrarsdodomissor(k){\displaystyle sucesor(k)}El enfoque básico consiste en pasar la consulta al sucesor de un nodo, si no puede encontrar la clave localmente. Esto dará lugar a unaO(norte){\displaystyle O(N)}tiempo de consulta dondenorte{\displaystyle N}es el número de máquinas en el anillo.

Tabla de dedos

Para evitar la búsqueda lineal anterior, Chord implementa un método de búsqueda más rápido al requerir que cada nodo mantenga una tabla de dedos que contenga hastametro{\displaystyle m}entradas, recuerde quemetro{\displaystyle m}es el número de bits en la clave hash.ith{\displaystyle i^{th}}entrada del nodonorte{\displaystyle n}contendrásdodomissor((norte+2i1)mod2metro){\displaystyle sucesor((n+2^{i-1})\,{\bmod {\,}}2^{m})}La primera entrada de la tabla de dedos es en realidad el sucesor inmediato del nodo (y por lo tanto no se necesita un campo de sucesor adicional). Cada vez que un nodo quiere buscar una clavek{\displaystyle k}, pasará la consulta al sucesor o predecesor más cercano (dependiendo de la tabla finger) dek{\displaystyle k}en su tabla de dedos (el "más grande" en el círculo cuyo ID es menor quek{\displaystyle k}), hasta que un nodo descubre que la clave está almacenada en su sucesor inmediato.

Con dicha tabla de dedos, el número de nodos que deben ser contactados para encontrar un sucesor en una red de N nodos esO(registronorte){\displaystyle O(\log N)}(Véase la prueba a continuación).

Unión de nodos

Siempre que se une un nuevo nodo, se deben mantener tres invariantes (los dos primeros garantizan la corrección y el último mantiene la rapidez de las consultas):

  1. El sucesor de cada nodo apunta correctamente a su sucesor inmediato.
  2. Cada llavek{\displaystyle k}se almacena ensdodomissor(k){\displaystyle sucesor(k)}.
  3. La tabla de dedos de cada nodo debe ser correcta.

Para satisfacer estas invariantes, se mantiene un campo de predecesor para cada nodo. Como el sucesor es la primera entrada de la tabla de dedos, ya no necesitamos mantener este campo por separado. Las siguientes tareas deben realizarse para un nodo recién unido:norte{\displaystyle n}:

  1. Inicializar nodonorte{\displaystyle n}(el predecesor y la tabla de dedos).
  2. Notificar a los demás nodos para que actualicen sus predecesores y tablas de dedos.
  3. El nuevo nodo hereda las claves responsables de su sucesor.

El predecesor denorte{\displaystyle n}se puede obtener fácilmente del predecesor desdodomissor(norte){\displaystyle sucesor(n)}(en el círculo anterior). En cuanto a su tabla de dedos, existen varios métodos de inicialización. El más sencillo es ejecutar consultas de búsqueda de sucesores para todosmetro{\displaystyle m}entradas, lo que resulta enO(METROregistronorte){\displaystyle O(M\log N)}tiempo de inicialización. Un método mejor es comprobar siith{\displaystyle i^{th}}La entrada en la tabla de dedos sigue siendo correcta para el(i+1)th{\displaystyle (i+1)^{th}}entrada. Esto conducirá aO(registro2norte){\displaystyle O(\log ^{2}N)}. El mejor método es inicializar la tabla de dedos a partir de sus vecinos inmediatos y realizar algunas actualizaciones, lo cual esO(registronorte){\displaystyle O(\log N)}.

Estabilización

Para garantizar búsquedas correctas, todos los punteros sucesores deben estar actualizados. Por lo tanto, un protocolo de estabilización se ejecuta periódicamente en segundo plano, actualizando las tablas de dedos y los punteros sucesores.

El protocolo de estabilización funciona de la siguiente manera:

  • Stabilize(): n le pide a su sucesor a su predecesor p y decide si p debería ser el sucesor de n (este es el caso si p se unió recientemente al sistema).
  • Notify(): notifica al sucesor de n de su existencia, para que pueda cambiar su predecesor a n.
  • Fix_fingers(): actualiza las tablas de dedos

Usos potenciales

  • Replicación cooperativa: Mecanismo de equilibrio de carga mediante una red local que aloja información disponible para ordenadores fuera de la red local. Este sistema podría permitir a los desarrolladores equilibrar la carga entre varios ordenadores en lugar de un servidor central para garantizar la disponibilidad de su producto.
  • Almacenamiento compartido en el tiempo: En una red, una vez que un ordenador se conecta, sus datos disponibles se distribuyen por toda la red para su recuperación cuando se desconecta. Asimismo, los datos de otros ordenadores se envían al ordenador en cuestión para su recuperación sin conexión cuando ya no están conectados a la red. Esto se aplica principalmente a nodos que no pueden conectarse a la red de forma permanente.
  • Índices distribuidos: Recuperación de archivos a través de la red dentro de una base de datos con capacidad de búsqueda. Por ejemplo, clientes de transferencia de archivos P2P.
  • Búsquedas combinatorias a gran escala: Las claves son soluciones candidatas a un problema y cada clave se asigna al nodo, o computadora, responsable de evaluarlas como solución o no. Por ejemplo, descifrado de códigos.
  • También se utiliza en redes de sensores inalámbricos para mayor fiabilidad [ 8 ].

Bocetos de prueba

Si dos nodos están separados por una distancia de 11 unidades a lo largo del anillo (es decir, hay 10 nodos entre ellos), se necesitan tres saltos para enviar un mensaje de uno a otro. El primer salto cubre una distancia de 8 unidades, el segundo de 2 unidades y el último de 1 unidad.
La ruta de enrutamiento entre los nodos A y B. Cada salto reduce la distancia restante a la mitad (o incluso menos).

Con alta probabilidad, contactos de cuerdaO(registronorte){\displaystyle O(\log N)}nodos para encontrar un sucesor en unnorte{\displaystyle N}-red de nodos.

Supongamos que el nodonorte{\displaystyle n}desea encontrar al sucesor de la clavek{\displaystyle k}. Dejarpag{\displaystyle p}ser el predecesor dek{\displaystyle k}. Deseamos encontrar un límite superior para el número de pasos que se necesitan para que un mensaje sea enrutado desdenorte{\displaystyle n}apag{\displaystyle p}Nodonorte{\displaystyle n}examinará su tabla de dedos y enrutará la solicitud al predecesor más cercano dek{\displaystyle k}que lo tiene. Llama a este nodoF{\displaystyle f}. SiF{\displaystyle f}es elith{\displaystyle i^{th}}entrada ennorte{\displaystyle n}mesa de dedos, luego ambosF{\displaystyle f}ypag{\displaystyle p}están a distancias entre2i1{\displaystyle 2^{i-1}}y2i{\displaystyle 2^{i}}denorte{\displaystyle n}a lo largo del círculo identificador. Por lo tanto, la distancia entreF{\displaystyle f}ypag{\displaystyle p}a lo largo de este círculo es como máximo2i1{\displaystyle 2^{i-1}}. Por lo tanto, la distancia desdeF{\displaystyle f}apag{\displaystyle p}es menor que la distancia desdenorte{\displaystyle n}aF{\displaystyle f}: la nueva distancia apag{\displaystyle p}es como máximo la mitad de la distancia inicial.

Este proceso de reducir a la mitad la distancia restante se repite, por lo que despuést{\displaystyle t}pasos, la distancia restante hastapag{\displaystyle p}es como máximo2metro/2t{\displaystyle 2^{m}/2^{t}}; en particular, despuésregistronorte{\displaystyle \log N}pasos, la distancia restante es como máximo2metro/norte{\displaystyle 2^{m}/N}Debido a que los nodos se distribuyen uniformemente al azar a lo largo del círculo identificador, el número esperado de nodos que caen dentro de un intervalo de esta longitud es 1, y con alta probabilidad, hay menos deregistronorte{\displaystyle \log N}tales nodos. Debido a que el mensaje siempre avanza al menos un nodo, tarda como máximoregistronorte{\displaystyle \log N}pasos para que un mensaje recorra esta distancia restante. El tiempo total de enrutamiento esperado es, por lo tanto,O(registronorte){\displaystyle O(\log N)}.

Si Chord realiza un seguimiento der=O(registronorte){\displaystyle r=O(\log N)}predecesores/sucesores, entonces con alta probabilidad, si cada nodo tiene una probabilidad de 1/4 de fallar, find_successor (ver más abajo) y find_predecessor (ver más abajo) devolverán los nodos correctos

Simplemente, la probabilidad de que todosr{\displaystyle r}Los nodos fallan es(14)r=O(1norte){\displaystyle \left({{1} \over {4}}\right)^{r}=O\left({{1} \over {N}}\right)}, lo cual es una probabilidad baja; por lo tanto, con alta probabilidad al menos uno de ellos está vivo y el nodo tendrá el puntero correcto.

Pseudocódigo

Definiciones de pseudocódigo
dedo[k]
primer nodo que tiene éxito(norte+2k1) mod 2metro,1kmetro{\displaystyle (n+2^{k-1}){\mbox{ mod }}2^{m},1\leq k\leq m}
sucesor
el siguiente nodo desde el nodo en cuestión en el anillo de identificadores
predecesor
el nodo anterior al nodo en cuestión en el anillo de identificadores

A continuación se muestra el pseudocódigo para encontrar el nodo sucesor de un ID:

// Pedir al nodo n que encuentre el sucesor de id n.find_successor(id) // Sí, debería ser un corchete de cierre para que coincida con el paréntesis de apertura. // Es un intervalo semicerrado. if id  (n, successor] then return successor else // reenviar la consulta alrededor del círculo n0 := nodo_precedente_más_cercano(id) devolver n0.find_successor(id) // busca en la tabla local el predecesor más alto de id n.closest_preceding_node(id) para i = m hasta 1 hacer si (finger[i]  (n, id)) entonces devolver dedo[i] devolver n

El pseudocódigo para estabilizar el anillo/círculo de cuerdas después de las uniones y salidas de nodos es el siguiente:

// crea un nuevo anillo de acordes. n.create() predecesor := nulo sucesor := n // Une un anillo de cuerdas que contiene el nodo n'. n.join(n') predecesor := nulo sucesor := n'.find_successor(n) // Se llama periódicamente. n pregunta al sucesor // sobre su predecesor, verifica si el sucesor inmediato de n // es consistente y le informa al sucesor sobre n. n.stabilize() x = sucesor.predecesor si x  (n, sucesor) entonces sucesor := x sucesor.notificar(n) // n' piensa que podría ser nuestro predecesor. n.notify(n') si el predecesor es nulo o n'  (predecesor, n) entonces predecesor := n' // Se llama periódicamente. Actualiza las entradas de la tabla de dedos. // A continuación, almacena el índice del dedo a corregir. n.fix_fingers() siguiente := siguiente + 1 si siguiente > m entonces siguiente := 1 finger[next] := find_successor(n+2 next-1 ); // Se llama periódicamente. Comprueba si el predecesor ha fallado. n.check_predecessor() Si el predecesor ha fallado, entonces el predecesor es nulo.

Véase también

  • Kademlia
  • Koorde
  • OverSim : el marco de simulación de superposición
  • SimGrid : un conjunto de herramientas para la simulación de aplicaciones distribuidas.

Referencias

  1. 1 2 3 Stoica, I. ; Morris, R.; Kaashoek, MF; Balakrishnan, H. (2001). "Chord: Un servicio de búsqueda peer-to-peer escalable para aplicaciones de Internet" (PDF) . ACM SIGCOMM Computer Communication Review . 31 (4): 149. doi : 10.1145/964723.383071 .
  2. "Premio ACM SIGCOMM Test of Time Paper Award" . Consultado el 16 de enero de 2022 .
  3. Stoica, I .; Morris, R.; Liben-Nowell, D.; Karger, D.; Kaashoek, MF; Dabek, F.; Balakrishnan, H. (2001). Chord: Un servicio de búsqueda peer-to-peer escalable para aplicaciones de internet (PDF) (Informe técnico). MIT LCS. MIT. 819. Archivado del original (PDF) el 22 de julio de 2012.
  4. Liben-Nowell, David; Balakrishnan, Hari; Karger, David (julio de 2002). Análisis de la evolución de los sistemas peer-to-peer (PDF) . PODC '02: Actas del vigésimo primer simposio anual sobre Principios de computación distribuida. págs. 233–242 . doi : 10.1145/571825.571863 . 
  5. Stoica, I .; Morris, R.; Liben-Nowell, D.; Karger, D.; Kaashoek, MF; Dabek, F.; Balakrishnan, H. (25 de febrero de 2003). "Chord: un protocolo de búsqueda peer-to-peer escalable para aplicaciones de Internet". IEEE/ACM Transactions on Networking . 11 (1): 17– 32. Bibcode : 2003ITNet..11...17S . doi : 10.1109/TNET.2002.808407 . S2CID 221276912 . 
  6. Zave, Pamela (2012). "Uso de modelos ligeros para comprender acordes" (PDF) . ACM SIGCOMM Computer Communication Review . 42 (2): 49– 57. doi : 10.1145/2185376.2185383 . S2CID 11727788 . 
  7. Zave, Pamela (2017). "Razonamiento sobre espacios de identificadores: Cómo hacer que Chord sea correcto" (PDF) . IEEE Transactions on Software Engineering . 43 (12): 1144– 1156. arXiv : 1610.01140 . Bibcode : 2017ITSEn..43.1144Z . doi : 10.1109/TSE.2017.2655056 .
  8. Labbai, Peer Meera (otoño de 2016). "T2WSN: SUPERPOSICIÓN DE CABLES DE DOS NIVELES MEJORADA QUE AYUDA A LA ROBUSTEZ Y LA RELACIÓN DE ENTREGA PARA REDES DE SENSORES INALÁMBRICOS" (PDF) . Journal of Theoretical and Applied Information Technology . 91 : 168–176 .
  • El Proyecto Chord (redireccionar desde: http://pdos.lcs.mit.edu/chord/ )
  • Open Chord – Una implementación Java de código abierto
  • Sin cables: otra implementación de Java de código abierto
  • jDHTUQ: una implementación Java de código abierto. API para generalizar la implementación de sistemas DHT peer-to-peer. Contiene una interfaz gráfica de usuario en modo estructura de datos.