本文已收录至Github,举荐浏览 Java随想录
微信公众号:Java随想录

摘要

Redis是一款开源的高性能key-value数据库,广泛应用于各种场景。在Redis中,数据类型(type)和编码(encoding)是十分重要的概念。本篇博客将具体介绍Redis反对的数据类型以及相应的编码方式和底层实现原理。

要查看Redis某个key的外部编码,能够应用Redis命令OBJECT ENCODING key。其中,key是你想要查问的键名。例如,如果你想要查问名为mykey的键的外部编码,能够执行以下命令:

127.0.0.1:6379> object encoding mykey  // 查看某个Redis键值的编码

redisObject

在 Redis 中,redisObject 是 Redis 中最根本的数据结构之一。redisObject 用于示意 Redis 中的键值对中的值,它能够是字符串、整数、列表、哈希表等任意一种 Redis 数据类型。

redisObject 的定义如下:

typedef struct redisObject {    // 类型    unsigned type:4;    // 编码方式    unsigned encoding:4;    // 援用计数    int refcount;    // 指向理论值的指针    void *ptr;} robj;
  • type:示意 redisObject 的类型。
  • encoding:示意 redisObject 的编码方式。
  • refcount:示意以后 redisObject 被援用的次数。
  • ptr: ptr字段则是一个指针,指向理论的 Redis 对象。

Redis源码encoding取值有如下几种:

#define OBJ_ENCODING_RAW 0        /* Raw representation */#define OBJ_ENCODING_INT 1        /* Encoded as integer */#define OBJ_ENCODING_HT 2         /* Encoded as hash table */#define OBJ_ENCODING_ZIPMAP 3     /* Encoded as zipmap */#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */#define OBJ_ENCODING_ZIPLIST 5    /* Encoded as ziplist */#define OBJ_ENCODING_INTSET 6     /* Encoded as intset */#define OBJ_ENCODING_SKIPLIST 7   /* Encoded as skiplist */#define OBJ_ENCODING_EMBSTR 8     /* Embedded sds string encoding */#define OBJ_ENCODING_QUICKLIST 9  /* Encoded as linked list of ziplists */

类型与编码介绍

Redis反对五种次要的数据类型:字符串(string)、列表(list)、汇合(set)、有序汇合(sorted set)和哈希(hash)。每种数据类型都有对应的编码方式。

数据类型与编码方式总览如下:

数据类型编码方式
字符串int、embstr、raw
哈希表ziplist、hashtable
列表ziplist、linkedlist、quicklist
汇合intset、hashtable
有序汇合ziplist、skiplist

字符串

字符串是Redis中最根本的数据类型,通常用于存储文本或二进制数据。Redis反对两种编码方式:

  • int:当字符串能够示意为整数时,Redis会将其转换为整数,并采纳int编码方式存储。int编码方式的长处是存储空间小,操作效率高。毛病是只能存储整数,不反对字符串操作。
  • embstr(embstr-encoded string):保留长度小于44字节的字符串,当一个字符串比拟短,采纳此编码方式存储,能够缩小内存占用。
  • raw(raw-encoded string):保留长度大于44字节的字符串,当一个字符串比拟长时,采纳此编码方式存储。

列表

列表是一系列有序的字符串汇合,能够增加、批改和删除元素。Redis反对三种编码方式:

  • ziplist:在Redis3.2版本之前,当List列表中每个字符串的长度都小于64字节并且List列表中元素数量小于512个时,List对象应用ziplist编码,其余状况应用linkedlist编码。ziplist是一种紧凑的、压缩的列表构造,能够节俭内存。实用于小型列表。
  • linkedlist:linkedlist是一种链表构造,反对任意大小的列表。但其内存占用会随着列表长度的减少而减少。
  • quicklist:Redis 3.2版本引入,quicklist是一种由多个ziplist组成的列表构造,既能保障性能,又能节俭内存。实用于大型列表。

汇合

汇合是一系列无序的字符串汇合,反对增加、删除和查问元素。Redis反对两种编码方式:

  • intset:当汇合中的元素都是整数时,Redis会采纳intset编码方式存储。intset编码方式的长处是存储空间小,操作效率高。
  • hashtable:当汇合中的元素蕴含字符串时,Redis会采纳hashtable编码方式存储。hashtable编码方式的长处是能够存储任意类型的元素,反对字符串操作。毛病是存储空间绝对较大,操作效率绝对较低。

有序汇合

有序汇合是一系列无序的字符串汇合,每个元素关联一个分数,能够依据分数排序。Redis反对两种编码方式:

  • ziplist:保留的元素少于128个并且所有元素大小都小于64字节应用ziplist编码,ziplist是一种紧凑的、压缩的列表构造,实用于小型有序汇合。
  • skiplist:skiplist是一种跳跃表构造,反对疾速查问和排序。实用于大型有序汇合。

哈希表

哈希表是一系列键值对汇合,每个键关联一个值。Redis反对两种编码方式:

  • ziplist:哈希对象保留的所有键值的字符串长度小于64字节并且键值对数量小于512个,Redis会采纳ziplist编码方式存储。ziplist编码方式的长处是存储空间小,操作效率高。毛病是不反对疾速的键查找操作。
  • hashtable:除上述条件之外,Redis会采纳hashtable编码方式存储。hashtable编码方式的长处是反对疾速的键查找操作。毛病是存储空间绝对较大,操作效率绝对较低。

类型与编码底层原理

理解Redis反对的数据类型和编码方式后,咱们来看一下它们的底层实现原理。

编码转换

Redis中的每个键值对都有一个类型标识,示意该键值对的数据类型。当咱们对一个键进行操作时,Redis会依据该键以后的编码方式以及操作所需的编码方式,对键值对进行编码转换。

例如,当咱们向一个字符串中追加内容时,如果该字符串以后的编码方式为raw,然而新的内容能够应用embstr编码方式存储,那么Redis会将该字符串的编码方式从raw转换为embstr。

数据结构

除了编码方式外,Redis还应用了许多经典的数据结构来实现各种数据类型。例如,Redis的列表和哈希表都是采纳链表构造实现的。而有序汇合则采纳了跳跃表(Skip List)这种高效的数据结构。

这些数据结构都通过了精心设计和优化,以满足各种场景下的利用需要。例如,链表构造适宜频繁地增加和删除元素,而跳跃表构造则适宜排序和查找。

总结

本篇博客介绍了Redis反对的五种次要数据类型以及相应的编码方式。Redis的数据类型和编码方式是为了在不同的场景下达到最佳的性能和内存占用。在应用Redis时,须要依据理论状况抉择适合的数据类型和编码方式,以达到最佳的成果。同时,须要留神不同数据类型和编码方式的优缺点,以便在理论应用中做出正当的抉择。


本篇文章就到这里,感激浏览,如果本篇博客有任何谬误和倡议,欢送给我留言斧正。文章继续更新,能够关注公众号第一工夫浏览。