Redis学习笔记-String数据类型及其节省空间优化

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis学习笔记-String数据类型及其节省空间优化

要更好地优化 Redis 使用数据使用情况,就需要先了解 Redis 数据类型的存储方式,而前面文章学习过 String 类型底层数据结构是 简单动态字符串,当你使用 set 2201000060 4402000080 插入数据时,看上去只需要 8B long + 8B long = 16B 存储空间,但实际却需要 56B 的内存空间,为什么会使用这么多内存空间呢?这篇文章就围绕这个问题,学习一下 String 类型以及如何优化这种情况的数据,从而能节省更多的存储空间。

1.笔记图

2.Redis 基本数据类型和底层数据结构关系示意图

  • String 类型对应 简单动态字符串
  • List 类型对应 双向链表压缩列表
  • Hash 类型对应 压缩列表 散列表
  • Sorted Set 类型对应 压缩列表跳表
  • Set 类型对应 散列表 整数集合

3.String 类型保存方式

  • int 编码方式:当保存 64 位有符号整数,会把它保存为一个 8 字节的 Long 类型整数
  • 简单动态字符串(SDS)
  • embstr 编码:字符串小于 44 字节,RedisObject 中的元数据、指针和 SDS 是一块连续的内存区域,这样就可以避免内存碎片
  • raw 编码:字符串大于 44 字节,Redis 不把 SDSRedisObject 布局在一起,会给 SDS 分配独立的空间,用指针指向 SDS 结构

  • 每个 key 会对应全局哈希桶 dictEntry 的结构体,用来指向一个键值对
  • buf:字节数组,保存实际数据。为了表示字节数组的结束,Redis 会自动在数组最后加一个\0,这就会额外占用 1 个字节的开销
  • len:占 4 个字节,表示 buf 的已用长度
  • alloc:也占个 4 字节,表示 buf 的实际分配长度,一般大于 len

4.压缩列表(ziplist)

       压缩列表(ziplist) 实际是一个字节数组,它的设计目的是为了节约内存,和普通数组不同的是在数组头部会有三个字段,分别是 zlbytes(列表长度)、zltail(列表尾部偏移量)、zllen(entry 的个数),在 压缩列表 的尾部还会有 zlend(结束)字段,示意图如下图:

  • zlbytes:列表长度
  • zltail:列表尾的偏移量
  • zllen:列表中的 entry 个数
  • entry
  • prev_len:表示前一个 entry 的长度。prev_len 有两种取值情况:1 字节或 5 字节。取值 1 字节时,表示上一个 entry 的长度小于 254 字节。虽然 1 字节的值能表示的数值范围是 0255,但是压缩列表中 zlend 的取值默认是 255,因此,就默认用 255 表示整个压缩列表的结束,其他表示长度的地方就不能再用 255 这个值了。所以,当上一个 entry 长度小于 254 字节时,prev_len 取值为 1 字节,否则,就取值为 5 字节
  • len:表示自身长度,4 字节
  • encoding:表示编码方式,1 字节
  • content:保存实际数据
  • zlend:列表结束

5.使用 Hash 类型替代 String 优化

  • 插入 String 类型数据
info memory
  #used_memory:867616
  set 2201000060 4402000080
  #used_memory:867672
  #增加56B
  set 2201000061 4402000081
  #used_memory:867728
  #增加56B
  set 2201000062 4402000082
  #used_memory:867784
  #增加56B
  set 2201000063 4402000083
  #used_memory:867840
  #增加56B
  set 2201000064 4402000084
  #used_memory:867896
  #增加56B
  set 2201000065 4402000085
  #used_memory:867952
  #增加56B
  set 2201000066 4402000086
  #used_memory:868008
  #增加56B

Tips:可以看到每次新增的 INT 类型数据占用空间 56B

  • 插入Hash类型数据
info memory
  #used_memory:868008
  hset 2201000 060 4402000080
  #used_memory:868096
  #增加88B
  hset 2201000 061 4402000081
  #used_memory:868112
  #增加16B
  hset 2201000 062 4402000082
  #used_memory:868120
  #增加8B
  hset 2201000 063 4402000083
  #used_memory:868144
  #增加24B
  hset 2201000 064 4402000084
  #used_memory:868160
  #增加16B
  hset 2201000 065 4402000085
  #used_memory:868176
  #增加16B
  hset 2201000 066 4402000086
  #used_memory:868192
  #增加16B

Tips:可以看到这种方式只是在第一次增加数据的时候占用 88B,其后每次平均只增加 16B,其原因是 key 的空间是在第一次的时候创建的,后面可以共用,数据是以 ziplist 方式存储的,需要注意避免产生 bigkey

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
27 0
|
6天前
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
160 47
|
6天前
|
存储 NoSQL 关系型数据库
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
16 0
|
6天前
|
NoSQL Redis 数据库
Redis中的常用命令非常丰富,涵盖了各种数据类型的基本操作以及服务器管理和维护的相关指令
【5月更文挑战第15天】Redis常用命令包括通用(如PING、SELECT)、键操作(KEYS、EXISTS、DEL)、字符串(SET、GET)、哈希(HSET、HGET)、列表(LPUSH、LPOP)、集合(SADD、SMEMBERS)和有序集合(ZADD、ZRANGE)等。这些命令用于数据操作及服务器管理,满足不同场景需求。了解更多命令,建议参考Redis官方文档。
17 2
|
6天前
|
SQL NoSQL Java
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
Redis数据类型 Hash Set Zset Bitmap HyperLogLog GEO
18 0
|
6天前
|
NoSQL Java Unix
Redis基础操作 String List
Redis基础操作 String List
12 0
|
6天前
|
存储 缓存 监控
快速掌握Redis优化要点,告别性能瓶颈!
# Redis优化指南 了解如何提升Redis性能,从读写方式(整体与部分)、KV size、Key数量、读写峰值、命中率、过期策略、平均穿透加载时间、可运维性、安全性等方面着手。选择合适的读写策略,如只整体读写或部分读写变更,优化KV size避免过大或差异过大,合理管理Key数量,应对不同读写峰值,监控命中率并持续优化,设置智能过期策略,减少平均穿透加载时间,确保高可运维性并强化安全性。一起探索Redis的性能潜力!
379 4
|
6天前
|
存储 NoSQL 定位技术
Redis常用数据类型及常用命令
这些是Redis中常用的数据类型和命令。Redis还提供了许多其他命令和功能,用于数据存储、操作和查询。你可以根据需要选择适当的数据类型和命令来满足你的应用程序需求。
26 4
|
6天前
|
缓存 NoSQL Java
优化Redis缓存:解决性能瓶颈和容量限制
优化Redis缓存:解决性能瓶颈和容量限制
22 0
|
6天前
|
存储 NoSQL 安全
Redis入门到通关之Redis数据结构-String篇
Redis入门到通关之Redis数据结构-String篇
36 1