首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

redis为什么这么快

一、使用内存进行存储

我们都知道redis是使用内存来进行数据的存储,这也是为什么redis的访问速度要远远快于mysql的主要原因,因为是使用内存存储数据,可以避免频繁的进行写盘操作,大大降低响应时间:

二、单线程结构

多线程一定比单线程快嘛?

虽然我们知道当我们使用多线程的时候,可以加快我们的系统访问,但是在使用多线程的过程中,对于共享变量的访问,会将多线程操作变成单线程进行操作,并且还需要增加额外的同步术语(例如java中的锁),存在的一定的性能开销,并且多个线程在进行锁竞争的时候,也会影响系统的吞吐性,所以多线程不一定比单线程快。

redis采用单线程来处理主要的响应命令,既不需要考虑数据安全问题,不需要额外去使用锁来降低性能开销,同时可以避免多线程的上下文切换的开销,并且CPU并不是redis的主要性能瓶颈。

redis的单线程并不是指,在整个redis的服务端只有一个线程在进行工作,只是在接受客户端的IO请求响应进行读写的时候是单线程的操作;redis本身是存在多线程的使用场景的,比如:异步删除、持久化、集群同步。

三、高性能的多路复用IO模型

可以与java的nio进行类比,相当于就是使用的是非阻塞性io模型,一个线程可以处理多个客户端连接,并且通过事件监听的机制,并通过基于事件的回调机制,即针对不同事件的发生,调用相应的处理函数,通过这种事件回调机制,可以避免redis去一直轮询关注是否有对应的事件发生,避免cpu的浪费。相当于redis单线程不会阻塞在某一个特定的操作上,所以一个redis的服务端,可以提供给多个客户端进行连接。

四、丰富的数据结构

redis是一个键值对存储的关系型数据库,对于key来说就是单一的string结构,但对于value,提供了丰富的数据结构:string、list、hast、set、sorted set。

String的底层是(简单动态字符串)

List的底层是(双向链表和压缩链表)

Hash的底层是(压缩链表和哈希表)

Set的底层是(整数数组和哈希表)

Sorted Set底层(压缩链表和跳表)

为了保证数据的快速查找redis的键值对采用的是哈希表的存储方式,来进行数据的存储,但因为其value的多样性,哈希表中存储的并不是具体的值,而是一个内存引用地址,在通过内存引用的地址查找到对应的具体的值。其结构如下图所示:

因为hash的结构,所以其查找数据的时间复杂度为O(1)。

但是存在的问题就是如果我们需要存储的key值在不断增长的过程中,就会存在一个影响性能的问题,就是哈希碰撞问题,当多个key值的hash落在同一个,就需要分成对应的链表进行,其结构如下所示:

所以当一个哈希桶下面挂了太多的数据的时候,那么其性能就会下降,为了解决hash碰撞的问题,就需要进行rehash,将我们的哈希桶位置增多,但是在rehash的过程中,需要进行大量的数据移动复制,那在rehash的时候肯定会影响我们的性能,那为了解决这个问题,将一次性的操作,分散到每个操作中,所以具体的逻辑就是。

redis在一开始的时候,就会存在两个hash表(hash1、hash2),一开始数据量不大的时候,我们的数据都会存放在hash1表中,当我们的key的数量在不断增加的时候,触发我们的rehash过程,这个时候hash2的结构是hash1的2倍,那么这个rehash的过程其实就是每一次操作过程中进行的,每次一个请求,都会将一个哈希桶的数据放在hash2中,这样可以将操作分散在每个操作中,不会出现系统突然的卡顿现象。其流程如下:

给哈希表2分配更大的空间,例如是原来哈希表1的两倍

将哈希表1中的数据重新映射并拷贝到哈希表2中;

释放掉哈希表1中的空间

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20201019A0I4WC00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券