Redis有5种基本数据类型它们分别是String、List、Hash、Set、ZSet;此外还有三种特殊数据类型Bitmaps、Geospatial、HyperLogLog
| 数据类型 | 简单描述 | 使用场景 |
| — | — | — |
| String | string(字符串)是Redis最简单也是使用最广泛的数据结构,它的内部是一个字符数组。String(字符串)是动态字符串,允许修改;它在结构上的实现类似于Java中的ArrayList(默认构造一个大小为10的初始数组),这是冗余分配内存的思想,也称为预分配;这种思想可以减少扩容带来的性能消耗。当string(字符串)的大小达到扩容阈值时,将会对string(字符串)进行扩容,string(字符串)的扩容主要有三种情况:1.长度小于1MB,扩容后为原先的两倍; length = length * 2 2.长度大于1MB,扩容后增加1MB; length = length + 1MB 3. 字符串的长度最大值为 512MB | 缓存、计数器、分布式锁等。 |
| List | Redis的列表相当于Java语言中的LinkedList,它是一个双向链表数据结构(但是这个结构设计比较巧妙,后面会介绍),支持前后顺序遍历。链表结构插入和删除操作快,时间复杂度O(1),查询慢,时间复杂度O(n)。Redis的list(列表)不是一个简单。LinkedList,而是quicklist ——“快速列表”,quicklist是多个ziplist(压缩列表)组成的双向列表; | 链表、异步队列、微博关注人时间轴列表…… |
| Hash | Redis的hash(字典)相当于Java语言中的HashMap,它是根据散列值分布的无序字典,内部的元素是通过键值对的方式存储。hash(字典)的实现与Java中的HashMap(JDK1.7)的结构也是一致的,它的数据结构也是数组+链表组成的二维结构,节点元素散列在数组上,如果发生hash碰撞则使用链表串联在数组节点上。Redis中的hash(字典)存储的value只能是字符串值,此外扩容与Java中的HashMap也不同。Java中的HashMap在扩容的时候是一次性完成的,而Redis考虑到其核心存取是单线程的性能问题,为了追求高性能,因而采取了渐进式rehash策略。渐进式rehash指的是并非一次性完成,它是多次完成的,因此需要保留旧的hash结构,所以Redis中的hash(字典)会存在新旧两个hash结构,在rehash结束后也就是旧hash的值全部搬迁到新hash之后,新的hash在功能上才会完全替代以前的hash。 | 用户信息、Hash 表…… |
| Set | Redis的set(集合)相当于Java语言里的HashSet,它内部的键值对是无序的、唯一的。它的内部实现了一个所有value为null的特殊字典。集合中的最后一个元素被移除之后,数据结构被自动删除,内存被回收。 | 去重功能、赞、踩、共同好友…… |
| ZSet | zset(有序集合)是Redis中最常问的数据结构。它类似于Java语言中的SortedSet和HashMap的结合体,它一方面通过set来保证内部value值的唯一性,另一方面通过value的score(权重)来进行排序。这个排序的功能是通过Skip List(跳跃列表)来实现的。zset(有序集合)的最后一个元素value被移除后,数据结构被自动删除,内存被回收。 | 粉丝列表、学生成绩排序、访问量排行榜、点击量排行榜…… |
| Bitmaps | Bitmaps 称为位图,严格来说它不是一种数据类型。Bitmaps底层就是字符串(key-value)byte数组。我们可以使用普通的get/set直接获取和设值位图的内容,也可以通过Redis提供的位图操作getbit/setbit等将byte数组看成“位数组”来处理。Bitmaps 的“位数组”每个单元格只能存储0和1,数组的下标在Bitmaps中称为偏移量。Bitmaps设置时key不存在会自动生成一个新的字符串,如果设置的偏移量超出了现有内容的范围,就会自动将位数组进行零扩充 | 员工打卡…… |
| Geospatial | Geospatial是Redis在3.2版本以后增加的地理位置GEO模块 | 微信附近的人,在线点餐“附近的餐馆”…… |
| HyperLogLog | HyperLogLog是用来做基数统计的算法,它提供不精确的去重计数方案(这个不精确并不是非常不精确),标准误差是0.81%,对于UV这种统计来说这样的误差范围是被允许的。HyperLogLog的优点在于,输入元素的数量或者体积非常大时,基数计算的存储空间是固定的。在Redis中,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同的基数。但是HyperLogLog只能统计基数的大小(也就是数据集的大小,集合的个数),他不能存储元素的本身,不能向set集合那样存储元素本身,也就是说无法返回元素。 | 基数统计比如UV等 |
这个我的理解大致是这样的面试官!!
Redis的数据结构均可以通过EXPIRE key seconds 的方式设置key的过期时间(TTL)。我们也习惯的认为Redis的key过期时间到了,就会自动删除,显然这种想法并不正确。Redis的设计考虑到性能/内存等综合因素,设计了一套过期策略。
-
主动删除(惰性删除)
-
被动删除(定期策略)
主动删除(惰性删除)指的是当key被访问的时候,先校验key是否过期,如果过期了则主动删除。 被动删除(定期策略)指的是Redis服务器定时随机的测试key的过期时间