redis可以存多少条数据_面试官:Redis数据结构与内部编码,你知道多少?

介绍

Redis是一个基于内存的数据库,所有的数据都存储在内存中,所以如何优化存储,减少内存空间占用对成本控制来说是非常重要的。精简键名和键值是最直观的减少内存占用的方式,而Redis则是通过内部编码规则来节省更多的内存空间。

Redis为每种数据类型都提供了两三种内部编码方式,以散列类型为例,散列类型是通过散列表实现的,这样就可以实现0(1)时间复杂度的查找、赋值操作,然而当键中元素很少的时候,0(1)的操作并不会比0(n)有明显的性能提高,所以这种情况下Redis会采用一种更为紧凑但性能稍差(获取元素的时间复杂度为0(n))的内部编码方式。内部编码方式的选择对于开发者来说是透明的,Redis会根据实际情况自动调整。当键中元素变多时Redis会自动将该键的内部编码方式转换成散列表。


一、Redis DB数据结构

Redis中是有16个redisDB库,默认是使用第一个。我们先来看下redisDB的数据结构:

fcfa3ffe1b4d457e738c66a8e3aaa653.png

  • dict:字典

  • dictht:就是一个hashtable,以o(1)时间复杂度获取size,used当前数组里面用掉了多少空间

  • dictEntry:数组里面的元素,**table指针指向数组,redis中所有的key都是存在dictEntry中

  • *var:存储key的值,也是一个指针,指向redisObject结构进行数据存储,这个指针指向真实的数据存储

  • next:当key发生hash冲突时(比如都是数组0),通过next指针建立一个单向的链表解决hash冲突

robj字段介绍:

  • type:对外的数据类型,string,list,hash,set,zset等

  • encoding:内部编码,raw,int,ziplist等,对内存利用率极致追求

  • LRU_BITS:内存淘汰策略

  • refcount:redis内存管理需要

  • *ptr:指向真实的数据存储结构,ziplist等,最终指向数据编码的对象

二、内部编码方式

下面是Redis数据结构与内部编码的关系:

9d5433b75db5ac4320dc8c3a65d5c841.png

查看一个键的内部编码方式:

127.0.0.1:6379> set foo barOK127.0.0.1:6379> object encoding foo"raw"

Redis的每个键值都是使用一个redisObject结构体保存的,在redis.h中声明的redisObj定义的如下:

typedef struct redisObject {   unsigned type:4; /** 4 bit */   unsigned encoding:4; /** 4 bit */   unsigned lru:LRU_BITS; /** 24 bit */  int refcount;  /** 4 byte */  void * ptr;  /** 8 byte */}robj;

其中type字段表示的是键值的数据类型,取值可以是如下内容:

#define REDIS_STRING 0 #define REDIS_LIST 1 #define REDIS_SET 2 #define REDIS_ZSET 3 #define REDIS_HASH 4

encoding字段表示的就是Redis键值的内部编码方式,取值可以是:

#define REDIS_ENCODING_RAW 0 /** Raw representation */ #define REDIS_ENCODING_INT 1 /** ed as integer */ #define REDIS_ENCODING_EMBSTR 2 /** cpu cache line */ #define REDIS_ENCODING_HT 3 /** Encoded as hash table */ #define REDIS_ENCODING_ZIPMAP 4 /** Encoded as zipmap */ #define REDIS_ENCODING_QUICKEDLIST 5 /** Encoded as regular quicked list */ #define REDIS_ENCODING_ZIPLIST 6 /** Encoded as ziplist */ #define REDIS_ENCODING_INTSET 7 /** Encoded as intset */ #define REDIS_ENCODING_SKIPLIST 8 /** Encoded as skiplist */

各个数据类型可能采用的内部编码方式以及相应的OBJECT ENCODING命令执行结果如下:

数据类型 内部编码方式 OBJECT ENCODING命令结果
字符串类型‍‍ REDIS_ENCODING_RAW "raw"
REDIS_ENCODING_INT "int"‍
REDIS_ENCODING_EMBSTR "embstr"
散列类型 REDIS_ENCODING_HT "hashtable"
REDIS_ENCODING_ZIPLIST "ziplist"
列表类型 REDIS_ENCODING_QUICKEDLIST "quickedlist"
REDIS_ENCODING_ZIPLIST "ziplist"
集合类型 REDIS_ENCODING_HT "hashtable"
REDIS_ENCODING_INTSET "intset"
有序集合类型 REDIS_ENCODING_SKIPLIST "skiplist"
REDI
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值