Redis底层设计原理 - Go语言中文社区

Redis底层设计原理


Redis是C语言实现的

Redis的Key和Value都是Sting,C语言中 char data[]="Allen"

Redis在C语言中自定义了一个数据结构来存储String,SDS数据结构

SDS = Simple dynamic string 简单动态字符串

特点:

1. 二进制安全的数据结构

2. 提供了内存预分配机制,避免了频繁的内存分配

3. 兼容C语言的函数库

String的扩容:

SDS {
    free:0
    len:6
    char buf[]="123456"
}

这时候调用append增加3个字符:123456 --> 123456123

addlen=3

预分配扩容后的长度为:18, 扩容的公式如下,

len = (len+addlen)*2

当string的大小大于1M之后就不会这样扩容了,会变成每次增加1M.

Redis的数据如何存储的,键值对的数据库

K-V
Key:String
Value:String,Hash,Set,Sorted Set,List

Redis中数据的存储, 在C语言中一redis存储的数据结构如下,字典数据结构:

数组: O(1) + 链表: O(N)

hash函数 -- 是计算机的一个功能,能把任意一个数据进行随机散列,哈希值转换为自然数

这里存储数据的模型就和hashmap的数据结构一样,redis采用的头插法来实现链表。

扩容 (ReHash)- 渐进式扩容,每次都有request来访问的时候,将附件的值搬到新的数组里面去,只有在rehash的时候才会到2个db里面去找。主进程,同步的方式进行扩容。

List 是一个有序的按加入时间培训的数据结构,Redis采用QuickList(双端链表)和ziplist作为list的底层实现。

可以设置ziplist的最大容量,quicklist的压缩范围,提升数据存取效率

list-max-ziplist-zize -2 //8kb

list-compress-depth 1 //从头节点往后走1个开始压缩

List的数结构

List低层采用 ziplist + qicklist 实现,采用一段连续的存储空间来存储数据,如下的Entry区域。

当Entry区域的数据太大时(如上设置为8K),需要把该Entry进行分裂,分裂成2个,用QuickList来存储数据,大概结构如下:

Hash的存储结构:

Hash数据结构的底层实现是一个字典(dict)。ziplist+hashtable

hash-max-ziplist-entries 512 //ziplist元素个数大于512,变为hashtable

hash-max-ziplist-value 64// 单个元素大于64byte时,变为hashtable

Set 数据结构:

set数据结构底层实现是一个Value为null的字典(dict),当数可以用整型表示时,Set结婚将被编码为intset数据结构当满足以下任意调节时用hashtable存储数据。

1. 元素个数大于set-max-intst-entries

2. 元素无法用整型表示

set-maxintset-entries 512 //instset 能存储的最大元素个数,超过则用hashtable编码

Zset数据结构:

字典(dict) +跳表(skiplist)

zset-max-ziplist-entries 128//当元素个数超过128,用跳表

zset-max-ziplist-value 64//当单个元素大小超过64byte,用跳表

 跳表原理:

GEO的使用

GeoHash纬度编码原理

基数位为精度,偶数位为偶数

把地球分为四个部分,

每个部分有可以分成四个部分

然后继续分下去,最后可以精确的 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/pengweismile/article/details/113192504
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-26 18:13:49
  • 阅读 ( 741 )
  • 分类:Redis

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢