Estructura de datos de Redis

Redis es un sistema de almacenamiento de valores clave. En comparación con Memcache, su valor admite más tipos de datos.
Redis utiliza objetos para identificar claves y valores en la base de datos. Siempre que se crea un par clave-valor en redis, se crean dos objetos: objetos clave y objetos de valor.
El objeto en Redis está representado por una estructura redisObject. Los tres atributos relacionados con guardar datos en esta estructura son: atributo de tipo, atributo de codificación y atributo ptr. como sigue:

typedef struct redisObject{
    
    
    //类型
    unsigned type:4;
    //编码
    unsigned encoding:4;
    指向底层实现数据结构的指针
    void *ptr;
}robj;

Uno, el tipo de datos de redis

El atributo type registra el tipo de objeto. El valor de este atributo puede ser una de las siguientes constantes:

Tipo constante El nombre del objeto
REDIS_STRING Objeto de cadena
REDIS_LIST Objeto de lista
REDIS_HASH Objeto hash
REDIS_SET Objeto de colección
REDIS_ZSET Colección ordenada de objetos

Entre ellos, la clave de Redis es siempre un objeto de cadena y el valor puede ser uno de los cinco tipos de objetos anteriores.
Úselo TYPE keypara ver un valor de clave de base de datos de los tipos de datos de objeto, como:

redis> set name "zs"
OK
redis> TYPE name
"string"

Dos, realización de codificación redis

El atributo de codificación registra la codificación utilizada por el objeto, es decir, qué estructura de datos utiliza el objeto como implementación subyacente del objeto; el puntero ptr apunta a la estructura de datos de implementación subyacente del objeto.
Los objetos de Redis de cada tipo de datos usan codificaciones diferentes. La siguiente tabla enumera las codificaciones que puede usar cada tipo de objeto:

Tipos de codificación Objeto
REDIS_STRING REDIS_ENCODING_INT Objeto de cadena implementado usando valores enteros
REDIS_STRING REDIS_ENCODING_EMBSTR Objeto de cadena realizado mediante el uso de cadena dinámica simple codificada en embstr
REDIS_STRING REDIS_ENCODING_RAW Objeto de cadena implementado usando una cadena dinámica simple
REDIS_LIST REDIS_ENCODING_ZIPLIST Objeto de lista implementado usando una lista comprimida
REDIS_LIST REDIS_ENCODING_LINKEDLIST Objeto de lista implementado usando una lista enlazada de dos extremos
REDIS_HASH REDIS_ENCODING_ZIPLIST Objeto hash implementado usando una lista comprimida
REDIS_HASH REDIS_ENCODING_HT Objeto hash implementado usando diccionario
REDIS_SET REDIS_ENCODING_INTSET Objetos de colección implementados usando colecciones de enteros
REDIS_SET REDIS_ENCODING_HT Objeto de colección implementado usando diccionario
REDIS_ZSET REDIS_ENCODING_ZIPLIST Objetos de colección ordenados implementados usando listas comprimidas
REDIS_ZSET REDIS_ENCODING_SKIPLIST Colección ordenada de objetos implementada usando tablas de salto

Úselo OBJECT ENCODING keypara ver el valor de los objetos de una base de datos de códigos clave, como:

redis> set name "zs"
OK
redis> OBJECT ENCODING name
"embstr"

La asociación de varios códigos para tipos específicos de objetos mejora en gran medida la flexibilidad y la eficiencia de Redis. Redis puede establecer diferentes códigos para un objeto de acuerdo con diferentes escenarios de uso, optimizando así la eficiencia del objeto en un determinado escenario. A continuación, presentaremos cómo cada tipo usa la codificación en diferentes escenarios.

3. Codificación y conversión de codificación de diferentes objetos

1. Objeto de cadena

La codificación de objetos de cadena puede ser int, raw, embstr.

  • int: el objeto de cadena contiene un valor entero, y este valor entero se puede representar mediante el tipo largo;
  • sin formato: el objeto de cadena almacena el valor de cadena y la longitud del valor de cadena es superior a 32 bytes;
  • embstr: el objeto de cadena almacena el valor de la cadena y la longitud del valor de la cadena es menor o igual a 32 bytes;
(1) codificación int

objeto de cadena codificado int
Ejemplo:

redis> set number 10086
OK
redis> OBJECT ENCODING number
"int"
(2) Codificación sin formato

objeto de cadena codificado sin formato
Ejemplo:

redis> set story "Long,long ago there lived a king..."
OK
redis> STRLEN story
(integer) 37
redis> OBJECT ENCODING story
"raw"
(3) codificación Embtsr

La codificación embstr es un método de codificación optimizado que se utiliza para guardar cadenas cortas. Esta codificación, como la codificación sin formato, utiliza la estructura redisObject y la estructura sdshdr para representar objetos de cadena, pero la codificación sin formato llama a la función de asignación de memoria dos veces para crearlos por separado. La estructura redisObject y la estructura sdshdr, mientras que la codificación embstr asigna un espacio continuo a través de una función de asignación de memoria, y el espacio contiene la estructura redisObject y la estructura sdshdr a su vez. Por lo tanto, la codificación embstr es más eficiente que la codificación sin formato en la asignación y liberación de memoria, y puede aprovechar mejor las ventajas del almacenamiento en caché.
objeto de cadena codificado embstr
Ejemplo:

redis> set msg "hello"
OK
redis> OBJECT ENCODING msg
"embstr"
(4) Conversión de código

Los objetos codificados en int y embstr se convertirán en objetos de cadena codificados sin formato cuando se cumplan las condiciones.
(a) Después de que se ejecutan algunos comandos para el objeto de cadena de codificación int, el objeto ya no es un valor entero, sino un valor de cadena, y la codificación cambiará de int a raw. Como:

redis> set number 10086
OK
redis> OBJECT ENCODING number
"int"
redis> APPEND number “ is a good number”
(integer) 23
redis> OBJECT ENCODING number
"raw"

(b) El objeto de cadena codificado por embstr es de solo lectura. Cuando ejecutamos cualquier comando de modificación en el objeto de cadena codificado por embstr, el programa primero convertirá la codificación del objeto de embstr a raw, y luego ejecutará el comando de modificación, entonces embstr El objeto de cadena codificado se convertirá en codificación sin formato después de la modificación. Como:

redis> set msg "hello"
OK
redis> OBJECT ENCODING msg
"embstr"
redis> APPEND msg " world"
(integer) 11
redis> OBJECT ENCODING msg
"raw"

2. Lista de objetos

La codificación del objeto de lista puede ser ziplist, linkedlist.

  • ziplist: Al mismo tiempo: (1) La longitud de todos los elementos de cadena almacenados en el objeto de lista es inferior a 64 bytes; (2) El número de elementos almacenados en el objeto de lista es inferior a 512;
  • Linkedlist: cuando no se cumple una de las dos condiciones anteriores, utilice la codificación de Linkedlist.
(1) codificación ziplist

objeto de lista codificada ziplist
Ejemplo:

redis> RPUSH numbers 1 "three" 5
(integer) 3
redis> OBJECT ENCODING numbers
"ziplist"
(2) Codificación de Linkedlist

Objeto de lista codificado por lista enlazada
La estructura de stringObject

Ejemplo:

redis> RPUSH numbers 1 "three" 5 .......
(integer) 513
redis> OBJECT ENCODING numbers
"linkedlist"
(3) Conversión de código

Para un objeto de lista que usa codificación ziplist, cuando no se puede cumplir alguna de las dos condiciones para usar la codificación ziplist, la codificación del objeto se convierte a lista vinculada.

3. Objetos hash

La codificación del objeto hash puede ser ziplist o hashtable.

  • ziplist: Al mismo tiempo: (1) La longitud de las cadenas de clave y valor de todos los pares clave-valor almacenados en el objeto hash es menos de 64 bytes; (2) El número de pares clave-valor almacenados en el objeto hash no excede 512;
  • Hashtable: cuando no se cumple una de las dos condiciones anteriores, se utiliza la codificación hashtable.
(1) codificación ziplist

Cuando se va a agregar un nuevo par clave-valor al objeto hash, el nodo de lista comprimida que almacena la clave se empuja al final de la tabla de lista comprimida, y luego el nodo de lista comprimido que almacena el valor se empuja al final de la tabla de lista comprimida.
objeto hash codificado ziplist
Implementación de bajo nivel de lista comprimida de objetos hash

Ejemplo:

redis> HSET profile name "Tom"
(integer) 1
redis> HSET profile age 25
(integer) 1
redis> HSET profile career "Programmerr"
(integer) 1
redis> OBJECT ENCODING numbers
"ziplist"
(2) codificación hashtable

El objeto hash codificado por tabla hash usa un diccionario como implementación subyacente, y cada par clave-valor en el objeto hash se almacena usando un par clave-valor de diccionario.
objeto hash codificado en tabla hash

Ejemplo:

redis> HSET  book "long_long_long_long_long_long...."
(integer) 1
redis> OBJECT ENCODING numbers
"hashtable"
(3) Conversión de código

Para un objeto hash que usa codificación ziplist, cuando no se puede cumplir alguna de las dos condiciones de codificación ziplist, la codificación del objeto se convierte en tabla hash.

4. Objetos de colección

La codificación del objeto de colección puede ser intset, hashtable.

  • intset: Al mismo tiempo: (1) Todos los elementos almacenados en el objeto de colección son valores enteros; (2) El número de elementos almacenados en el objeto de colección no excede 512;
  • Hashtable: cuando no se cumple una de las dos condiciones anteriores, se utiliza la codificación hashtable.
(1) codificación intset

Utilice la colección de enteros como la implementación subyacente, y todos los elementos contenidos en el objeto de colección se almacenan en la colección de enteros.
objeto de colección codificado en intset

Ejemplo:

redis> SADD numbers 1 3 5
(integer) 3
redis> OBJECT ENCODING numbers
"intset"
(2) codificación hashtable

El objeto de colección codificado en tabla hash utiliza un diccionario como implementación subyacente.Cada clave del diccionario es una cadena y los valores del diccionario están todos configurados en NULL.
objeto de colección codificado en tabla hash

Ejemplo:

redis> SADD fruits "cherry" "apple" "banana"
(integer) 3
redis> OBJECT ENCODING fruits
"hashtable"
(3) Conversión de código

Para los objetos de colección que usan la codificación intset, cuando no se puede cumplir cualquiera de las dos condiciones para la codificación intset, la codificación del objeto se convertirá en tabla hash.

5. Colección ordenada de objetos

La codificación de objetos de conjuntos ordenados puede ser ziplist, skiplist.

  • ziplist: Al mismo tiempo: (1) El número de elementos almacenados en el conjunto ordenado es menor a 128; (2) La longitud de todos los miembros de elementos almacenados en el conjunto ordenado es menor a 64 bytes;
  • skiplist: cuando no se cumple una de las dos condiciones anteriores, se utiliza la codificación skiplist.
(1) codificación ziplist

El objeto de colección ordenado codificado con ziplist utiliza una lista comprimida como capa inferior. Cada elemento de colección se guarda utilizando dos nodos de lista comprimidos uno al lado del otro. El primer nodo almacena los miembros del elemento y el segundo elemento almacena la puntuación del elemento. . Los elementos del conjunto de la lista comprimida se organizan en orden descendente de puntuación. Los elementos con puntuaciones más pequeñas se colocan cerca de la cabecera de la tabla y los elementos con puntuaciones más grandes se colocan cerca del final de la tabla.
objeto de colección ordenado codificado ziplist
Los elementos del conjunto ordenados se ordenan de pequeños a grandes en la lista comprimida

Ejemplo:

redis> ZADD price 8.5 apple 5.0 banana 6.0 cherry
(integer) 3
redis> OBJECT ENCODING price
"ziplist"
(2) Codificación de lista de omisiones

El objeto de colección ordenado codificado por skiplist utiliza zset como implementación subyacente. Una estructura zset contiene un diccionario (dict) y una lista de omisión (zsl).
La tabla de salto zsl guarda todos los elementos de la colección, de pequeños a grandes, según la puntuación. Cada nodo de la tabla de salto guarda un elemento de colección: el atributo de objeto de la tabla de salto almacena los miembros del elemento y el atributo de puntuación de la tabla de salto almacena la puntuación del elemento. A través de la lista de salto, puede realizar operaciones de rango en el conjunto ordenado. Por ejemplo, comandos como ZRANK y ZRANGE se implementan según la API de lista de salto.
El diccionario dict crea un mapeo de miembros a puntuaciones para un conjunto ordenado. Cada par clave-valor del diccionario almacena un elemento de conjunto: la clave del diccionario almacena los miembros del elemento y el valor del diccionario almacena la puntuación del elemento. A través del diccionario, el programa puede buscar la puntuación de un miembro dado con complejidad O (1), como el comando ZSCORE.
Objeto de colección ordenado codificado por skiplist
Los objetos de colección ordenados se almacenan en el diccionario y en la lista de salto al mismo tiempo

Ejemplo:

redis> ZCARD numbers
(integer) 128
redis> OBJECT ENCODING numbers
"ziplist"
redis> ZADD numbers 3.14 pi
(integer) 1
redis> ZCARD numbers
(integer) 129
redis> OBJECT ENCODING numbers
"skiplist"
(3) Conversión de código

Para un conjunto ordenado de objetos codificados mediante ziplist, cuando no se puede cumplir cualquiera de las dos condiciones de codificación mediante ziplist, la codificación del objeto se convertirá en skiplist.

Cuatro, referencias

[1]: "Diseño e implementación de Redis" Parte uno Estructura de datos y objetos

Supongo que te gusta

Origin blog.csdn.net/zpy20120201/article/details/109275255
Recomendado
Clasificación