上一篇文章中说过,Redis快的原因就是因为Redis有着合理选择的数据结构,提供高效的存储和快速的访问能力,这一篇文章我们就来看看Redis中的数据结构
Redis的数据结构
- String
- List
- Hash
- Set
- Sorted Sets
- 布隆过滤器
1.String
实现
(1)Redis中String是基于SDS实现的。
SDS是Redis中的一种底层数据结构,Redis对C语言原生的字符串进行了结构体封装;
type struct{ free //当前buf中可用的大小 len //当前buf的长度 buf //存储数据的buf地址 }SDS
使用SDS后,Redis可以O(1)时间获取字符串长度,可以动态的调整字符串的大小,避免了频繁的内存申请和释放。
用途
K-V中的K都是由String实现,可用来存储简单的整数,字符串等数据
2.List
实现
Redis中的List由两种存储方式分别是ziplist、linklist
(1)当存储元素数量少,元素占用内存更小时使用ziplist
(2)除去(1)的情况使用linklist
linklist:
双端链表,支持前后访问
ziplist:
压缩列表,更加节省内存,少了pre 和next 两个指针,ziplist在申请内存是连续分配的,存储效率很高,但是在修改数据时会重新申请整个内存,当数据量过大时,会造成大量的数据拷贝。
用途
和语言层面的List一样,Redis中List支持两端数据的插入和删除,可用来实现简单的队列,栈等数据机构。
3.Hash
实现
(1)当数据量较少时使用ziplist实现
(2)当数据量大时,使用哈希表存储
Redis中哈希表基本知识点:
- 负载因子
未执行BGSAVE时,负载因子大于1就扩容
执行BGSAVE时,负载因子大于5再扩容
- 哈希冲突
通过链地址法解决哈希冲突---和Golang一致
- 扩容方式
渐进式扩容---和Golang一致。记录扩容的状态,慢慢的扩容
用途
Redis中Hash是一种键值对集合,一般在Redis中用来存储更加复杂的value值,比如存储一个商品或者人物的Json。
4.Set
实现
(1)当数据量过少时使用intset(整数数组)实现
(2)当数据量过多时使用hash表实现
用途
Redis 的集合是一个无序的字符串集合,不允许重复的元素。提供交集、并集和差集等集合运算。可应用于好友关系和推荐系统等场景。
5.Sorted Set
实现
(1)当数据量过少时使用ziplist实现
(2)当数据量过大时使用skiplist实现
skiplist(跳表)是Redis中实现的一种数据结构。思想就是通过多级索引对链表进行二分。每一层索引都可以快速判断数据是否在当前半区(二分思想)。
用途
Redis 的有序集合是一个有序的字符串集合,每个元素关联着一个分数,用于排序和排名。有序集合支持按照分数范围进行快速的查找和排名操作,可应用于排行榜、热门文章等场景。
6.布隆过滤器
实现
基于hash表和bitmap思想实现。对k进行hash计算,通过bitmap存入。
误判是怎么产生的?
(1)将k1进行hash得到hash值 h1。
(2)检测k2是否存在集合内,对k2 hash,得到hash值h1。
可以看到此时k2并不存在但是误判成存在了,根本原因就是hash函数差,导致出现hash冲突。
总结:
布隆过滤器只能告诉我们k绝对不在集合内或者可能在集合内。
解释:
(1)根据hash值认定k不存在集合内。此时集合内一定不存在k
(2)根据hash值认定k存在集合内。此时集合内可能有k。若未误判,k存在集合内。若误判,k不存在集合内。
用途
用于快速判断某个K是否存在集合内。
介绍
我是烤鱼。目前是一名Golang开发者,使用过C++、Python等语言。目前正在整理一些后端的基础知识,主要包括Golang、Python、Mysql、Redis、Kafka、计算机网络、分布式等面试经常考察的知识点,以及面试热门的leetcode算法题解,希望大家互相学习进步。想要查看更多、更全的文章,请关注我的公众号 <喜欢吃烤鱼>