八股文之Redis篇

前言

Redis的应用场景有很多,比如缓存、分布式锁、消息队列、延迟队列、排行榜,每一个场景都会有对应的问题和成熟的解决方案,都需要进行了解,特别要结合自身的项目进行侧重。下面会列出多种面试会问到的点,以及一些解决方案。

Redis底层中的数据结构

  • SDSSimple Dynamic String):简单动态字符串,代替了C语言的中的char *定义的字符串,因为其有很多问题,比如:内存分配带来的开销、安全性问题(C 语言的字符串没有保存字符串的长度信息,容易导致缓冲区溢出和越界访问等安全问题)、复杂的字符串操作问题,所以SDS的优点有如下:O(1) 时间获取字符串的长度、支持动态扩容、使用预分配来减少内存分配次数、拥有二进制安全(涉及到二进制字符、字符串长度信息、越界访问等等)。
  • IntSet:IntSet是Redis中Set集合的一种实现方式,基于整数数组来实现,具备长度可变、有序等特性,Redis会确保intSet中的元素唯一、有序,具备类型升级机制、可以节省内存空间、底层采用二分查找的方式来查询,数据量不多的情况下使用最佳。
  • Dict(dictionary):实现键与值的映射关系的数据结构,包括Dict + dictHashTable + dictEntry,渐进式rehash
  • ZipList:是一种特殊的双端链表,由一系列特殊编码的连续内存块组成,可以在任意一段进行插入和弹出操作,并且读取操作的时间复杂度是O(1),节省内存,但是必须是连续空间,一旦内存占用多,则申请内存得效率很低
  • QuickList:Redis3.2引入的,是一个双端链表,只不过链表中得每一个节点都是ZipList
  • SkipList:是一个双向链表,元素按照升序排列存储,节点包含多个指针,指针的跨度不同,最多32层,实现相比红黑树更加简单,层数越大,跨度越大,crud效率和红黑树基本一致
  • RedisObject:Redis中的任意数据类型的键和值都会被封装成一个RedisObject

Redis中的编码方式

在这里插入图片描述

Redis数据类型对应的编码方式

在这里插入图片描述
String:编码方式RAW编码,基于SDS实现,存储上限为512mb,如果SDS长度小于44字节,则会采用EMBSTR编码,如果存储的字符串是整数值,并且大小在LONG_MAX范围内,则会采用INT编码:直接将数据保存在RedisObject的ptr指针位置(刚好8字节)
List:3.2版本之前,Redis采用ZipList和LinkedList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList,超过则采用LinkedList编码实现。在3.2版本之后,Redis统一采用QuickList实现List
Set:采用HT编码(Dict)。Dict中的key用来存储元素,value统一为null(和Java中的HashMap与HashSet类型),当存储的所有数据都是整数,并且数量不超过set-max-intset-entries时,set会采用IntSet编码,以节省内存
ZSet:也就是sorted set,其中每一个元素都需要指定一个score和member值,需要根据score值排序,member必须唯一,可以根据member查询分数,能够总结出三个点:键值存储、键必须唯一、可排序,自然用到的编码方式就有:SkipList(可以排序,并且可以同时存储score和member值)、HT(Dict):可以键值存储、并且可以根据 key 找 value,优化点:当元素数量不多时,HT和SkipList的优势不明显,而且更消耗内存,因此zset还会采用ZipList接口来节省内存,不过需要同时满足两个条件:1.元素数量小于zset_max_ziplist_entries(默认128),2.每个元素都小于zset_max_ziplist_value字节(默认64)。ZipList本身没有排序功能,没有键值对的概念,因此需要由zset通过编码实现:ziplist是连续内存,而且score和element是紧挨在一起的entry,element在前,score在后,score越小越接近队首,越大越接近队尾,按照score值升序排列,这种方式只是为了节省内存,查询效率并不提升,这是兼顾内存节省和查询性能的表现。
Hash:Hash底层采用的编码和Zse基本一致,只需要把排序有关的SkipList去掉即可,Hash结构默认采用ZipList编码,以节省内存,ZipList中相邻的两个entry分别保存field和value,当数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值