范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

为什么Redis这么快之数据结构

  数据库这么多,为啥 Redis 能有这么突出的表现呢?一方面,这是因为它是内存数据库,所有操作都在内存上完成,内存的访问速度本身就很快。另一方面,这要归功于它的数据结构。
  如果问你 Redis 有哪些数据结构,大部分人都能答出:" 不就是 String(字符串)、List(列表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)吗?"。但其实这是表面的数据类型,是通过底层数据结构来实现的,方便开发者使用的封装数据类型。
  Redis 的底层数据有6种,分别是简单动态字符串、哈希表、压缩列表、快速列表、跳表和整数数组。
  看到上图我们会产生几个问题:这些数据结构都是值的底层实现,键和值本身之间用什么结构组织?为什么集合类型有那么多的底层结构,它们都是怎么组织数据的,都很快吗?什么是简单动态字符串,和常用的字符串是一回事吗?简单动态字符串
  Redis 中的字符串是可以修改的字符串,在内存中它是以字节数组的形式存在的。
  Redis 的字符串叫 SDS,也就是 Simple Dynamic String。它的结构是一个带长度信息的字节数组。struct SDS {   T capacity; // 数组容量   T len; // 数组长度   byte flags; // 特殊标识位,不理睬它   byte[] content; // 数组内容  } 复制代码
  如代码所示,content 里面存储了真正的字符串内容,capacity 表示所分配数组的长度,len 表示字符串的实际长度。前面我们提到字符串是可以修改的字符串,它要支持 append 操作。如果数组没有冗余空间,那么追加操作必然涉及到分配新数组,然后将旧内容复制过来,再 append 新内容。如果字符串的长度非常长,这样的内存分配和复制开销就会非常大。
  上面的 SDS 结构使用了范型 T,为什么不直接用 int 呢,这是因为当字符串比较短时,len 和 capacity 可以使用 byte 和 short 来表示,Redis 为了对内存做极致的优化,不同长度的字符串使用不同的结构体来表示。键和值用什么结构组织?哈希表
  Redis 使用了一个哈希表来保存所有键值对。
  一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以,我们常说,一个哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。
  这里有个疑问:如果值是集合类型的话,作为数组元素的哈希桶怎么来保存呢?
  答案是:哈希桶中的元素保存的并不是值本身,而是指向具体值的指针。这也就是说,不管值是 String,还是集合类型,哈希桶中的元素都是指向它们的指针。
  在下图中,可以看到,哈希桶中的 entry 元素中保存了 key 和 value 指针,分别指向了实际的键和值,这样一来,即使值是一个集合,也可以通过 value 指针被查找到。
  哈希表的最大好处很明显,就是让我们可以用 O(1) 的时间复杂度来快速查找到键值对——我们只需要计算键的哈希值,就可以知道它所对应的哈希桶位置,然后就可以访问相应的 entry 元素。
  这个查找过程主要依赖于哈希计算,和数据量的多少并没有直接关系。也就是说,不管哈希表里有 10 万个键还是 100 万个键,我们只需要一次计算就能找到相应的键。哈希冲突怎么解决
  当你往哈希表中写入更多数据时,哈希冲突是不可避免的问题。这里的哈希冲突,也就是指,两个 key 的哈希值和哈希桶计算对应关系时,正好落在了同一个哈希桶中。
  Redis 解决哈希冲突的方式,就是链式哈希。链式哈希也很容易理解,就是指同一个哈希桶中的多个元素用一个链表来保存,它们之间依次用指针连接。
  如下图所示:entry1、entry2 和 entry3 都需要保存在哈希桶 3 中,导致了哈希冲突。此时,entry1 元素会通过一个 next 指针指向 entry2 ,同样, entry2 也会通过next指针指向 entry3。这样一来,即使哈希桶 3 中的元素有 100 个,我们也可以通过 entry 元素中的指针,把它们连起来。这就形成了一个链表,也叫作哈希冲突链。
  但是,这里依然存在一个问题,哈希冲突链上的元素只能通过指针逐一查找再操作。如果哈希表里写入的数据越来越多,哈希冲突可能也会越来越多,这就会导致某些哈希冲突链过长,进而导致这个链上的元素查找耗时长,效率降低。对于追求"快"的 Redis 来说,这是不太能接受的。
  所以,Redis 会对哈希表做 rehash 操作。rehash 也就是增加现有的哈希桶数量,让逐渐增多的 entry 元素能在更多的桶之间分散保存,减少单个桶中的元素数量,从而减少单个桶中的冲突。那具体怎么做呢?
  简单来说就是在第二步拷贝数据时,Redis 仍然正常处理客户端请求,每处理一个请求时,从哈希表 1 中的第一个索引位置开始,顺带着将这个索引位置上的所有 entries 拷贝到哈希表 2 中;等处理下一个请求时,再顺带拷贝哈希表 1 中的下一个索引位置的 entries。如下图所示:
  这样就巧妙地把一次性大量拷贝的开销,分摊到了多次处理请求的过程中,避免了耗时操作,保证了数据的快速访问。压缩列表
  zset 和 hash 容器对象在元素个数较少的时候,采用压缩列表 ziplist 进行存储。
  压缩列表实际上类似于一个数组,数组中的每一个元素都对应保存一个数据。和数组不同的是,压缩列表在表头有三个字段 zlbytes、zltail 和 zllen,分别表示列表长度、列表尾的偏移量和列表中的 entry 个数;压缩列表在表尾还有一个 zlend,表示列表结束。
  在压缩列表中,如果我们要查找定位第一个元素和最后一个元素,可以通过表头三个字段的长度直接定位,复杂度是 O(1)。而查找其他元素时,就没有这么高效了,只能逐个查找,此时的复杂度就是 O(N) 了。
  压缩列表的设计不是为了查询的,而是为了减少内存的使用和内存的碎片化。比如一个列表中的只保存 int,结构上还需要两个额外的指针prev 和 next,每添加一个结点都这样。而压缩列表是将这些数据集合起来只需要一个 prev 和 next。快速列表
  Redis 早期版本存储 list 列表数据结构使用的是压缩列表 ziplist 和普通的双向链表 linkedlist,也就是元素少时用 ziplist,元素多时用 linkedlist。// 链表的节点  struct listNode {    listNode* prev;    listNode* next;    T value;  }  // 链表  struct list {    listNode *head;    listNode *tail;    long length;  } 复制代码
  考虑到链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 ( 64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。后续版本对列表数据结构进行了改造,使用 quicklist 代替了 ziplist 和 linkedlist。
  quicklist 是 ziplist 和 linkedlist 的混合体,它将 linkedlist 按段切分,每一段使用 ziplist 来紧凑存储,多个 ziplist 之间使用双向指针串接起来。
  quicklist 内部默认单个 ziplist 长度为 8k 字节,超出了这个字节数,就会新起一个 ziplist。ziplist 的长度由配置参数 list-max-ziplist-size决定。跳表
  有序链表只能逐一查找元素,导致操作起来非常缓慢,于是就出现了跳表。具体来说,跳表在链表的基础上,增加了多级索引,通过索引位置的几个跳转,实现数据的快速定位,如下图所示:
  如果我们要在链表中查找 33 这个元素,只能从头开始遍历链表,查找 6 次,直到找到 33 为止。此时,复杂度是 O(N),查找效率很低。
  为了提高查找速度,我们来增加一级索引:从第一个元素开始,每两个元素选一个出来作为索引。这些索引再通过指针指向原始的链表。例如,从前两个元素中抽取元素 1 作为一级索引,从第三、四个元素中抽取元素 11 作为一级索引。此时,我们只需要 4 次查找就能定位到元素 33 了。
  如果我们还想再快,可以再增加二级索引:从一级索引中,再抽取部分元素作为二级索引。例如,从一级索引中抽取 1、27、100 作为二级索引,二级索引指向一级索引。这样,我们只需要 3 次查找,就能定位到元素 33 了。
  可以看到,这个查找过程就是在多级索引上跳来跳去,最后定位到元素。这也正好符合"跳"表的叫法。当数据量很大时,跳表的查找复杂度就是 O(logN)。
  不同数据结构查找的时间复杂度如下图:
  作者:政采云技术团队
  链接:https://juejin.cn/post/7155638836763033637

宝妈带男童进女厕频惹争议专家呼吁未来可考虑增设儿童卫生间在围绕男童进女厕的争议中,男童的年龄往往被视为这一行为是否合理的关键点。一些到了入学年龄的男童,在父母眼里或许仍是个性别不分明的孩子,但在其他女性眼里已经属于异性。他们出现在异性的最小抑郁症患者才8岁出现这些症状家长要留意如今,精神疾病的发病年龄已经越来越低龄,暨南大学附属第一医院精神医学科主任潘集阳教授接诊的抑郁症患者中年龄最小的只有8岁,他表示,我国抑郁症识别率只有20,不到10接受过药物治疗。伤痛什么是积极的期待?没有一对父母不期望自己的孩子成龙成凤的。有的甚至一出生就被赋予沉重的期待,人生的方向也已被长辈安排指定好了。我们总在攀比。你看你那贼模样,成绩烂成这样,再看看人家佛山子女3周岁以内,父母每年各享10日假近日,佛山市优化生育政策促进人口长期均衡发展的实施方案(以下简称实施方案)正式印发实施。实施方案将婚嫁生育养育教育医疗住房等一体考虑,围绕实施三孩生育政策优生优育服务普惠托育服务降想要宝宝长个,春季补钙不要错过研究发现,每年35月是儿童少年的加速生长期,平均长高达到1。37厘米,明显高于其他季节。药补不如食补,这几样含钙量高的食物,可变着花样加入宝宝平时的饮食中。1。芝麻酱。芝麻酱富含蛋美国TMobile明年4月关闭2GGSM网络美国电信运营商TMobileUS最近透露,该公司将于2024年4月2日关闭其2GGSM网络。在此之前,TMobile在2022年期间关闭了其自身的3G网络以及并购获得的Sprint48岁吴彦祖美国被偶遇!挺大肚腩老到认不出,发际线上移险些秃头2月15日,有网友在美国街头偶遇了知名演员吴彦祖。该网友表示首次近距离与明星见面的心情,激动到无法用语言来形容,可见她是多么兴奋。除此之外,她还晒出了一张与男神的合照,久未露面的吴从美国俄亥俄升起的那朵蘑菇云,看化学品这把双刃剑的另一面头条创作挑战赛癸卯年伊始,一列运载有毒化学品氯乙烯的列车在美国俄亥俄州东部脱轨,瞬间,毒云漫天,毒光闪烁,动物哀亡,世人惊呼美国版切尔诺贝利和日本福岛核泄漏再现了。毋庸置疑,化学品美国著名战争的时间顺序美国历史上有许多著名的战争,这些战争在不同的时间和情境下对美国的发展产生了深远的影响。本文将按照时间顺序,简要介绍美国历史上的一些著名战争。独立战争(17751783)独立战争是美最短命的美国总统,就职后睡了一觉,第二天醒来总统已经换人在1849年3月,曾经有过一个任期仅为一天的总统。这位总统就职后一觉睡到第二天中午,醒来就发现总统已经易主。那么这究竟是怎么回事?这位总统又究竟是谁呢?阴差阳错就职的平民美国总统这美国弄死中兴以后对准了华为,不料华为却有准备?漂亮国的连番打击下,华为只能忍痛卖掉了荣耀。漂亮国的人开始了无情的嘲讽,不是中华有为,没我们的技术和芯片,华为哪来的中华有为。1987年拿着集资的两万块钱,任正非成立了华为,那时候
火了!陕西学霸天团全员保研双一流,还来自同校同学院12月,既是一年的结束,也预示着新岁的开始。对于无数逐梦研考的学子而言,这段时间是一段承上启下的分界,回头是漫长艰辛的备考,向前则是满怀希望的未来。但其实,不论是以何种方式踏上研途2022年下半年陕西省中小学教师资格面试考前温馨提示2022年下半年中小学教师资格面试将于2023年1月7日至8日举行,现就有关事项提示如下一hr及时下载打印准考证考生自2023年1月3日起可登录中小学教师资格考试报名系统(http陕西金叶龙虎榜数据(12月27日)陕西金叶今日涨停,全天换手率22。68,成交额12。57亿元,振幅14。46。龙虎榜数据显示,机构净卖出1648。79万元,营业部席位合计净买入3022。56万元。深交所公开信息显天猫精灵歌词音箱,让你真正爱上音乐忙碌的都市生活,让你多久没能静下心来好好欣赏一首音乐了?试想这样一个场景,周末睡懒觉后起床,在客厅捧着一杯咖啡,坐在懒人沙发上,用音箱播放一首喜欢的歌曲。这样的生活,想必会让每一个丰田全新电动越野SUV曝光既像雅力士又像酷路泽你敢相信,一款丰田的全新电动SUV,居然从Ta专属的轮胎上面能够看到Yaris和Crusier的两个标识?什么意思,难道是既像雅力士,又像酷路泽吗?早在2021年的丰田新能源战略发俗语人怕腊月死,更忌腊月生,为何这样说?腊月出生真不好吗在头条看见彼此腊月已经到了,俗话说正月忌头,腊月忌尾,因为腊月后就是春节了,为了图个喜庆自古以来在民间腊月份的忌讳也是比较多的。比较常见的就是腊月不定亲腊月不搬家,腊月不动土,还有我国台湾省拥有南海哪些机场?南海位于我国南方的南部,属于我国三大边缘海之一。南海面积为350万平方千米,是我国近海面积最大,水最深瑟海区。根据联合国海洋法规定沿岸国家可以拥有12海里领海和200海里经济专属区中国有4家p4级生物实验室,其余两家在台湾全球有多少p4生物实验室?事实上,全世界的p4实验室并不多,只有69个,其中52个正在运行,3个处于建设中,14个正在计划中。而这些p4实验室中,美国达13个,占了18。8,其中就台湾黄金八点档,一部剧几百集,卖到内地也轻松登上收视冠军床垫这个梗是过不去了。夺回床垫,再毁了它。但这次不是张兰汪小菲,而是比他们还狗血的台湾乡土剧。最近网友吃的瓜被一家团圆搬上了荧幕,山上的笋真是都要被夺完了。不是都说台剧消费升级了吗台湾游记(一)芳苑海边湿地红树林天空好蓝好蓝,阳光不燥,微风轻柔,天上云朵飘荡。带上好心情,胡先生开车带我们开始了今年来台湾的第一次芳苑海边湿地红树林海空步道之旅。海空步道坐落于彰化芳苑海边,是全台湾最宽达六公里小米发布年轻人的第一款智能鱼缸年轻人的第一次太多了,小米都给安排上了,这次又带来了年轻人的第一个智能鱼缸,产品的最大看点是,半年免换水。鱼缸的最大的容量为20L,采用金晶五线超白UHA级玻璃,169黄金宽屏,从