matlab 字符串如何存储为ascii_Redis字符串(string)是如何存储的?

以下涉及到的源码均来自 https://github.com/redis/redis (branch 6.2)

背景知识

在6.2这个版本redis支持的数据结构如下

0b41633e9c8ce01e29d48e2fdcb3ac58.png

可能大家比较熟悉和用得比较多的是前5种数据结构(后面两种是后来加入的)

redis数据结构编码类型

90a521652d2830aa7d3f87dfa14cf9c5.png

其中字符串涉及到的编码类型有

OBJ_ENCODING_RAW(原生)

OBJ_ENCODING_INT(整型)

OBJ_ENCODING_EMBSTR(紧凑型, 前提条件字符串长度小于等于44,后面再分析这个数字是如何来的)

这些数据结构在redis内部表示

0b6e8158850e9e59c4d4474fac745dc9.png

从redisObject可以算出该结构体占用内存大小

4bit + 4bit + 24bit + 4Byte + 4Byte = 12Byte

即是 sizeof(struct redisObject) = 12 (后面有用到)

Redis字符串(string)内部数据结构Sds

89425f212d94d822ddb98f37f7287a44.png

从上面看起来sds和普通字符串没啥区别, 其实redis为了节省内存做了更细的划分

2dcd411264409dbd3c3e4a6d0f704f31.png
8575c2c3959be7ed47d50d0f050fd904.png

除了sdshdr5的结构不太一样,其它结构都一样(适用于不同长度的字符串)

len -> 已使用的长度

alloc -> 分配的长度(除去了sds头和空'0'结束符 - 可以更方便的计算可用长度 avail = alloc - len)

flags -> 低三位表示sds类型, 高五位目前还未使用到

buf[] -> 实际字符串数据

sds header里存有len长度的一个解释:

You can print the string with printf() as there is an implicit 0 at the end of the string. However the string is binary safe and can contain 0 characters in the middle, as the length is stored in the sds header.

来看看sds的创建过程就能大概明白了

sds创建

5cd6f1c541aa1db0f5cb81082cd8d3ef.png
1975591ad3d9f36bfbb6afce13ff8d0d.png

1. 如何确定新建的sds类型

dc37be265cebb3071fb47d8fb327ad13.png

2. 计算sds header大小

6a7d8bc97919725d100933eabbe96583.png

3. 分配内存

58e4ac90b22786129116c7ae257ed897.png

4. 内存初始化

6c83f4e0a943cc02883e1d937efafe95.png

5. sds结构设置

d09bdc777ef7c1eb5390999a4af1a3e3.png
f021b878ea23bc092a6385b4d8c62cbc.png

从上面sds创建过程可以大概地了解到sds在内存的存储形式

连续的内存, 可依次分为sds header + sds buf(字符串数据) + '0'(终止符)

redis的字符串结构体redisObject的ptr指向就是sds结构

接着来看看struct redisObject(也就是robj)在内存的存储形式,了解完后就能对一个字符串是如何在redis中存储的就会比较清晰了

redisObject(robj)内存存储形式

再来回顾下这个结构

59c2a519eb6d16e032cb60ec92331080.png

简单看看robj的创建过程

2e2efff6d27f45ad36ed68c5cef239a5.png

Redis是如何确定字符串的编码类型(robj->encoding)的?

首先从string的set command入手看看

809e10897b513a1dbcb3d0d7bdc4481d.png

OBJ_ENCODING_INT编码类型

79feac8336b387ceb99b1638050d3ffc.png

OBJ_ENCODING_EMBSTR

d7a10ede0c638f2d04c68ed7240586a9.png

字符串对象(StringObject)创建过程

1c53e75349649359d6606a1e2b9f302a.png

1. OBJ_ENCODING_EMBSTR_SIZE_LIMIT是如何计算出来的

看看redis的注释

The current limit of 44 is chosen so that the biggest string object

we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc.

redis使用的内存分配库的申请内存快单位是64byte, 由于embstr的整个redisObject是设计成一块连续内存的(提升读写效率), 因此embstr的整个redisObject大小就被限制在64byte, 那再来计算实际字符串的可用内存大小。

开篇就计算了整个struct redisObject大小是12byte

64 - 12 - 7(sizeof(sdshdr8)) - 1(0) = 44byte

2. Embedded String创建

bb0a4245525309867c1a1183ca231e8f.png

3. Raw String创建

db27c8bcd99d90959dcfd6c92cc921d2.png

Redis-Cli查看robj type encoding

set abc "1"

type abc -> string

object encoding -> int

set abc "1a"

type abc -> string

object encoding -> embstr

博客相关Github地址

https://github.com/rodbate/blog-code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值