【Redis——数据类型和内部编码和Redis使用单线程模型的分析】


在这里插入图片描述
在这里插入图片描述
总而言之,Redis提供的哈希表容器并不一定真的是真的哈希表,而是在特点的场景下,用别的容器去实现,为了保证时间复杂度符合承诺(就是为了高效)

Redis的数据类型和内部编码

在这里插入图片描述

string
(由于只学过C++,这里只站在C++的角度理解Redis中的数据结构

  • raw:最基本的字符串,底层就是持有一个char数组(C++)。
  • int:当value是一个整数时,此时redis可能用int来保存。
  • embstr:针对短字符串进行的特殊优化。

以上内部编码方式Redis会自动适应,在使用时感知不到。

hash:

  • hashtable:虽然有可能实现方式不太一样,但是整体的思想跟C++的哈希表是一样的。
  • ziplist:压缩列表,在哈希表元素较少的时候,可能优化成ziplist压缩列表,就能够节省空间。因为元素较少,所以遍历的时候仍然能视为O(1)的时间复杂度。

为啥要压缩,为啥要节省时间呢?
因为在key特别多的情况下,如果key对应的value都是哈希表,则对应的hash也特别多,但是每个hash又不大的情况下,就可以将这些hash压缩,让整体占用内存更少。

list:

  • linkedlist:链表,就是数据结构中熟悉的那个链表,包括单链表,双链表。
  • ziplist:如果元素个数少,就用压缩列表实现,因为节省空间,如果元素个数多,那就会用链表。
    从redis3.2版本开始,引入了新的实现方式:quicklist,这个就同时兼顾了linkedlist和ziplist的优点。
    可以认为quicklist就是一个链表,链表的每个元素是ziplist。这样的折中方案把空间和效率都兼顾了。
    所以quicklist就比较像C++的deque。

set:

  • hashtable:这个跟前面那个讲解一样,看上面那个即可。
  • intset:针对特定场景的优化:比如集合中都是一个整数,就优化成intset

zset:

  • skiplist:跳表。在链表的笔试题中,有一道题叫做:“复杂链表的复制”,除了有一个next指向下一个节点外,还有一个Random节点指向其他随机节点。这里的跳表同理,每个节点上有多个指针域的指向,巧妙的搭配这些指针域的指向,就能做到查找时的时间复杂度O(logN)

  • ziplist:看上面的解释

通过object encoding key来查看key对应的value的编码方式。
比如:

set key1 1
object encoding key1,可以得到key1对应的value的编码方式是int

单线程模型的工作过程

在这里插入图片描述

Redis在处理命令时虽然是一个单线程模型,为啥效率那么高,速度快呢?

(这里不是说Redis是单线程,虽然在早期版本确实是单线程,但是在后面的版本中,Redis引入了多线程来保证网络IO,持久化等,但是处理命令时,仍然是单独开一个线程专门处理的)
(面试题)(说Redis快的参照物是关系型数据库:MySQL等)

  • 1.redis访问内存,MySQL访问硬盘。
  • 2.redis的核心功能比数据库的核心功能简单。比如针对插入删除,数据库的各种约束(主键约束,外键约束),在插入时,会先判断在不在,判断完成后,还得找个位置插入。这样同样又会有消耗。
  • 3.单线程模型避免了不必要的线程竞争开销。Redis的每个基本操作都是短平快的,就是简单地操作内存,没多大消耗CPU,就算搞个多线程提升不大(具体得看业务场景)。
  • 4.处理网络IO时,使用了epoll的I/O多路复用。一个线程可以管理多个socket,对TCP来说,当客户端到来时,都要给该客户端设置一个socket,并且在很多情况下,大部分客户端的通信并没有那么频繁,而是仅仅有少量客户端是活跃的。但是在传统的IO时,是为一个客户端创建一个线程专门服务的。而大部分客户端只发了几次数据就不活跃了。此时线程也会被阻塞住,而线程创建,销毁,调度都是消耗性能的操作。所以使用I/O多路服用,让一个线程同时监听处理多个socket,大大提高了效率。(但是,一个线程监听多个socket是只有当这些socket只有少量是活跃的时候才能这样做。否则这些socket如果同时非常活跃,就可能导致线程忙不过来。打游戏+和女朋友打电话的例子)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邓富民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值