Redis数据结构概览
发表于|更新于
|浏览量:
Redis支持的主要有5种数据类型,string, list, set, zset , hash,但是对于每种数据类型,Redis都不是简单的使用一种数据结构来实现,而是根据数据量等因素使用多种数据结构(SDS、双向链表、hashtable等),来达到提高效率、节省空间的目的,可以使用object encoding <key> 来查看数据的内部结构

(注:对于Redis的早期版本,list 结构内部是使用双向链表实现的)
相关推荐
2019-06-21
Redis内存优化小技巧
在Redis中,相同的数据,如果我们使用不同的数据结构来存储,它们使用的内存大小差异可能是非常大的,要想更多的节省空间,我们不仅仅需要了解Redis的几种常用数据类型,还需要了解他们内部在不同情况下使用的具体数据结构 之前曾整理过一篇Redis每种数据类型及对应的内部结构,如果对此不太了解的同学可以先大致看一下 压缩数据结构 Redis为hash、set、zset都提供了对应的节约空间的数据结构存储方式,合理使用它们可以大大节约内存空间 下面以hash结构举例,其他的结构也是类似的 hash内部有两种结构 hashtable -哈希表 这是我们比较熟悉的一种结构,内部使用数组与链表结合,正常使用数组,如果遇到冲突则使用链表 查找迅速但是比较占用空间 ziplist - 压缩列表 使用条件: 键和值的长度都不能超过64字节(可通过 hash-max-ziplist-value配置) 键值对数量小于512个(可通过 hash-max-ziplist-entries配置) ziplist的使用条件虽然苛刻了一些,但是如果满足条件后,则可以节省很多的空间 它内部使用的是一段连续内存...
2020-03-15
Redis RDB与AOF
Redis的存储是基于内存的,这就有意味着,如果服务重启那么所有的数据都会丢失,这是我们不能接受的,为此,Redis提供了 RDB 与 AOF 两种持久化机制 简介 RDB: 对于RDB,我们可以把它理解一个定时的快照,就是每隔一段时间(或其他策略),它会创建一个当时所有数据的一个快照,默认存储到的文件为 dump.rdb AOF: 因为RDB创建的是所有数据的快照,这点就决定了它不可能进行高频率的执行,但是如果不经常性的执行,那么当出现如服务器宕机等情况时,会丢失从上次快照到当前的所有操作数据。为了解决这个问题,AOF应运而生,它会在每次执行操作的时候,将这个操作命令进行持久化存储,默认存储到的文件为 appendonly.aof,这样恢复的时候,可以将 aof文件中的所有命令重新执行一遍,即可恢复数据 配置及使用 RDB和AOF的配置都在redis的配置文件redis.conf中进行配置,我们看下主要的配置 RDB的主要配置如下 1234567rdbcompression yes # 是否使用 LZF算法 压缩字符串dbfilename dump.rdb # 持久...
2019-06-02
Redis Rehash源码分析
接着之前说过的 Java HashMap的Rehash,这次我们来看看 Redis中的 hash结构(对应Java中的Map)是如何实现rehash的。 这次先说下结论,它的结构与HashMap基本一致,只是它有两个哈希表,平时只使用其中的第一个,在发生rehash时,会逐渐的将元素转移到另一个表中,全部转移完成后,再将引用赋值给第一个哈希表 下面我们来开始看代码 注:为了简化代码,只保留了源码中的主要字段,不是完整源码,需要的可以参看Redis源码 12345678910111213141516171819202122// 字典typedef struct dict { // 哈希表(一共有两个,这是rehash的关键) dictht ht[2]; long rehashidx; /* 没有在进行rehash时,rehashidx == -1 */} dict;// 哈希表// 每个字典都使用两个哈希表,从而实现渐进式 rehash(从一个哈希表渐进转到另一个哈希表)typedef struct dictht { dict...
2019-01-26
Redis数据结构-SDS
基本结构 Redis中没有使用C语言原生的字符串,而是在其基础上包装了一个新的数据结构-SDS,其结构如下 1234567891011// 指向下面结构中的buf指针typedef char *sds;struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len; // 使用到的空间 uint8_t alloc; // 分配的C语言字符串空间,不包括头部和C字符串的中止符号null unsigned char flags; // 使用后三位表示是sdshdr8/sdshdr16的类型 char buf[]; // 实际字符数组的空间}// 类似的还有 sdshdr16, sdshdr32等,用于节省空间// 其中的所有方法都在此结构基础上实现 主要方法及实现 sdslen(sds s) - 获取sds中已经使用的数组空间大小 根据flags判断类型,将指向buf的指针前移到结构开始,转换为结构类型,获取len属性返回 源码如下 123456789101112131415161718...
2019-06-08
Redis服务端-客户端通信协议
了解Redis通信内容 Redis我们都比较熟悉,可以用来做缓存、分布式锁等,但是,其中的客户端与服务端是如何进行通信的呢? 我们可以分别模拟一个服务端或者客户端,打印查看来自实际连接的请求来获取它们的通信方式 首先,让我们先使用先模拟一个服务端,使用Jedis进行连接查看 1234567891011121314// 一个简单的demopublic class MockRedisServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(6379); Socket socket = serverSocket.accept(); try (InputStream inputStream = socket.getInputStream(); final OutputStream outputStream = socket.getO...
