这是我看完书,理解了之后,将其中的数据结构及其特性提取出来,方便复习用的。
- redis服务器内的数据库
- redisServer{
- redisDb *db;:redis默认创建16个数据库,都存放在redisDb这个类型的数组里。
- dbnum;:数据库个数
- };
- redisClient{
- redisDb *db;:每个redis客户端都有自己的目标数据库作为它的操作对象。
- };
- redisDb{
- dict *dict;:这个被指向的dict存放了所有key。它的值可以是字符串、链表、哈希表等。
- dict *expires;:这个被指向的dict存放了有过期时间的key。
- }
- redisServer{
- string字符串不修改时,用C字符串。
- 字符串修改时,用简单动态字符串SDS
- len长度,单位字节,不记录空字符。
- free未使用,单位字节
- buf 字节数组char []。结尾保存空字符是SDS函数自动完成的
- 优点
- 常数复杂度获取长度
- 不会因为没手动分配内存导致缓冲区溢出,(相比c字符串,由于数据被频繁修改,又需要高效,因此)优化了内存分配策略
- 不会因为没有分配足够内存导致缓冲区??溢出,因为在修改(扩增)字符串时,会先扩展内存空间,再修改字符串。
- 原则1:未使用空间free足够,内存不重分配。
- 原则2:修改后SDS的长度len小于1MB,那么设置free=len。
- 原则3:修改后SDS的长度len大于等于1MB,那么free=1MB。
- 原则4:字符串缩短时,不减长度,将长度累加到free中。但redis也提供了释放SDS的未使用空间的函数。
- C字符串中不能保存“\0”字符,因为会被误认为字符串结束了,因此它只能保存文本数据,不能保存图像视频音频压缩文件这样的二进制数据。但SDS是用len的长度来判断字符串是否结束,因此可以保存任意格式的二进制数据,因此是二进制安全的。buf(字节数组)里面存的是二进制数据而不是字符。?字符也是二进制数据?
- 可以使用部分<string.h>库中的函数。比如,如果有一个保存文本数据的SDS,就可以用<string.h>/strcasecmp函数。
- 问题:
- 图像视频音频压缩文件都能转成二进制吗
- //求字符数组的元素个数:i=szieof(B)/sizeof(char);字符的不同编码都能放进char数组中吗。
- list链表
- 当列表键包含的元素数量多,或者列表里都是长字符串,redis就会用链表list作为?列表键?的底层实现。
- 发布与订阅、慢查询、监视器等用到了链表,多个客户端的状态信息用到链表,构建客户端输出缓冲区用到了链表。
- 特性
- 双向链表
- 无环
- 表头list结构有指向表头和表尾的指针
- 表头记录了长度
- 多态:?链表节点使用void*指针来保存节点值,并且可以通过list结构的dup、free、match三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值?
- typedef struct listNode{ //listNode结构
- struct listNode *prev;
- struct listNode *next;
- void *value;
- }listNode;
- typedef struct list{ //list结构
- listNode *head;
- lsitNode *tail;
- unsigned long len; //节点数量
- void *(*dup) (void *ptr); //节点值复制函数。用于复制listNode的value
- void (*free) (void *ptr); //节点值释放函数。用于释放listNode的value
- int (*match) (void *ptr, void *key) //节点值对比函数。用于对比listNode的value与另一个输入值是否相等
- }list;
- 字典
- ?Redis的数据库用字典作为底层实现,对数据库的增删改查操作也是构建在对字典的操作之上?
- 是哈希键的底层实现?之一?
- 字典dict--->哈希表dictht--->dictEntry*[]--->哈希表节点dictEntry
- 哈希算法
- 链地址法解决哈希冲突
- 渐进法来rehash。rehash条件
- set
- sorted set跳跃表
- 跳跃表zskiplist--->跳跃表节点zskiplistNode
- intset正数集合
- 当集合只包含整数值元素,且元素数量不多。元素不重复
- ziplist压缩列表
- 是列表键和哈希键的底层实现。当哈希键只包含少量键值对,且值为小整数或短字符串,压缩列表就作为哈希键的底层实现。
- 结构
- previous_entry_length
- encoding
- content
- redisObject对象
- 包括字符串对象、列表对象、哈希对象、集合对象、有序集和对象。
- 对象系统利用引用计数法进行内存回收
- 记录了访问时间
- 生存时间
- PEXPIREAT将key的过期时间设置为timestamp,精度为毫秒。其它的设置命令都能转换成这个命令