Principio de Redis: mecanismo de objeto RedisObject

La dirección del texto original se actualiza y el efecto de lectura es mejor.

Principio de Redis: mecanismo de objeto RedisObject | Mástil de programación de CoderMast icono-predeterminado.png?t=N5F7https://www.codermast.com/database/redis/redis-object.html

¿Por qué está diseñado RedisObject?

En Redis, nuestras operaciones se realizan mediante instrucciones, y entre estos comandos, los comandos para el procesamiento de claves ocupan una gran parte. Algunas instrucciones solo pueden dirigirse a ciertos tipos, mientras que otras instrucciones pueden dirigirse a todos los tipos. Pero para implementar estos comandos correctamente, se debe establecer un manejo diferente para diferentes tipos de teclas. Por ejemplo, el proceso de operación de eliminar una clave de lista es diferente al de eliminar una clave de cadena, y es necesario llamar a diferentes métodos de vista en la capa inferior.

Hay dos implementaciones diferentes de nivel inferior de tipos de colección: diccionario y colección de enteros. Cuando los usuarios operan en colecciones, no quieren preocuparse por la implementación específica de nivel inferior. Siempre que Redis pueda completar las funciones correspondientes de acuerdo con sus propias instrucciones, como agregar y eliminar elementos, la implementación específica de nivel inferior es transparente e invisible para los usuarios.

Por lo tanto, Redis debe tener información de tipo para cada clave, así como su método de codificación subyacente Solo con estas dos piezas de información Redis puede implementar con precisión las instrucciones del usuario. Luego, el objeto RedisObject debe contener al menos 3 atributos, información de tipo, método de codificación y datos reales.

# RedisObjeto

La clave y el valor de cualquier tipo de datos en Redis se encapsularán como un objeto RedisObject, también llamado objeto Redis, que se /src/server.himplementa en el archivo de la siguiente manera:

typedef struct redisObject {
    unsigned type:4;        
    unsigned encoding:4;    // 共有 11 种编码方式,占据 4 个比特位
    unsigned lru:LRU_BITS;  /* LRU 表示该对象最后一次被访问的时间,其占用 24 个 bit 位,
                               便于判断空闲时间太久的key */
    int refcount;           // 对象引用计数器,计数器为 0 则说明对象无人引用,可以被回收。
    void *ptr;              // 指针,指向数据的真实存储空间地址。一般为 8 个字节
} robj;
  • tipo sin signo: 4 ocupa 4 bits, que son cadena, lista, conjunto, zset, hash correspondiente a 0 1 2 3 4
  • codificación sin firmar: 4 Hay 11 métodos de codificación, que ocupan 4 bits
  • unsigned lru:LRU_BITSLRU indica la última vez que se accedió al objeto, que ocupa 24 bits, lo cual es conveniente para juzgar la clave que ha estado inactiva durante demasiado tiempo
  • contador de referencia de objeto refcount int, si el contador es 0, significa que nadie hace referencia al objeto y puede reciclarse.
  • puntero void *ptr, que apunta a la dirección del espacio de almacenamiento real de los datos. Generalmente 8 bytes

# método de codificación

Redis elegirá diferentes métodos de codificación según los diferentes tipos de datos almacenados, incluidos 11 tipos diferentes en total:

número de serie Codificación ilustrar
1 CODIFICACIÓN DE OBJ SIN PROCESAR cadena dinámica de codificación sin procesar
2 OBJ CODIFICACIÓN INT Cadena de enteros de tipo Long
3 OBJ_ENCODING_HT tabla hash (dict diccionario)
4 CODIFICACIÓN DE OBJ ZIPMAP obsoleto
5 OBJ_ENCODING_LINKEDLIST lista enlazada de dos extremos
6 ZIPLIST DE CODIFICACIÓN DE OBJ lista comprimida
7 OBJ_ENCODING INTSET conjunto de enteros
8 LISTA DE SALTOS DE CODIFICACIÓN DE OBJ mesa de salto
9 OBJ_ENCODING EMBSTR cadena dinámica para embstr
10 LISTA RÁPIDA DE CODIFICACIÓN DE OBJ_ lista rápida
11 FLUJO DE CODIFICACIÓN DE OBJETOS Arroyo

#tipo de datos

En Redis, se seleccionan diferentes métodos de codificación según el tipo de datos almacenados. La codificación utilizada para cada tipo de datos es la siguiente:

tipo de datos Codificación número de serie ilustrar
OBJ_STRING int, embstr, raw 0 cadena
OBJ_LIST LinkedList y ZipList (antes de 3.2), QuickList (después de 3.2) 1 la lista
OBJ_SET inserción、HT 2 recolectar
OBJ_ZSET ZipList, HT, SkipList 3 conjunto ordenado
OBJ_HASH ZipList、HT 4 tabla de picadillo

Aviso

Aquí solo hay 5 tipos básicos, y 3 tipos especiales no se mencionan, porque la capa inferior de estos tres tipos especiales se OBJ_STRINGimplementa usando, y no hay una nueva implementación de capa inferior.

# procesamiento de comandos

De acuerdo con la descripción anterior, cuando Redis ejecuta un comando, necesita juzgar el tipo de datos y el método de codificación que se ejecutará.Cuando Redis ejecuta un comando para procesar el tipo de datos, Redis realiza los siguientes pasos:

  1. De acuerdo con la clave dada, busque el redisObject correspondiente en el diccionario de la base de datos, si no lo encuentra, devuelva NULL
  2. Verifique si el atributo de tipo de redisObject coincide con el tipo requerido para ejecutar el comando; de lo contrario, el tipo de retorno es incorrecto
  3. De acuerdo con la codificación especificada por el atributo de codificación de redisObject, seleccione la función de operación adecuada para procesar la estructura de datos subyacente
  4. Devuelve el resultado de la operación en la estructura de datos como el valor de retorno del comando

Por ejemplo, ejecute el comando LPOP ahora:

# intercambio de objetos

Redis generalmente coloca algunos valores comunes en un objeto compartido, lo que evita que el programa tenga problemas de asignación repetida y ahorra algo de tiempo de CPU.

Los objetos de valor preasignados de Redis son los siguientes

  • El valor de retorno de varios comandos, como OK devuelto cuando tiene éxito, ERROR devuelto cuando ocurre un error, QUEUE devuelto cuando un comando pone en cola una transacción, etc.
  • Incluyendo 0, todos los números enteros menores que REDIS_SHARED_INTEGERS (el valor predeterminado de REDIS_SHARED_INTEGERS es 10000)

Aviso

Los objetos compartidos solo pueden ser utilizados por estructuras de datos como diccionarios y listas doblemente enlazadas que pueden tener punteros, y solo los punteros pueden apuntar a direcciones arbitrarias. Sin embargo, las colecciones de enteros y las listas comprimidas, que solo pueden almacenar datos reales, como cadenas y enteros, no se pueden compartir.

¿Por qué redis no comparte objetos de lista, objetos hash, objetos de colección, objetos de colección ordenados, sino solo objetos de cadena?

  • Los objetos de lista, los objetos hash, los objetos de colección y los objetos de colección ordenados pueden contener objetos de cadena, que tienen una gran complejidad.
  • Si el objeto compartido va a contener un objeto de cadena, entonces la complejidad de la operación de verificación es O(1)
  • Si el objeto compartido es un objeto de cadena que contiene un valor de cadena, la complejidad de la operación de validación es O(N)
  • Si el objeto compartido es un objeto que contiene varios valores y el valor en sí es un objeto de cadena, es decir, los objetos de cadena están anidados en otros objetos, como objetos de lista y objetos hash, entonces la complejidad de la operación de verificación será O (N al cuadrado)
  • Si crea un objeto compartido para un objeto de alta complejidad, necesita consumir mucha CPU y no es apropiado intercambiar este consumo por espacio de memoria. Y si la complejidad del objeto es demasiado alta, significa que el objeto tiene más personalidad y menos elementos comunes, por lo que el número y la frecuencia de uso del objeto serán muy bajos.

#contador de referencia

Hay un atributo refcount en RedisObject, que es un contador de referencias de objetos y se usa para registrar la cantidad de referencias de objetos.

Cuando el contador es 0, significa que no se hace referencia al objeto y no se volverá a utilizar, lo que significa que el objeto se puede eliminar y destruir.

Cuando se crea un objeto recientemente, su propiedad refcount se establece en 1.

Al compartir un objeto, Redis agrega uno al refcount del objeto.

Cuando se usa un objeto, o se elimina la referencia a un objeto, el programa decrementa el refcount del objeto en uno.

 

Supongo que te gusta

Origin blog.csdn.net/qq_33685334/article/details/131278579
Recomendado
Clasificación