1 什么是redis? 它是干什么的?
Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。
2 Redis的应用及数据结构
1. String(字符串)
String是Redis中最常用的一种数据类型,也是Redis中最简单的一种数据类型。首先,表面上它是字符串,但其实他可以灵活的表示字符串、整数、浮点数3种值。Redis会自动的识别这3种值。
举例:掘金每日连续签到
用户每日有一次签到的机会,如果断签,连续签到计数将归0。连续签到的定义:每天必须在23:59:59前签到
数据结构:sds
结构中的每个成员变量分别介绍下:
len,记录了字符串长度。这样获取字符串长度的时候,只需要返回这个成员变量值就行,时间复杂度只需要 O(1)。
alloc分配给字符数组的空间长度。这样在修改字符串的时候,可以通过 alloc - len 计算出剩余的空间大小,可以用来判断空间是否满足修改需求,如果不满足的话,就会自动将 SDS 的空间扩展至执行修改所需的大小,然后才执行实际的修改操作,所以使用 SDS 既不需要手动修改 SDS 的空间大小,也不会出现前面所说的缓冲区溢出的问题。
flags,用来表示不同类型的 SDS。一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64,后面在说明区别之处。
buf[],字符数组,用来保存实际数据。不仅可以保存字符串,也可以保存二进制数据。
2. List(列表)
实际上是一个链表,before Node after , left,right 都可以插入值
举例:消息通知
例如当文章更新时,将更新后的文章推送到ES,用户就能搜索到最新的文章数据
数据结构:Quicklist、Listpack
list 结构为链表提供了链表头指针 head、链表尾节点 tail、链表节点数量 len、以及可以自定义实现的 dup、free、match 函数。
3. Hash(哈希)
比String更加适合存对象
举例:一个用户有多项计数需求,可通过hash结构存储
数据结构:dict
Redis 采用了**「链式哈希」来解决哈希冲突,在不扩容哈希表的前提下,将具有相同哈希值的数据串起来,形成链接器,以便这些数据在表中仍然可以被查询到。不过,链式哈希局限性也很明显,随着链表长度的增加,在查询这一位置上的数据的耗时就会增加,毕竟链表的查询的时间复杂度是 O(n)。要想解决这一问题,就需要进行rehash,也就是对哈希表的大小进行扩展。
4. Zset(有序集合)
成绩表排序,工资表排序,年龄排序等需求可以用zset来实现
举例:积分排行榜
积分变化时,排名要实时变,结合dict后,可实现通过key操作跳表的功能
数据结构:zskiplist、dict
Zset 对象是唯一一个同时使用了两个数据结构来实现的 Redis 对象,这两个数据结构一个是跳表,一个是哈希表。这样的好处是既能进行高效的范围查询,也能进行高效单点查询。