sql >> Base de Datos >  >> NoSQL >> Redis

¿Cuáles son las estructuras de datos subyacentes utilizadas para Redis?

Intentaré responder a su pregunta, pero comenzaré con algo que puede parecer extraño al principio:si no está interesado en las partes internas de Redis, no debería importarle sobre cómo se implementan internamente los tipos de datos. Esto se debe a una sencilla razón:para cada operación de Redis, encontrará la complejidad del tiempo en la documentación y, si tiene el conjunto de operaciones y la complejidad del tiempo, lo único que necesita es alguna pista sobre el uso de la memoria (y porque hacemos muchas optimizaciones que pueden variar según los datos, la mejor manera de obtener estas últimas cifras es haciendo algunas pruebas triviales del mundo real).

Pero como lo preguntó, aquí está la implementación subyacente de cada tipo de datos de Redis.

  • Cuerdas se implementan utilizando una biblioteca de cadenas dinámicas de C para que no paguemos (asintóticamente hablando) por las asignaciones en las operaciones de adición. De esta manera tenemos apéndices O(N), por ejemplo, en lugar de tener un comportamiento cuadrático.
  • Listas se implementan con listas enlazadas.
  • Conjuntos y hashes se implementan con tablas hash.
  • Conjuntos ordenados se implementan con listas de omisión (un tipo peculiar de árboles equilibrados).

Pero cuando las listas, los conjuntos y los conjuntos ordenados son pequeños en número de elementos y tamaño de los valores más grandes, se utiliza una codificación diferente y mucho más compacta. Esta codificación difiere para los diferentes tipos, pero tiene la característica de que es una masa compacta de datos que a menudo fuerza un escaneo O(N) para cada operación. Dado que usamos este formato solo para objetos pequeños, esto no es un problema; escanear un pequeño blob O(N) es olvidar la memoria caché así que, en términos prácticos, es muy rápido, y cuando hay demasiados elementos, la codificación cambia automáticamente a la codificación nativa (lista enlazada, hash, etc.).

Pero su pregunta no era solo sobre los elementos internos, su punto era ¿Qué tipo usar para lograr qué? .

Cuerdas

Este es el tipo base de todos los tipos. Es uno de los cuatro tipos, pero también es el tipo base de los tipos complejos, porque una Lista es una lista de cadenas, un Conjunto es un conjunto de cadenas, etc.

Una cadena Redis es una buena idea en todos los escenarios obvios en los que desea almacenar una página HTML, pero también cuando desea evitar convertir sus datos ya codificados. Entonces, por ejemplo, si tiene JSON o MessagePack, puede almacenar objetos como cadenas. En Redis 2.6, incluso puede manipular este tipo de objetos del lado del servidor mediante secuencias de comandos de Lua.

Otro uso interesante de las cadenas son los mapas de bits y, en general, las matrices de bytes de acceso aleatorio, ya que Redis exporta comandos para acceder a rangos aleatorios de bytes, o incluso bits individuales. Por ejemplo, consulte esta buena publicación de blog:Métricas rápidas y sencillas en tiempo real con Redis.

Listas

Las listas son buenas cuando es probable que toque solo los extremos de la lista:cerca de la cola o cerca de la cabeza. Las listas no son muy buenas para paginar cosas, porque el acceso aleatorio es lento, O (N). Por lo tanto, los buenos usos de las listas son colas y pilas simples, o procesar elementos en un bucle usando RPOPLPUSH con la misma fuente y destino para "rotar" un anillo de artículos.

Las listas también son buenas cuando solo queremos crear una colección limitada de N elementos donde generalmente accedemos solo a los elementos superiores o inferiores, o cuando N es pequeño.

Conjuntos

Los conjuntos son una recopilación de datos desordenados, por lo que son buenos cada vez que tiene una colección de elementos y es muy importante verificar la existencia o el tamaño de la colección de una manera muy rápida. Otra cosa interesante acerca de los conjuntos es la compatibilidad con elementos aleatorios de peeking o pop (comandos SRANDMEMBER y SPOP).

Los conjuntos también son buenos para representar relaciones, por ejemplo, "¿Qué son los amigos del usuario X?" Etcétera. Pero otras buenas estructuras de datos para este tipo de cosas son los conjuntos ordenados, como veremos.

Los conjuntos admiten operaciones complejas como intersecciones, uniones, etc., por lo que esta es una buena estructura de datos para usar Redis de manera "computacional", cuando tiene datos y desea realizar transformaciones en esos datos para obtener algún resultado.

Los conjuntos pequeños se codifican de forma muy eficiente.

Hashes

Los hashes son la estructura de datos perfecta para representar objetos, compuestos por campos y valores. Los campos de hash también se pueden incrementar atómicamente usando HINCRBY. Cuando tiene objetos como usuarios, publicaciones de blog o algún otro tipo de elemento , los hash son probablemente el camino a seguir si no desea utilizar su propia codificación como JSON o similar.

Sin embargo, tenga en cuenta que Redis codifica los hash pequeños de manera muy eficiente, y puede pedirle a Redis que OBTENGA, CONFIGURE o incremente atómicamente campos individuales de una manera muy rápida.

Los hashes también se pueden usar para representar estructuras de datos vinculados, usando referencias. Por ejemplo, compruebe la implementación de comentarios de lamernews.com.

Conjuntos ordenados

Los conjuntos ordenados son las únicas otras estructuras de datos, además de las listas, para mantener elementos ordenados . Puedes hacer una serie de cosas geniales con conjuntos ordenados. Por ejemplo, puede tener todo tipo de Top Something listas en su aplicación web. Los mejores usuarios por puntaje, las mejores publicaciones por páginas vistas, lo que sea, pero una sola instancia de Redis admitirá toneladas de operaciones de inserción y obtención de elementos principales por segundo.

Los conjuntos ordenados, como los conjuntos regulares, se pueden usar para describir relaciones, pero también le permiten paginar la lista de elementos y recordar el orden. Por ejemplo, si recuerdo amigos del usuario X con un conjunto ordenado, puedo recordarlos fácilmente en orden de amistad aceptada.

Los conjuntos ordenados son buenos para las colas de prioridad.

Los conjuntos ordenados son como listas más poderosas donde insertar, eliminar u obtener rangos desde el medio de la lista siempre es rápido. Pero usan más memoria y son estructuras de datos O(log(N)).

Conclusión

Espero haber proporcionado algo de información en esta publicación, pero es mucho mejor descargar el código fuente de lamernews de http://github.com/antirez/lamernews y comprender cómo funciona. Muchas estructuras de datos de Redis se usan dentro de Lamer News, y hay muchas pistas sobre qué usar para resolver una tarea determinada.

Perdón por los errores tipográficos, aquí es medianoche y estoy demasiado cansado para revisar la publicación;)