Redis中的String编码转换底层原理及6.0新特性

String编码转换底层原理

String对象为什么把大于39字节或者44字节的字符串编码为raw,小于的时候编码为embstr?

在Redis3.2以前的版本中,SDS作为字符串类型中存储字符串内容的结构,源码如下:

3.2版本SDS结构

struct sdshdr {// 记录buf数组中已使用字节的数量// 等于SDS保存字符串的长度 4byteint len;// 记录buf数组中未使用字节的数量 4byteint free;// 字节数组,用于保存字符串 字节\0结尾的字符串占用了1bytechar buf[];
}

Redis对象头

一个字符串对象不仅仅包含SDS结构,还包含了RedisObject(Redis对象头),这时每个Redis对象都要携带的一种结构跟Java对象类似,Java对象也有相应的对象头,它的结构如下

// Redis对象
typedef struct redisObject {// 类型 4bits; 即【String、List、Hash、Set、Zset】中的一个unsigned type:4// 编码方式 4 bits, encoding表示对象底层所使用的编码unsigned encoding:4;// LRU时间(相对于server.lrulock) 24bits;unsigned lru:24;// 引用计数 Redis里面的数据可以通过引用计数进行共享 32bitsint refcount;// 指向对象的值 64bitvoid* ptr;
} robj; // 16bytes

操作系统中的内存分配

由于操作系统使用jmalloc和tmalloc进行内存的分配,而内存分配的单位都是2的N次方,所以是2,4,8,16,32,64,如果Redis采取32字节分配的化,那么32-16(RedisObject)-9(3.2版本的SDS)=7,相当于可使用字节数为7字节,Redis认为太过于小了,所以Redis采取分配的是64字节,即64-25=39。

SDS结构优化

在Redis之后的版本中,为了进一步优化字符串对象在一次操作系统的内存分配中扩大可使用的空间,又将sdshdr分为了sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64结构如下

struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* used */uint8_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* used */uint64_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
// 一些变量的定义 
#define SDS_TYPE_5  0
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4

结构示例图

  • sdshdr5的结构如图
    在这里插入图片描述
  • sdshdr8的结构如图
    在这里插入图片描述

疑惑解答

有人可能会问既然分出来这么多的结构,如果用sdshdr5的结构,那么64-16-1-1=46个字节,跟平常说的44个字节不一样,如果我们用sdshdr5的结构,那么这个结构的flags中只有5个bit可以让我们使用,
表示的空间地址就是2^5=32个长度,表示的空间太小了,所以我们得用sdshdr8的结构那么可以表示的空间地址
将会是2^8=256,但实际上,在Redis内部中,键是使用sdshdr5的结构,因为键不大可能会更新,而值会经常更新,所以干脆直接sdshdr8来表示值对象

Redis6.0新特性

多线程

概述

redis6.0提供了多线程的支持,redis6以前的版本,严格来说也是多线程,只不过执行用户命令的请求是单线程模型,还有一些线程用来执行后台任务,比如unlink删除大key,rdb持久化等

redis6.0提供了多线程的读写IO,但是最终执行用户命令的线程依然是单线程的,这样,就没有多线程数据的竞争关系,依然很高效

线程模型

在这里插入图片描述

  • redis6.0以前线程执行模式,如下操作再一个线程中执行完成

在这里插入图片描述

  • redis6.0线程执行模式:
参数配置

可以通过如下参数配置多线程模型:

io-threads 4 // 这里说 有三个IO线程,还有一个线程是main线程,main线程负责IO读写和命令执行操作

默认情况下,如上配置,有三个IO线程,这三个IO线程只会执行IO中的write操作,也就是说,read和命令执行都由main线程执行,最后多线程讲数据写回客户端。

在这里插入图片描述
开启了如下参数:

io-threadas-do-reads yes // 将支持IO线程执行 读写任务

Client side caching(客户端缓存)

概述

redis6提供了服务端追踪key的变化,客户端缓存数据的特性,这需要客户端实现
在这里插入图片描述

执行流程

当客户端访问某个key时,服务端将记录key和client,客户端拿到数据后,进行客户端缓存,这时,当key再次被访问时,key将被直接返回,避免了与redis服务器的再次交互,节省服务端资源,当数据被其他请求修改时,服务端将主动通知客户端失效的key,客户端进行本地失效,下次请求时,重新获取最新数据目前只有lettuce对其进行了支持:

代码示例
  • 依赖导入
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce‐core</artifactId>
<version>6.0.0.RELEASE</version>
</dependency>
  • Java代码
public class Main {public static void main(String[] args) {RedisClient redisClient = RedisClient.create("redis://127.0.0.1");Map<String, String> clientCache = new ConcurrentHashMap<>();StatefulRedisConnection<String, String> myself = redisClient.connect();CacheFrontend<String, String> frontend = ClientSideCaching.enable(CacheAccessor.forMap(clientCache), myself,TrackingArgs.Builder.enabled().noloop));String key = "csk";int count = 0;while (true) {System.out.println(frontend.get(key));TimeUnit.SECONDS.sleep(3);if (count++ == Integer.MAX_VALUE) {myself.close();redisClient.shutdown();}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/754977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华岳M9制造企业管理软件业务流程 2/4

华岳M9制造企业管理软件业务流程 2/4 步骤3 初始一、应收账款初始余额二、应付账款初始余额三、出纳账项初始余额四、会计账项初始余额五、盘点入库六、存货细目七、存货属性设置八、存货存量控制九、存货价格管理十、月末处理 步骤4 技术一、存货目录二、存货细目三、仓库绑定…

nginx代理服务器配置

nginx代理服务器配置 需要配置环境需求 1、一台1.1.1.1服务器&#xff0c;一台2.2.2.2服务器 前端包路径在1.1.1.1 /etc/dist 下 后端服务在2.2.2.2 上 暴露端口为9999 2、需求 现在需要访问 1.1.1.1:80访问到2.2.2.2 上面的9999后端服务 3、配置nginx ①&#xff1a;在…

【深度学习实践】面部表情识别,深度学习分类模型,mmpretrain用于分类的实用教程,多任务网络头

文章目录 数据集数据集的进一步处理转换training.csv转换validation.csv 剔除无法使用的图片数据选择mmpretrain框架来训练配置四个文件改写base model改写base datasetsschedulesdefault_runtime 总配置开始训练训练分析考虑在网络上增加facial_landmarks回归head考虑是否可以…

B树B+树,字典树详解,哈夫曼树博弈树

目录 B树&#xff1a;B-Tree B树 字典树&#xff1a;Trie Tree 哈夫曼树 博弈树 B树&#xff1a;B-Tree 多路平衡搜索树 1.M阶B树&#xff0c;就是M叉&#xff08;M个指针&#xff09;。 2.每个节点内记录个数<M-1。 3.根节点记录个数>1。 4.其余节点内记录个数&…

人工智能技术的不当利用与风险

目录 前言1 视频篡改技术的滥用1.1 虚假信息传播与社会动荡1.2 对公众信任的破坏与舆论混乱 2 隐私泄露与监视风险2.1 个人信息安全与数据滥用风险2.2 社会稳定与个人自由权利的平衡 3 虚假评论与信息传播3.1 舆论操纵与社会意识形态的影响3.2 对信息可信度与公众信任的威胁 结…

Mysql迁移至达梦所遇问题汇总

问题与解决&#xff1a; 1: 建表语句中不允许出现类似如下语句&#xff1a; create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPKEY member_id (member_id) USING BTREE 2: SQL 错误 [22000]: 仅当指定列列表&#xff0c;且SET IDENTIT…

红与黑(bfs, acwing)

题目描述&#xff1a; 有一间长方形的房子&#xff0c;地上铺了红色、黑色两种颜色的正方形瓷砖。 你站在其中一块黑色的瓷砖上&#xff0c;只能向相邻&#xff08;上下左右四个方向&#xff09;的黑色瓷砖移动。 请写一个程序&#xff0c;计算你总共能够到达多少块黑色的瓷…

03 龙芯平台openstack部署搭建-keystone部署

#!/bin/bash #创建keystone数据库并授权&#xff0c;可通过mysql -ukeystone -ploongson验证授权登录 mysql -uroot -e “set password for rootlocalhost password(‘loongson’);” mysql -uroot -ploongson -e ‘CREATE DATABASE keystone;’ #本地登录 mysql -uroot -ploo…

【Linux】进程---概念---进程---优先级

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;Linux_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.操作系统(Operator System) 1.1 概念 1.2 设计OS的目的 1.3 定位 1.4 如何理解 "管理" 1.5 总结 1.6 系统调用和…

蓝桥杯刷题总结(Python组)

1、蛇形矩阵 解题思路&#xff1a;每次赋值后都对方向进行改变&#xff0c;一般上下左右就是&#xff08;-1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&#xff0c;1&#xff09;&#xff0c;&#xff08;1&#xff0c;0&#xff09;&#xff0c;&#xff08;0&…

智慧城市物联网建设:提升城市管理效率与居民生活品质

目录 一、智慧城市物联网建设的意义 1、提升城市管理效率 2、改善居民生活品质 3、促进城市可持续发展 二、智慧城市物联网建设面临的挑战 1、技术标准与互操作性问题 2、数据安全与隐私保护问题 3、投资与回报平衡问题 三、智慧城市物联网建设的实施策略 1、制定统一…

Linux下安装多个nodejs并映射Jenkins

背景 需要Jenkins中切换多个Node&#xff0c;比如nodejs16和nodesjs18,所以在宿主机按照好这两个版本&#xff0c;然后再映射到Jenkins容器中 步骤 1.下载地址 https://nodejs.org/dist/ 放到 cd /opt/soft/2.解压 tar -xzvf node-v16.20.0-linux-x64.tar.gz tar -xzvf n…

STM32F4+薄膜压力传感器(FSR)AO模拟输出程序ADC模数转换器详解

前言&#xff1a;博主在使用STM32F4加薄膜压力传感器用来测量压力时&#xff0c;发现给的例程只有STM32F1系列的&#xff0c;而STM32F4系列库函数程序不太一致&#xff0c;博主实战解决了该问题&#xff0c;用STM32F4标准库开发。有关ADC模数转换器的详细知识点详情点击我的博文…

ChatGPT是什么,怎么使用,需要注意些什么?

一、ChatGPT 是什么&#xff1f; ChatGPT&#xff0c;全称聊天生成预训练转换器&#xff08;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;是 OpenAI 开发的人工智能(AI)聊天机器人程序&#xff0c;于2022年11月推出。该程序使用基于GPT-3.5、GPT-4架构的…

关于物联网的技术与概念

什么是嵌入式系统&#xff1f; 嵌入式系统是以应用为中心&#xff0c;以计算机技术为基础&#xff0c;能够根据用户需求&#xff08;功能、可靠性、成本、体积、功耗、环境等&#xff09;灵活裁剪软硬件模块的专用计算机系统。它们通常用于特定的任务&#xff0c;具有高度的集…

基于java+springboot+vue实现的旅游信息管理系统(文末源码+Lw+ppt)23-464

摘 要 本系统为用户而设计制作旅游信息管理系统&#xff0c;旨在实现旅游信息智能化、现代化管理。本旅游信息管理自动化系统的开发和研制的最终目的是将旅游信息的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的便利和条件…

【C语言】空心正方形图案

思路&#xff1a; 1&#xff0c;两行两列打印* &#xff1a;第一行和最后一行&#xff0c;第一列和最后一列。 2&#xff0c;其他地方打印空格。 代码如下&#xff1a; #include<stdio.h> int main() { int n 0; int i 0; int j 0; while (scanf("…

centos创建并运行一个redis容器 并支持数据持久化

步骤 : 创建redis容器命令 docker run --name mr -p 6379:6379 -d redis redis-server --appendonly yes 进入容器 : docker exec -it mr bash 链接redis : redis-cli 查看数据 : keys * 存入一个数据 : set num 666 获取数据 : get num 退出客户端 : exit 再退…

GaussDB分区表自动新增分区

前言 GaussDB是华为自主研发的企业级分布式关系型数据库&#xff0c;支持集中式和分布式两种部署方式。为企业提供了高可用&#xff0c;高可靠&#xff0c;高安全等能力&#xff0c;其产品全栈自研&#xff0c;并且具有完善生态工具和开源社区。在实际去O的项目过程&#xff0…

oracle pctfreepctused介绍

pctfree这个参数定义了一个块保留空间的百分比&#xff0c;保留空间是为了将来可能发生的更新操作&#xff0c;因为更新可能增大被更新行占用的空间&#xff0c;如果此时该块没有可利用空间&#xff0c;那么只有发生row migrate了&#xff0c;从而会降低I/O性能。换句话说&…