Los grafos de salto son un tipo de estructura de datos distribuida basada en listas de salto . Fueron inventados en 2003 por James Aspnes y Gauri Shah. Una estructura de datos casi idéntica, llamada SkipNet, fue inventada independientemente por Nicholas Harvey, Michael Jones, Stefan Saroiu, Marvin Theimer y Alec Wolman, también en 2003. [ 1 ]
Los grafos de salto poseen la funcionalidad completa de un árbol equilibrado en un sistema distribuido . Se utilizan principalmente para la búsqueda en redes peer-to-peer . Al permitir consultas por orden de clave , ofrecen ventajas sobre las herramientas de búsqueda basadas únicamente en la funcionalidad de tablas hash . A diferencia de las listas de salto y otras estructuras de datos de árbol , son muy robustos y toleran una gran cantidad de fallos de nodos . Además, la construcción, inserción, búsqueda y reparación de un grafo de salto afectado por fallos de nodos se puede realizar mediante algoritmos sencillos. [ 2 ]
Descripción
Un grafo de salto es una estructura de datos distribuida basada en listas de salto diseñada para asemejarse a un árbol de búsqueda equilibrado . Son uno de los diversos métodos para implementar una tabla hash distribuida , que se utiliza para localizar recursos almacenados en diferentes ubicaciones a través de una red, dado el nombre (o clave) del recurso. Los grafos de salto ofrecen varias ventajas sobre otros esquemas de tablas hash distribuidas como Chord (peer-to-peer) y Tapestry (DHT) , incluyendo la adición y eliminación en tiempo logarítmico esperado, espacio logarítmico por recurso para almacenar información de indexación, no se requiere conocimiento del número de nodos en un conjunto y soporte para consultas de rango complejas. Una diferencia importante con Chord y Tapestry es que no hay hash de las claves de búsqueda de los recursos, lo que permite que los recursos relacionados estén cerca unos de otros en el grafo de salto; esta propiedad hace factibles las búsquedas de valores dentro de un rango dado. Otra ventaja de los grafos de salto es la resiliencia a fallas de nodos tanto en modelos de falla aleatorios como adversarios .
Detalles de implementación
Al igual que con las listas de salto , los nodos se organizan en orden ascendente en múltiples niveles; cada nodo en el nivel i está contenido en el nivel i +1 con alguna probabilidad p (un parámetro ajustable). El nivel 0 consta de una lista doblemente enlazada que contiene todos los nodos del conjunto. Las listas se vuelven cada vez más dispersas en los niveles superiores, hasta que la lista se compone de un solo nodo. Donde los grafos de salto se diferencian de las listas de salto es que cada nivel i ≥1 contendrá múltiples listas; la pertenencia de una clave x a una lista se define mediante el vector de pertenencia . . El vector de pertenencia se define como una palabra aleatoria infinita sobre un alfabeto fijo, cada lista en el grafo de salto se identifica mediante una palabra finita w del mismo alfabeto, si esa palabra es un prefijo de entonces el nodo x es un miembro de la lista. [ 2 ]
Operaciones
Los gráficos de salto admiten las operaciones básicas de búsqueda , inserción y eliminación . Además, admitirán la operación de búsqueda de rango más compleja .
Buscar
El algoritmo de búsqueda para grafos de salto es casi idéntico al algoritmo de búsqueda para listas de salto, pero se modifica para ejecutarse en un sistema distribuido. Las búsquedas comienzan en el nivel superior y recorren la estructura. En cada nivel, la búsqueda recorre la lista hasta que el siguiente nodo contiene una clave mayor. Cuando se encuentra una clave mayor, la búsqueda pasa al siguiente nivel y continúa hasta que se encuentra la clave o se determina que no está contenida en el conjunto de nodos. Si la clave no está contenida en el conjunto de nodos, se devuelve el mayor valor menor que la clave de búsqueda.
Cada nodo de una lista tiene los siguientes campos:
key- El valor del nodo.
neighbor[R/L][level]- Un array que contiene punteros al vecino derecho e izquierdo en el nodo doblemente enlazado en el nivel i.
buscar(searchOp, startNode, searchKey, level) si (v.key = searchKey) entonces enviar (foundOp, v) a startNode si (v.key < searchKey) entonces mientras level ≥ 0 si (v.neighbor[R][level].key ≤ searchKey) entonces enviar (searchOp, startNode, searchKey, level) a v.neighbor[R][level] romper sino nivel = nivel - 1 De lo contrario, mientras nivel ≥ 0, si ((v.neighbor[L][nivel]).key ≥ searchKey) entonces envía (searchOp, startNode, searchKey, nivel) a v.neighbor[L][nivel] salir de lo contrario nivel = nivel - 1 Si (nivel < 0) entonces envía (notFoundOp, v) a startNode
El análisis realizado por William Pugh muestra que, en promedio, una lista de saltos y, por extensión, un gráfico de saltos contieneniveles para un valor fijo de p . [ 3 ] Dado que como máximoLos nodos se buscan en promedio por nivel, el número total esperado de mensajes enviados esy el tiempo previsto para la búsqueda es. [ 2 ] Por lo tanto, para un valor fijo de p , se espera que la operación de búsqueda tome O (log n ) tiempo usando O (log n ) mensajes. [ 2 ]
Insertar
La inserción se realiza en dos fases y requiere que un nuevo nodo u conozca algún nodo introductor v ; el nodo introductor puede ser cualquier otro nodo actualmente en el grafo de salto. En la primera fase, el nuevo nodo u usa el nodo introductor v para buscar su propia clave; se espera que esta búsqueda falle y devuelva el nodo s con la clave más grande menor que u . En la segunda fase, u se inserta en cada nivel hasta que sea el único elemento en una lista en el nivel superior. [ 2 ] La inserción en cada nivel se realiza usando operaciones estándar de lista doblemente enlazada; el puntero siguiente del vecino izquierdo se cambia para que apunte al nuevo nodo y el puntero anterior del vecino derecho se cambia para que apunte al nodo.
insertar() buscar s L = 0 mientras sea verdadero Insertar u en el nivel L desde s. Recorrer el nivel L para encontrar s' tal que tenga un vector de pertenencia que coincida con el vector de pertenencia de u para los primeros L + 1 caracteres si no existe s'. salida de lo contrario s = s' L = L + 1
De forma similar a la búsqueda, la operación de inserción requiere O (log n ) mensajes y O (log n ) tiempo. Con un valor fijo de p, se espera que la operación de búsqueda en la fase 1 requiera O (log n ) tiempo y mensajes. En la fase 2, en cada nivel L ≥ 0, u se comunica con un promedio de 1/ p nodos para localizar s ', lo que requerirá O (1/ p ) tiempo y mensajes, resultando en O (1) tiempo y mensajes para cada paso en la fase 2. [ 2 ]
Borrar
Los nodos pueden eliminarse en paralelo en cada nivel en un tiempo O (1) y O (log n ) mensajes. [ 2 ] Cuando un nodo desea abandonar el grafo, debe enviar mensajes a sus vecinos inmediatos para reorganizar sus punteros siguiente y anterior. [ 2 ]
delete() para L = 1 hasta el nivel máximo, en paralelo elimina u de cada nivel. Elimina u del nivel 0.
El grafo de salto contiene un promedio de O (log n ) niveles; en cada nivel, u debe enviar 2 mensajes para completar una operación de eliminación en una lista doblemente enlazada. Dado que las operaciones en cada nivel pueden realizarse en paralelo, la operación de eliminación puede finalizarse en un tiempo de O (1) y con un número esperado de O (log n ) mensajes.
Tolerancia a fallos
En los grafos de salto, la tolerancia a fallos describe el número de nodos que pueden desconectarse del grafo de salto debido a fallos de otros nodos. [ 2 ] Se han examinado dos modelos de fallos: fallos aleatorios y fallos adversariales. En el modelo de fallos aleatorios, cualquier nodo puede fallar independientemente de cualquier otro nodo con cierta probabilidad. El modelo adversarial supone que los fallos de los nodos se planifican de tal manera que se alcance el peor fallo posible en cada paso, se conoce toda la estructura del grafo de salto y los fallos se eligen para maximizar la desconexión de nodos. Una desventaja de los grafos de salto es que no existe un mecanismo de reparación ; actualmente, la única forma de eliminar y reparar un grafo de salto es construir un nuevo grafo de salto con nodos supervivientes.
Fallo aleatorio
Los grafos de salto son altamente resistentes a fallas aleatorias. Al mantener información sobre el estado de los vecinos y utilizar enlaces redundantes para evitar vecinos que fallen, las operaciones normales pueden continuar incluso con una gran cantidad de fallas de nodos. Mientras que el número de nodos que fallan es menor queEl grafo de salto puede seguir funcionando con normalidad. [ 2 ] Las simulaciones realizadas por James Aspnes muestran que un grafo de salto con 131072 nodos pudo tolerar que hasta el 60% de sus nodos fallaran antes de que los nodos supervivientes fueran aislados. [ 2 ] Si bien otras estructuras de datos distribuidas pueden alcanzar niveles más altos de resiliencia, tienden a ser mucho más complejas.
fracaso adversario
Es difícil simular fallos adversarios en una red grande, ya que resulta difícil encontrar patrones de fallos en el peor de los casos. [ 2 ] El análisis teórico muestra que la resiliencia depende de la relación de expansión de vértices del grafo, definida de la siguiente manera. Para un conjunto de nodos A en el grafo G, el factor de expansión es el número de nodos que no están en A pero que son adyacentes a un nodo en A dividido por el número de nodos en A. Si los grafos de salto tienen una relación de expansión suficientemente grande deentonces como máximoLos nodos pueden separarse, incluso si se buscan específicamente hasta f fallos. [ 2 ]
Referencias
- ↑ Nicholas JA Harvey; Michael B. Jones; Stefan Saroiu; Marvin Theimer; Alec Wolman. "SkipNet: una red superpuesta escalable con propiedades de localidad prácticas" (PDF) .
- 1 2 3 4 5 6 7 8 9 10 11 12 13 James Aspnes; Gauri Shah. "Grafos de salto" (PDF) . Ciencias de la Computación – Universidad de Yale .
Los grafos de salto son una novedosa estructura de datos distribuida, basada en listas de salto, que proporciona la funcionalidad completa de un árbol equilibrado en un sistema distribuido donde los recursos se almacenan en nodos separados que pueden fallar en cualquier momento. Están diseñados para su uso en la búsqueda de sistemas peer-to-peer y, al proporcionar la capacidad de realizar consultas basadas en el orden de las claves, mejoran las herramientas de búsqueda existentes que solo proporcionan la funcionalidad de una tabla hash. A diferencia de las listas de salto u otras estructuras de datos de árbol, los grafos de salto son altamente resilientes, tolerando una gran fracción de nodos fallidos sin perder la conectividad. Además, se pueden utilizar algoritmos simples y directos para construir un grafo de salto, insertar nuevos nodos en él, buscar en él y detectar y reparar errores en un grafo de salto introducidos debido a fallas de nodos.
- ↑ William Pugh. "Listas de salto: una alternativa probabilística a los árboles equilibrados" (PDF) .
- Estructuras de datos de grafos