Estructura de datos de Redis: análisis completo del tipo Hash

Redis, como sistema de almacenamiento de estructura de datos en memoria de código abierto, se utiliza ampliamente en diversos escenarios, como almacenamiento en caché, colas de mensajes y sistemas de publicación-suscripción, gracias a su excelente rendimiento y tipos de datos flexibles. Entre los cinco tipos de datos básicos de Redis, el tipo Hash es un tipo de datos muy importante. Puede almacenar una colección de pares clave-valor y puede agregar, eliminar, actualizar y buscar operaciones con una complejidad temporal de menos de 1 milisegundo, por lo que tiene una amplia gama de usos en aplicaciones prácticas.

En el próximo artículo, presentaré en detalle el tipo Hash de Redis, incluida su implementación interna, características principales, comandos comunes y escenarios de aplicación. Si es nuevo en Redis o un desarrollador con cierta experiencia, creo que puede aprender algunos conocimientos útiles de este artículo. Tengamos un conocimiento profundo del tipo Hash de Redis y exploremos su encanto.



1. Tipo de datos Redis-Hash

1.1 Introducción al tipo Redis-Hash

El tipo Hash de Redis es una colección de pares clave-valor y este tipo de datos es adecuado para almacenar objetos. En el tipo Hash, cada clave tiene un valor correspondiente, que es muy similar al diccionario de Python, HashMap de Java y los objetos JavaScript.

Estas son algunas de las características clave del tipo Redis Hash:

  1. Colección de pares clave-valor: el tipo Hash puede almacenar múltiples pares clave-valor y cada clave tiene un valor correspondiente.

  2. Binary Safe: las claves y los valores de tipo hash son binarios seguros, lo que significa que pueden contener cualquier dato, incluidos los binarios.

  3. Gran capacidad: un solo tipo de Hash puede almacenar más de 400 millones de pares clave-valor.

  4. Velocidad de búsqueda eficiente: no importa cuántos datos se almacenen en el Hash, la velocidad para encontrar una clave es muy rápida.

1.2 Escenarios de aplicación Redis-Hash

El tipo Hash de Redis es una colección de pares clave-valor, adecuado para almacenar objetos, por lo que tiene una amplia gama de aplicaciones en muchos escenarios. A continuación se muestran algunos escenarios de aplicación comunes:

  1. Almacenar objetos: el tipo Hash puede almacenar múltiples pares clave-valor, lo cual es muy adecuado para almacenar objetos. Por ejemplo, puede utilizar el tipo Hash para almacenar información del usuario, como nombre de usuario, contraseña, correo electrónico, etc.;

  2. Análisis de datos: puede utilizar el tipo Hash para almacenar diversos datos estadísticos, como datos de comportamiento del usuario, y luego realizar un análisis de datos;

  3. Red social: en una aplicación de red social, puede utilizar el tipo Hash para almacenar la lista de amigos, la lista de seguidores, etc.

Los anteriores son solo algunos escenarios de aplicación comunes. De hecho, debido a la flexibilidad de Redis, puede aplicar el tipo Hash de Redis a más escenarios según sus propias necesidades.


2. Estructura subyacente de Redis-Hash
2.1 Introducción a la estructura subyacente de Redis-Hash

La implementación subyacente del tipo Hash de Redis es una estructura de datos muy optimizada, que elegirá utilizar una lista comprimida compacta (ziplist) o una tabla hash (hashtable) como implementación subyacente de acuerdo con la situación real.

El tipo Hash de Redis cambiará entre la lista comprimida (ziplist) y la tabla hash (hashtable) según la situación real, que depende principalmente de dos parámetros de configuración: hash-max-ziplist-entriesy hash-max-ziplist-value.

  1. hash-max-ziplist-entries: Este parámetro se utiliza para establecer el número máximo de nodos que la lista comprimida puede almacenar. Si la cantidad de elementos de un tipo Hash excede este valor, cambiará de una lista comprimida a una tabla hash. El valor predeterminado es 512;
  2. hash-max-ziplist-value: Este parámetro se utiliza para establecer el tamaño máximo (en bytes) de cada nodo en la lista comprimida. Si el tamaño de cualquier elemento de tipo Hash excede este valor, se realiza un cambio de la lista comprimida a la tabla hash. El valor predeterminado es 64.

Ambos parámetros se pueden configurar en el archivo de configuración de Redis. Al ajustar estos dos parámetros, puede optar por ahorrar memoria o mejorar el rendimiento según las características de su aplicación.

  1. Convertir de una lista comprimida a una tabla hash: cuando la cantidad de campos y valores almacenados por el tipo Hash excede el hash-max-ziplist-entriesvalor, o el tamaño de cualquier campo o valor excede hash-max-ziplist-valueel valor, Redis convertirá la estructura subyacente de una lista comprimida a una tabla de picadillo. Este proceso es automático y transparente para el usuario.
  2. Conversión de tabla hash a lista comprimida: sin embargo, una vez que la estructura subyacente del tipo Hash se ha convertido en una tabla hash, no se puede volver a convertir en una lista comprimida. Esto se debe a que el rendimiento de la tabla hash es mayor y, en la mayoría de los casos, una vez que el tamaño de un tipo Hash excede un cierto umbral, es probable que su tamaño continúe creciendo.
2.2, lista comprimida de Redis (ziplist)

Cuando la cantidad de campos y valores almacenados en el tipo Hash es pequeña y la longitud de la cadena de los campos y valores es corta, Redis optará por utilizar la lista comprimida como implementación subyacente. Una lista comprimida es una estructura de codificación especial diseñada para ahorrar memoria, que almacena todos los campos y valores juntos de forma compacta. La ventaja de este método es que ocupa menos memoria, pero cuando es necesario modificar los datos, es posible que sea necesario reescribir toda la lista comprimida y el rendimiento es bajo.

La lista comprimida de Redis (ziplist) es una estructura de codificación especial diseñada para ahorrar memoria. Una lista comprimida almacena todos los elementos juntos de forma compacta y cada elemento ocupa sólo espacio de memoria contiguo.

Una lista comprimida tiene la siguiente estructura:

+---------+---------+--------+---------+---------+---------+--------+
| zlbytes | zltail  | zllen  | entry_1 | entry_2 |  ...    | zlend  |
+---------+---------+--------+---------+---------+---------+--------+

Ps: en el código fuente de Redis, la estructura de la lista comprimida (ziplist) no se define directamente como una estructura C, sino que se opera una memoria continua a través de una serie de macros y funciones.

Atributos ilustrar
“zlbytes” Un entero de 4 bytes, que indica el número de bytes ocupados por toda la lista comprimida, incluido <zlbytes>su propio tamaño.
"dorado" Un entero de 4 bytes que representa el desplazamiento del último elemento de la lista comprimida. Este desplazamiento es relativo a la dirección inicial de toda la lista comprimida.
“zllen” Un entero de 2 bytes que representa el número de elementos de la lista comprimida. Si el número de elementos excede 65535, entonces este valor se establecerá en 65535 y será necesario recorrer toda la lista comprimida para obtener el número real de elementos.
"entrada" Comprime los elementos de la lista, cada elemento consta de uno o más bytes. El primer byte de cada elemento (también conocido como "encabezado de entrada") se utiliza para indicar la longitud del elemento y el método de codificación.
“zlender” Un byte con un valor de 255 que indica el final de la lista comprimida.
2.3, tabla hash de Redis (tabla hash)

Cuando la cantidad de campos y valores almacenados en el tipo Hash es grande, o la longitud de la cadena de los campos y valores es larga, Redis optará por utilizar la tabla hash como implementación subyacente. Una tabla hash es una estructura de mapeo de pares clave-valor común, que asigna claves a un depósito a través de una función hash y luego busca en el depósito. La ventaja de este método es que el rendimiento de búsqueda y modificación de datos es alto, pero también ocupa más memoria.

La tabla hash de Redis es una estructura de mapeo de pares clave-valor común, que asigna claves a un depósito a través de una función hash y luego busca en el depósito. La tabla hash de Redis utiliza el método de lista vinculada para resolver conflictos hash, es decir, cuando se asignan varias claves al mismo depósito, se almacenan en la misma lista vinculada.

En el código fuente de Redis, la estructura de la tabla hash se define de la siguiente manera:

typedef struct dictEntry {
    
    
    void *key;
    void *val;
    struct dictEntry *next;
} dictEntry;

typedef struct dictht {
    
    
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dict {
    
    
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    int iterators; /* number of iterators currently running */
} dict;

en:

  • dictEntryUna estructura representa un nodo en una tabla hash y contiene una clave ( key), un valor ( val) y un puntero al siguiente nodo ( next).

  • dicthtLa estructura representa una tabla hash, que contiene un puntero a la matriz de la tabla hash ( table), el tamaño de la matriz de la tabla hash ( size), la máscara de tamaño de la matriz de la tabla hash ( sizemask) y el número de nodos utilizados ( used).

  • dictLa estructura representa un diccionario que contiene dos tablas hash ( ht), el índice que se está repitiendo actualmente ( rehashidx) y el número de iteradores que se están ejecutando actualmente ( iterators).

Esta es la estructura de una tabla hash de Redis.


3. Hash de comandos comunes

Los siguientes son algunos comandos relacionados con el tipo Hash en Redis:

3.1 Establecer valor hash

El comando para establecer el valor Hash en Redis es HSETque su sintaxis es la siguiente:

HSET key field value

Entre ellos, keyestá el nombre de la tabla hash, fieldel nombre del campo en la tabla hash y valueel valor correspondiente al campo. Si el campo aún no existe en la tabla hash, se crea un nuevo campo y su valor se establece en el valor especificado. Si el campo ya existe, se sobrescribirá el valor original.

Por ejemplo, podemos establecer el valor de user:1001un campo en una tabla hash denominada con el siguiente comando :nameAlice

HSET user:1001 name Alice

Si necesita establecer los valores de varios campos al mismo tiempo, puede utilizar HMSETel comando, su sintaxis es la siguiente:

HMSET key field1 value1 [field2 value2 ...]

Por ejemplo, podemos establecer el valor de los campos y user:1001en una tabla hash al mismo tiempo usando el siguiente comando :nameage

HMSET user:1001 name Alice age 25

Esto le permite establecer los valores de varios campos a la vez.

En Redis, el comando para obtener el valor Hash es HGET, su sintaxis es la siguiente:

HGET key field

Donde, keyes el nombre de la tabla hash fieldy es el nombre del campo en la tabla hash.

Por ejemplo, podemos obtener el valor de user:1001un campo en una tabla hash denominada usando el siguiente comando name:

HGET user:1001 name
3.2 Obtener valor hash

Si necesita obtener los valores de varios campos en la tabla hash, puede usar HMGETel comando, su sintaxis es la siguiente:

HMGET key field1 [field2 ...]

Por ejemplo, podemos obtener los valores de los campos y user:1001en la tabla hash con el siguiente comando :nameage

HMGET user:1001 name age

Si necesita obtener todos los campos y valores de la tabla hash, puede usar HGETALLel comando, su sintaxis es la siguiente:

HGETALL key

Por ejemplo, podemos obtener user:1001todos los campos y valores de una tabla hash con el siguiente comando:

HGETALL user:1001
3.3 Eliminar valor hash

En Redis, el comando para eliminar el valor Hash es HDELy su sintaxis es la siguiente:

HDEL key field [field ...]

donde keyes el nombre de la tabla hash y fieldes el nombre del campo que se eliminará. Puede eliminar uno o más campos a la vez.

Por ejemplo, podemos eliminar un user:1001campo en una tabla hash denominada con el siguiente comando name:

HDEL user:1001 name

Si desea eliminar varios campos, puede enumerar los nombres de estos campos uno por uno después del comando, por ejemplo:

HDEL user:1001 name age

Este comando eliminará los campos y user:1001en la tabla hash .nameage

Cabe señalar que HDELel comando solo eliminará el campo especificado y su valor, pero no toda la tabla hash. Si desea eliminar toda la tabla hash, puede usar DELel comando, por ejemplo:

DEL user:1001

Este comando elimina toda la user:1001tabla hash.

3.4 Otros comandos Hash

Algunos otros comandos comunes de Hash en Redis son:

  1. HEXISTS key field: compruebe si el campo especificado existe en la clave de la tabla hash.
  2. HLEN key: obtiene el número de campos en la tabla hash.
  3. HKEYS key: Obtiene todos los campos de la tabla hash.
  4. HVALS key: Obtiene todos los valores de la tabla hash.
  5. HGETALL key: Obtiene todos los campos y valores de la clave especificada en la tabla hash.
  6. HINCRBY key field increment: agregue incremento al valor entero del campo especificado en la clave de la tabla hash.
  7. HINCRBYFLOAT key field increment: agregue incremento al valor de punto flotante del campo especificado en la clave de la tabla hash.
  8. HMSET key field value [field value ...]: Establezca varios pares de valor de campo (valor de campo) en la clave de la tabla hash al mismo tiempo.
  9. HMGET key field [field ...]: Obtiene todos los valores del campo dado.

Supongo que te gusta

Origin blog.csdn.net/weixin_45187434/article/details/132510601
Recomendado
Clasificación