加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

Redis为何这么快——数据存储角度

发布时间:2018-10-12 15:59:20 所属栏目:编程 来源:JAVA高级程序员
导读:【新产物上线啦】51CTO播客,随时随地,碎片化进修 本文内容思想导图如下: 一、简介和应用 Redis是一个由ANSI C说话编写,机能优越、支持收集、可耐久化的K-K内存数据库,并提供多种说话的API。它常用的范例首要是 String、List、Hash、Set、ZSet 这5种 Re
副问题[/!--empirenews.page--] 【新产物上线啦】51CTO播客,随时随地,碎片化进修

本文内容思想导图如下:

Redis为何这么快——数据存储角度

一、简介和应用

Redis是一个由ANSI C说话编写,机能优越、支持收集、可耐久化的K-K内存数据库,并提供多种说话的API。它常用的范例首要是 String、List、Hash、Set、ZSet 这5种

Redis为何这么快——数据存储角度

Redis在互联网公司一样平常有以下应用:

  •  String:缓存、限流、计数器、漫衍式锁、漫衍式Session
  •  Hash:存储用户信息、用户主页会见量、组合查询
  •  List:微博存眷人时刻轴列表、简朴行列
  •  Set:赞、踩、标签、挚友相关
  •  Zset:排行榜

再好比电商在大促销时,会用一些非凡的计划来担保体系不变,扣减库存可以思量如下计划:

Redis为何这么快——数据存储角度

上图中,直接在Redis中扣减库存,记录日记后通过Worker同步到数据库,在计划同步Worker时必要思量并发处理赏罚和一再处理赏罚的题目。

通过上面的应用场景可以看出Redis长短常高效和不变的,那Redis底层是怎样实现的呢?

二、Redis的工具redisObject

当我们执行set hello world呼吁时,会有以下数据模子:

Redis为何这么快——数据存储角度

  •  dictEntry:Redis给每个key-value键值对分派一个dictEntry,内里有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值沟通的键值对链接在一路,由此来办理哈希斗嘴题目(链地点法)。
  •  sds:键key“hello”是以SDS(简朴动态字符串)存储,后头具体先容。
  •  redisObject:值val“world”存储在redisObject中。现实上,redis常用5中范例都是以redisObject来存储的;而redisObject中的type字段指明白Value工具的范例,ptr字段则指向工具地址的地点。

redisObject工具很是重要,Redis工具的范例、内部编码、内存接纳、共享工具等成果,都必要redisObject支持。这样计划的甜头是,可以针对差异的行使场景,对5中常用范例配置多种差异的数据布局实现,从而优化工具在差异场景下的行使服从。

无论是dictEntry工具,照旧redisObject、SDS工具,都必要内存分派器(如jemalloc)分派内存举办存储。jemalloc作为Redis的默认内存分派器,在减小内存碎片方面做的相比拟力好。好比jemalloc在64位体系中,将内存空间分别为小、大、庞大三个范畴;每个范畴内又分别了很多小的内存块单元;当Redis存储数据时,会选择巨细最吻合的内存块举办存储。

前面说过,Redis每个工具由一个redisObject布局暗示,它的ptr指针指向底层实现的数据布局,而数据布局由encoding属性抉择。好比我们执行以下呼吁获得存储“hello”对应的编码:

Redis为何这么快——数据存储角度

redis全部的数据布局范譬喻下(重要,后头会用):

Redis为何这么快——数据存储角度

三、String

字符串工具的底层实现可所以int、raw、embstr(上面的表对应著名称先容)。embstr编码是通过挪用一次内存分派函数来分派一块持续的空间,而raw必要挪用两次。

Redis为何这么快——数据存储角度

int编码字符串工具和embstr编码字符串工具在必然前提下会转化为raw编码字符串工具。embstr:<=39字节的字符串。int:8个字节的长整型。raw:大于39个字节的字符串。

简朴动态字符串(SDS),这种布局更像C++的String可能Java的ArrayList<Character>,长度动态可变:

  1. struct sdshdr {  
  2.  // buf 中已占用空间的长度  
  3.  int len;  
  4.  // buf 中剩余可用空间的长度  
  5.  int free;  
  6.  // 数据空间  
  7.  char buf[]; // ’’空字符末了  
  8. }; 
  •  get:sdsrange---O(n)
  •  set:sdscpy—O(n)
  •  create:sdsnew---O(1)
  •  len:sdslen---O(1)

常数伟大度获取字符串长度:由于SDS在len属性中记录了长度,以是获取一个SDS长度时刻伟大度仅为O(1)。

预空间分派:假如对一个SDS举办修改,分为一下两种环境:

  •  SDS长度(len的值)小于1MB,那么措施将分派和len属性同样巨细的未行使空间,这时free和len属性值沟通。举个例子,SDS的len将酿成15字节,则措施也会分派15字节的未行使空间,SDS的buf数组的现实长度酿成15+15+1=31字节(特殊一个字节用户生涯空字符)。
  •  SDS长度(len的值)大于便是1MB,措施会分派1MB的未行使空间。好比举办修改之后,SDS的len酿成30MB,那么它的现实长度是30MB+1MB+1byte。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读