Redis
-
Redis常规八股(Redis common interview questions and concepts):
- Redis是什么?(What is Redis?):Redis是一个开源的内存数据存储系统,可以用作数据库、缓存和消息中间件。
- Redis的特点是什么?(What are the features of Redis?):Redis具有高性能、支持多种数据结构、提供持久化选项、支持复制和高可用性、可通过插件扩展功能等特点。
- Redis支持哪些数据结构?(What data structures does Redis support?):Redis支持字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)、位图(Bitmap)、HyperLogLog和地理空间索引(Geospatial Index)等数据结构。
-
Redis的八种数据结构(Eight data structures in Redis):
- 字符串(String):简单的键值对存储。
- 哈希(Hash):键值对的集合,可以嵌套存储多个字段和对应的值。
- 列表(List):按照插入顺序排序的字符串元素集合,可以在列表的两端进行插入和删除操作。
- 集合(Set):不重复字符串元素的无序集合,支持集合操作(交集、并集、差集等)。
- 有序集合(Sorted Set):类似于集合,但每个元素都关联了一个分数,可以根据分数进行排序。
- 位图(Bitmap):由二进制位组成的数据结构,可以进行位级别的操作。
- HyperLogLog:用于基数(cardinality)估算的数据结构,可以统计一组元素的独立数量。
- 地理空间索引(Geospatial Index):用于存储和操作地理空间位置信息的数据结构。
• String 类型的应用场景:缓存对象、常规计数、分布式锁、共享 session 信息等。
• List 类型的应用场景:消息队列(但是有两个问题:1. 生产者需要自行实现全局唯一 ID;2. 不能以消费组形式消费数据)等。
• Hash 类型:缓存对象、购物车等。
• Set 类型:聚合计算(并集、交集、差集)场景,比如点赞、共同关注、抽奖活动等。
• Zset 类型:排序场景,比如排行榜、电话和姓名排序等。
-
ZSet的跳表原理(Skip List principle in ZSet):
- 有序集合(Sorted Set)在Redis中使用了跳表(Skip List)数据结构来实现。
- 跳表是一种基于有序链表的数据结构,通过在链表中添加多级索引节点,提高了查询有序数据的效率。
- 在有序集合中,每个元素都有一个对应的分数,通过分数来进行排序。
- 跳表中的索引节点包含了指向下一级索引节点的指针,可以通过这些索引快速定位到目标元素的位置。
-
用Redis实现分布式ID(Implementing distributed ID with Redis):
- 可以使用Redis的原子操作来实现分布式ID生成器。
- 一种常见的实现方式是使用Redis的自增操作(INCR)来生成唯一的递增ID。
- 在分布式环境下,可以使用Redis的分布式锁来确保ID的唯一性和一致性。
- 通过在Redis中维护一个计数器,每次请求获取ID时,使用自增操作获取新的ID值即可。
-
String 类型内部实现
String 类型的底层的数据结构实现主要是 SDS(简单动态字符串)。 SDS 和我们认识的 C 字符串不太一样,之所以没有使用 C 语言的字符串表示,因为 SDS 相比于 C 的原生字符串:
SDS 不仅可以保存文本数据,还可以保存二进制数据。因为 SDS 使用 len 属性的值而不是空字符来判断字符串是否结束,并且 SDS 的所有 API 都会以处理二进制的方式来处理 SDS 存放在 buf[] 数组里的数据。所以 SDS 不光能存放文本数据,而且能保存图片、音频、视频、压缩文件这样的二进制数据。
SDS 获取字符串长度的时间复杂度是 O(1)。因为 C 语言的字符串并不记录自身长度,所以获取长度的复杂度为 O(n);而 SDS 结构里用 len 属性记录了字符串长度,所以复杂度为 O(1)。
Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出。因为 SDS 在拼接字符串之前会检查 SDS 空间是否满足要求,如果空间不够会自动扩容,所以不会导致缓冲区溢出的问题。
-
Redis 如何做内存优化?
可以好好利用 Hash,list,sorted set,set 等集合类型数据,因为通常情况下很多小的 Key-Value 可以用更紧凑的方式存放到一起。尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的 web 系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的 key,而是应该把这个用户的所有信息存储到一张散列表里面。 -
Redis为啥快,为啥单线程,为啥用它不用其他的,只有单线程吗?除了缓存还能干啥
Redis之所以快速的原因有多个方面。首先,Redis将数据存储在内存中,避免了磁盘I/O的开销,提高了读写速度。
其次,Redis采用单线程的方式处理请求,避免了多线程之间的锁竞争和上下文切换的开销。单线程模型简化了Redis的内部实现,使得它能够高效地处理请求。
此外,Redis还通过异步的方式将数据写入磁盘,保证了数据的持久性。除了作为缓存使用外,Redis还可以用于实现消息队列、实时统计、分布式锁等功能