Articulo de referencia

Hashing consistente

En ciencias de la computación , el hash consistente [ 1 ] [ 2 ] es un tipo especial de técnica de hash tal que cuando se redimensiona una tabla hash , solo norte / metro {\displ...

En ciencias de la computación , el hash consistente [ 1 ] [ 2 ] es un tipo especial de técnica de hash tal que cuando se redimensiona una tabla hash , solonorte/metro{\displaystyle n/m}Las teclas deben reasignarse en promedio dondenorte{\displaystyle n}es el número de llaves ymetro{\displaystyle m}es el número de ranuras. El hash consistente distribuye uniformemente las claves de caché entre los fragmentos , incluso si algunos de los fragmentos fallan o dejan de estar disponibles. [ 3 ] En contraste, en la mayoría de las tablas hash tradicionales, un cambio en el número de ranuras de la matriz hace que casi todas las claves se reasignen porque la asignación entre las claves y las ranuras se define mediante una operación modular .

Las redes de distribución de contenido utilizan el hash consistente porque resulta útil para distribuir las solicitudes de contenido desde una población rotativa de servidores web. Tim Berners-Lee atribuye a los algoritmos de hash consistente, y a Daniel Lewin como su inventor, la solución al problema del slashdotting que afectó a la World Wide Web en la década de 1990. [ 4 ]

Historia

El término "hashing consistente" fue introducido por David Karger et al. en el MIT para su uso en el almacenamiento en caché distribuido , particularmente para la web . [ 5 ] Este artículo académico de 1997 en el Simposio sobre Teoría de la Computación introdujo el término "hashing consistente" como una forma de distribuir las solicitudes entre una población cambiante de servidores web. [ 6 ] Cada ranura está representada por un servidor en un sistema distribuido o clúster. La adición de un servidor y la eliminación de un servidor (durante la escalabilidad o la interrupción) requiere solonortemetro_kmiys/nortemetro_slots{\displaystyle num_keys/num_slots}elementos que se reorganizan cuando cambia el número de ranuras (es decir, servidores). Los autores mencionan el hash lineal y su capacidad para manejar la adición y eliminación secuencial de servidores, mientras que el hash consistente permite agregar y eliminar servidores en un orden arbitrario. [ 1 ] El artículo fue posteriormente reutilizado para abordar el desafío técnico de realizar un seguimiento de un archivo en redes peer-to-peer como una tabla hash distribuida . [ 7 ] [ 8 ]

Teradata utilizó esta técnica en su base de datos distribuida , lanzada en 1986, aunque no empleó este término. Teradata sigue utilizando el concepto de tabla hash para cumplir precisamente con este propósito. Akamai Technologies fue fundada en 1998 por los científicos Daniel Lewin y F. Thomson Leighton (coautores del artículo que acuñó el término "hashing consistente"). En la red de entrega de contenido de Akamai, [ 9 ] el hash consistente se utiliza para equilibrar la carga dentro de un clúster de servidores, mientras que un algoritmo de matrimonio estable se utiliza para equilibrar la carga entre clústeres. [ 2 ]

El hash consistente también se ha utilizado para reducir el impacto de fallas parciales del sistema en grandes aplicaciones web para proporcionar un almacenamiento en caché robusto sin incurrir en las consecuencias de una falla en todo el sistema. [ 10 ] El hash consistente también es la piedra angular de las tablas hash distribuidas (DHT), que emplean valores hash para particionar un espacio de claves en un conjunto distribuido de nodos, y luego construyen una red superpuesta de nodos conectados que proporciona una recuperación eficiente de nodos por clave.

El hash de encuentro , diseñado en 1996, es una técnica más simple y general . Logra los objetivos de un hash consistente utilizando el algoritmo de peso aleatorio más alto (HRW), que es muy diferente.

Técnica básica

En este caso, usar un hash consistente daría como resultado que el "BLOB" se almacene en el servidor 139. Un BLOB se asigna al siguiente servidor que aparece en el círculo en sentido horario hasta que llega a un servidor que esζID del servidor{\displaystyle \zeta \leq {\text{ID del servidor}}}

En el problema del equilibrio de carga , por ejemplo, cuando un BLOB tiene que ser asignado a uno denorte{\displaystyle n}servidores en un clúster , se podría usar una función hash estándar de tal manera que calculemos el valor hash para ese BLOB, suponiendo que el valor resultante del hash seaβ{\displaystyle \beta }, realizamos una operación modular con el número de servidores (norte{\displaystyle n}en este caso) para determinar el servidor en el que podemos colocar el BLOB:ζ=β % norte{\displaystyle \zeta =\beta \ \%\ n}; por lo tanto, el BLOB se colocará en el servidor cuyoID del servidor{\displaystyle {\text{ID del servidor}}}es sucesor deζ{\displaystyle \zeta }en este caso. Sin embargo, cuando se agrega o se elimina un servidor durante una interrupción o escalado (cuandonorte{\displaystyle n}cambios), todos los BLOB en cada servidor deben reasignarse y moverse debido al rehashing , pero esta operación es costosa.

El hash consistente se diseñó para evitar el problema de tener que reasignar cada BLOB cuando se agrega o elimina un servidor en todo el clúster. La idea central es utilizar una función hash que mapee tanto el BLOB como los servidores a un círculo unitario, generalmente2π{\displaystyle 2\pi }radianes. Por ejemplo,ζ=Φ % 360{\displaystyle \zeta =\Phi \ \%\ 360}(dóndeΦ{\displaystyle \Phi }es el hash de un BLOB o identificador del servidor, como la dirección IP o el UUID ). Cada BLOB se asigna al siguiente servidor que aparece en el círculo en sentido horario. Por lo general, se utiliza un algoritmo de búsqueda binaria o una búsqueda lineal para encontrar un "lugar" o servidor donde colocar ese BLOB en particular.O(registronorte){\displaystyle O(\log N)}oO(norte){\displaystyle O(N)}complejidades respectivamente; y en cada iteración, que ocurre en sentido horario, una operaciónζ  Ψ{\displaystyle \zeta \ \leq \ \Psi }(dóndeΨ{\displaystyle \Psi }(es el valor del servidor dentro del clúster) se realiza para encontrar el servidor donde colocar el BLOB. Esto proporciona una distribución uniforme de los BLOB entre los servidores. Pero, más importante aún, si un servidor falla y se elimina del círculo, solo los BLOB que estaban asignados a ese servidor deben reasignarse al siguiente servidor en sentido horario. Del mismo modo, si se agrega un nuevo servidor, se agrega al círculo unitario y solo los BLOB asignados a ese servidor deben reasignarse.

Es importante destacar que, cuando se agrega o se elimina un servidor, la gran mayoría de los BLOB mantienen sus asignaciones de servidor anteriores, y la adición denorteth{\displaystyle n^{th}}El servidor solo causa1/norte{\displaystyle 1/n}fracción de los BLOBs a reubicar. Aunque el proceso de mover BLOBs entre servidores de caché en el clúster depende del contexto, comúnmente, el servidor de caché recién agregado identifica a su "predecesor" y mueve todos los BLOBs cuyo mapeo pertenece a este servidor (es decir, cuyo valor hash es menor que el del nuevo servidor) desde él. Sin embargo, en el caso de las cachés de páginas web , en la mayoría de las implementaciones no hay participación de movimiento o copia, suponiendo que el BLOB en caché sea lo suficientemente pequeño. Cuando una solicitud llega a un servidor de caché recién agregado, se produce un fallo de caché y se realiza una solicitud al servidor web real y el BLOB se almacena en caché localmente para futuras solicitudes. Los BLOBs redundantes en los servidores de caché utilizados anteriormente se eliminarían según las políticas de desalojo de caché . [ 11 ]

Implementación

Dejarhb(incógnita){\displaystyle h_{b}(x)}yhs(incógnita){\displaystyle h_{s}(x)}sean las funciones hash utilizadas para el BLOB y el identificador único del servidor respectivamente. En la práctica, se utiliza un árbol de búsqueda binaria (BST) para mantener dinámicamente elID del servidor{\displaystyle {\text{ID del servidor}}}Dentro de un clúster o hash, y para encontrar el sucesor o el mínimo dentro del BST, se utiliza el recorrido del árbol .

Insertarincógnita{\displaystyle x}en el grupo
Dejarβ{\displaystyle \beta }sea ​​el valor hash de un BLOB tal que,hb(incógnita)=β % 360{\displaystyle h_{b}(x)=\beta \ \%\ 360}dóndeincógnitaBLOB{\displaystyle x\in \mathrm {BLOB} }yhb(incógnita)=ζ{\displaystyle h_{b}(x)=\zeta}. Para insertarincógnita{\displaystyle x}, encontrar al sucesor deζ{\displaystyle \zeta }en el BST deID del servidor{\displaystyle {\text{ID del servidor}}}s. Siζ{\displaystyle \zeta }es más grande que todos losID del servidor{\displaystyle {\text{ID del servidor}}}s, el BLOB se coloca en el servidor con el más pequeñoID del servidor{\displaystyle {\text{ID del servidor}}}valor.
Eliminarincógnita{\displaystyle x}del grupo
Encuentra al sucesor deζ{\displaystyle \zeta }En el BST, elimine el BLOB del resultado.ID del servidor{\displaystyle {\text{ID del servidor}}}. Siζ{\displaystyle \zeta }no tiene sucesor, elimine el BLOB del más pequeño de losID del servidor{\displaystyle {\text{ID del servidor}}}s. [ 12 ]
Insertar un servidor en el clúster
DejarΦ{\displaystyle \Phi }sea ​​el valor hash del identificador de un servidor tal que,hs(incógnita)=Φ % 360{\displaystyle h_{s}(x)=\Phi \ \%\ 360}dóndeincógnita{Dirección IP, UUID}{\displaystyle x\in \{{\text{dirección IP, UUID}}\}}yhs(incógnita)=θ{\displaystyle h_{s}(x)=\theta }. Mueva todos los BLOBs cuyo valor hash sea menor queθ{\displaystyle \theta }, del servidor cuyoID del servidor{\displaystyle {\text{ID del servidor}}}es sucesor deθ{\displaystyle \theta }. Siθ{\displaystyle \theta }es el más grande de todosID del servidor{\displaystyle {\text{ID del servidor}}}s, mueva los BLOB relevantes del más pequeño de losID del servidor{\displaystyle {\text{ID del servidor}}}s enθ{\displaystyle \theta }. [ 13 ]
Eliminar un servidor del clúster
Encuentra al sucesor deθ{\displaystyle \theta }En el BST, mueva los BLOBs desdeθ{\displaystyle \theta }en su servidor sucesor. Siθ{\displaystyle \theta }no tiene sucesor, mueva los BLOBs al más pequeño de losID del servidor{\displaystyle {\text{ID del servidor}}}s. [ 14 ]

Reducción de la varianza

Para evitar la asimetría de múltiples nodos dentro del radio, que se produce debido a la falta de una distribución uniforme de los servidores dentro del clúster, se utilizan múltiples etiquetas. Estas etiquetas duplicadas se denominan "nodos virtuales", es decir, múltiples etiquetas que apuntan a una única etiqueta o servidor "real" dentro del clúster. La cantidad de nodos virtuales o etiquetas duplicadas utilizadas para un servidor en particular dentro de un clúster se denomina "peso" de ese servidor en particular. [ 15 ]

Extensiones prácticas

Se necesitan varias extensiones a la técnica básica para utilizar eficazmente el hash consistente en el balanceo de carga en la práctica. En el esquema básico anterior, si un servidor falla, todos sus BLOB se reasignan al siguiente servidor en sentido horario, lo que podría duplicar la carga de ese servidor. Esto puede no ser deseable. Para garantizar una redistribución más uniforme de los BLOB en caso de fallo del servidor, cada servidor puede ser hasheado en múltiples ubicaciones en el círculo unitario. Cuando un servidor falla, los BLOB asignados a cada una de sus réplicas en el círculo unitario se reasignarán a un servidor diferente en sentido horario, redistribuyendo así los BLOB de manera más uniforme. Otra extensión se refiere a una situación en la que un solo BLOB se vuelve "caliente" y se accede a él muchas veces, por lo que tendrá que alojarse en varios servidores. En esta situación, el BLOB puede asignarse a varios servidores contiguos recorriendo el círculo unitario en sentido horario. Una consideración práctica más compleja surge cuando dos BLOBs se procesan mediante hash cerca uno del otro en el círculo unitario y ambos se "calientan" al mismo tiempo. En este caso, ambos BLOBs utilizarán el mismo conjunto de servidores contiguos en el círculo unitario. Esta situación puede mitigarse si cada BLOB elige una función hash diferente para asignar los servidores al círculo unitario. [ 2 ]

Comparación con el hash de encuentro y otras alternativas

El hash Rendezvous , diseñado en 1996, es una técnica más simple y general, y permite un acuerdo totalmente distribuido sobre un conjunto dek{\displaystyle k}opciones de un conjunto posible denorte{\displaystyle n}opciones. De hecho, se puede demostrar que el hashing consistente es un caso especial del hashing por encuentro. Debido a su simplicidad y generalidad, el hashing por encuentro se utiliza actualmente en lugar del hashing consistente en muchas aplicaciones.

Si los valores de las claves siempre aumentan de forma monótona , un enfoque alternativo que utilice una tabla hash con claves monótonas puede ser más adecuado que el hash consistente.

Complejidad

ElO(K/norte){\displaystyle O(K/N)}es un costo promedio para la redistribución de claves y elO(registronorte){\displaystyle O(\log N)}La complejidad del hash consistente proviene del hecho de que se requiere una búsqueda binaria entre los ángulos de los nodos para encontrar el siguiente nodo en el anillo.

Ejemplos

Entre los ejemplos conocidos de uso de funciones hash consistentes se incluyen:

Referencias

  1. 1 2 Karger, D.; Lehman, E.; Leighton, T. ; Panigrahy, R.; Levine, M.; Lewin, D. (1997). Hashing consistente y árboles aleatorios: protocolos de almacenamiento en caché distribuido para aliviar puntos críticos en la World Wide Web . Actas del vigésimo noveno simposio anual de la ACM sobre teoría de la computación . ACM Press Nueva York, NY, EE. UU. págs. 654–663 . doi : 10.1145/258533.258660 . 
  2. 1 2 3 Bruce Maggs y Ramesh Sitaraman (2015). "Algorithmic nuggets in content delivery" (PDF) . ACM SIGCOMM Computer Communication Review . 45 (3).
  3. Diseño de sistemas distribuidos: Patrones y paradigmas para servicios escalables y confiables . O'Reilly Media. 2018. ISBN 9781491983607.
  4. Berners-Lee, Tim (2025). Esto es para todos: la historia inconclusa de la World Wide Web . Farrar, Straus and Giroux. pág. 156. ISBN  978-0-374-61246-7.
  5. Roughgarden y Valiant 2021 , pág. 2.
  6. Roughgarden y Valiant 2021 , pág. 7.
  7. Roughgarden y Valiant 2021 , pág. 8.
  8. I. Stoica et al., "Chord: un protocolo de búsqueda peer-to-peer escalable para aplicaciones de Internet", en IEEE/ACM Transactions on Networking, vol. 11, n.º 1, págs. 17–32, febrero de 2003, doi: 10.1109/TNET.2002.808407.
  9. Nygren, E.; Sitaraman RK; Sun, J. (2010). "The Akamai Network: A Platform for High-Performance Internet Applications" ( PDF) . ACM SIGOPS Operating Systems Review . 44 (3): 2– 19. doi : 10.1145/1842733.1842736 . S2CID 207181702. Archivado (PDF) del original el 30 de noviembre de 2022. Recuperado el 29 de agosto de 2023 . 
  10. Karger, D.; Sherman, A.; Berkheimer, A.; Bogstad, B.; Dhanidina, R.; Iwamoto, K.; Kim, B.; Matkins, L.; Yerushalmi, Y. (1999). "Almacenamiento en caché web con hash consistente" . Computer Networks . 31 (11): 1203– 1213. doi : 10.1016/S1389-1286(99)00055-9 . Archivado del original el 21 de julio de 2008. Recuperado el 5 de febrero de 2008 .
  11. Roughgarden y Valiant 2021 , pág. 6.
  12. Moitra 2016 , pág. 2.
  13. Moitra 2016 , págs. 2–3.
  14. Moitra 2016 , pág. 3.
  15. Roughgarden y Valiant 2021 , págs. 6-7.
  16. "¿Qué es exactamente Membase?" . 16 de diciembre de 2014 . Consultado el 29 de octubre de 2020 .
  17. Holt, Greg (febrero de 2011). "Construyendo un anillo de hash consistente" . openstack.org . Recuperado el 17 de noviembre de 2019 .
  18. ^ DeCandia, G.; Hastorún, D.; Jampani, M.; Kakulapati, G.; Lakshman, A.; Pilchín, A.; Sivasubramanian, S.; Vosshall, P.; Vogels, Werner (2007). "Dínamo" (PDF) . Revisión de los sistemas operativos ACM SIGOPS . 41 (6): 205– 220. doi : 10.1145/1323293.1294281 . Consultado el 7 de junio de 2018 .
  19. Lakshman, Avinash; Malik, Prashant (2010). "Cassandra: un sistema de almacenamiento estructurado descentralizado". ACM SIGOPS Operating Systems Review . 44 (2): 35– 40. doi : 10.1145/1773912.1773922 . S2CID 916681 . 
  20. "Comparativa NoSQL: MongoDB vs ScyllaDB" . benchant.com . Consultado el 21 de marzo de 2024 .
  21. "Diseño -- Voldemort" . www.project-voldemort.com/ . Archivado del original el 9 de febrero de 2015. Consultado el 9 de febrero de 2015. El hash consistente es una técnica que evita estos problemas, y la utilizamos para calcular la ubicación de cada clave en el clúster.
  22. "Akka Routing" . akka.io. Consultado el 16 de noviembre de 2019 .
  23. "Riak Concepts" . Archivado del original el 19 de septiembre de 2015. Consultado el 6 de diciembre de 2016 .
  24. "Algoritmos de GlusterFS: Distribución" . gluster.org . 1 de marzo de 2012. Consultado el 16 de noviembre de 2019 .
  25. Roughgarden, Tim; Valiant, Gregory (28 de marzo de 2016). "Caja de herramientas algorítmicas modernas" (PDF) . stanford.edu . Consultado el 17 de noviembre de 2019 .
  26. Vishnevskiy, Stanislav (2017-07-06). "Cómo Discord escaló Elixir a 5.000.000 de usuarios concurrentes" . Recuperado el 2022-08-16 .
  27. "Balanceo de carga hash consistente para gRPC" . 24 de noviembre de 2021. Consultado el 4 de septiembre de 2023 .
  28. 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. doi : 10.1109/TNET.2002.808407 . S2CID 221276912 . 
  29. "Análisis profundo del control de versiones, metadatos y almacenamiento de MinIO" . 3 de enero de 2022. Consultado el 24 de octubre de 2023 .

Obras citadas

  • Moitra, Ankur (10 de febrero de 2016). "Algoritmos avanzados, 6.854" (PDF) . Instituto Tecnológico de Massachusetts . Archivado (PDF) del original el 13 de abril de 2021. Recuperado el 8 de octubre de 2021 .
  • Roughgarden, Tim; Valiant, Gregory (28 de marzo de 2021). "The Modern Algorithmic Toolbox, Introduction to Consistent Hashing" (PDF) . Universidad de Stanford . Archivado (PDF) del original el 25 de julio de 2021. Recuperado el 7 de octubre de 2021 .
  • Comprender el hash consistente
  • Hashing consistente realizado por Michael Nielsen el 3 de junio de 2009.
  • Hashing consistente, Danny Lewin y la creación de Akamai
  • Hash consistente con salto: un algoritmo de hash consistente, rápido y con mínimo consumo de memoria.
  • Hashing de encuentro: una alternativa al hash consistente
  • Implementaciones en varios idiomas:
    • do
    • C++
    • DO#
    • Erlang
    • Ir
    • Java
    • PHP
    • Rubí
    • Pitón
    • Python (de nuevo)
    • Perl
    • Perl6