#### String类型127.0.0.1:6379> set name zhangsanOK127.0.0.1:6379> type namestring#### List类型127.0.0.1:6379> lpush keylist 1 zhangsan(integer) 2127.0.0.1:6379> type keylistlist#### Hash类型127.0.0.1:6379> hmset keyhash name zhangsanOK127.0.0.1:6379> type keyhashhash#### Set类型127.0.0.1:6379> sadd keyset name zhangsan(integer) 2127.0.0.1:6379> type keysetset#### Sort Set类型127.0.0.1:6379> zadd keyzset 1 zhangsan(integer) 1127.0.0.1:6379> type keyzsetzset#### Bitmaps 类型127.0.0.1:6379> setbit keybitmap 10 1(integer) 0127.0.0.1:6379> type keybitmapstring#### Hyperloglogs类型 127.0.0.1:6379> pfadd keyhyperloglogs 2 23 42 2(integer) 1127.0.0.1:6379> type keyhyperloglogsstring#### Geospatial类型127.0.0.1:6379> geoadd keygeo 13.361389 38.115556 test(integer) 1127.0.0.1:6379> type keygeozset#### Stream类型127.0.0.1:6379> xadd keystream * name zhangsan"1650552771376-0"127.0.0.1:6379> type keystreamstream
元数据encodingencoding表示当前value值的编码格式有三种int、embstr、raw,可以通过命令object encoding key获取
#### 如果值是数字编码类型就是int127.0.0.1:6379> set name 1OK127.0.0.1:6379> object encoding name"int"#### 如果值是字符串同时长度小于等于44那么就是embstr127.0.0.1:6379> set name1 "zhangsan"OK127.0.0.1:6379> object encoding name1"embstr"#### 如果值是字符串同时长度大于44127.0.0.1:6379> set name2 "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"OK127.0.0.1:6379> object encoding name2"raw"
元数据refcountrefcount为被引用对象,当refcount=0表示可回收对象,可以通过命令refcount key查看引用次数 。
RedisObject指针ptr如果值的类型为int,那么ptr直接存储的就是这个int类型的值,不会去指向其它内存地址,如下所示 。
文章插图
当值为字符串类型,同时字符串的长度小于等于44时,数据采用embstr编码格式编码,将RedisObject对象的元数据、指针、SDS分配到一片连续的内存空间,避免内存碎片 。
为什么字符串长度需要小于等于44呢?
Redis中的内存分配器jemalloc认为超出64字节就是一个大字符串所以就以64为界,而元数据占8字节、指针占8字节,SDS分两种情况
1、如果是6.x版本SDS其它内存消耗4个字节(1B(len)+1B(alloc)+1B(flag)+1B(''))所以是64-8-8-4=44 。
2、如果是3.x版本SDS其它内存消耗9个字节(4B(len)+4B(free)+1B(''))所以是64-8-8-9=39 。
版本不同编码格式判断的临界值会有稍微不同 。
文章插图
当值是字符串但是长度大于44时,编码格式变为raw,SDS和RedisObject的内存分配不再连续,SDS内存空间将独立分配,如下所示 。
文章插图
dictEntry结构那么除了SDS动态字符串和RedisObject结构,一个简单的String操作还会涉及到哪些内存分配呢?当然是有的那就是哈希桶中的元素dictEntry,dictEntry中包含key、value、next等值如下所示 。
文章插图
总结String使用虽然简单但不是万金油哪里都能使用,在数据量大的时候我们需要选择合适的数据结构来避免这种情况的发生,如list、set、sort set、hash等这些数据结构就能节省dictEntry所需要的内存,下面以6.x版本演示如下所示( info memory可以查看内存使用情况) 。
#########################hash集合类型#############################127.0.0.1:6379> info memory# Memoryused_memory:866600127.0.0.1:6379> hset obj name zhangsan(integer) 1127.0.0.1:6379> info memory# Memory 第一次创建hash结构需要 消耗80字节used_memory:866680127.0.0.1:6379> hset obj addr beijin(integer) 1127.0.0.1:6379> info memory# Memory 后续在hash结构中加入属性 只消耗16字节used_memory:866696#########################String类型###############################127.0.0.1:6379> info memory# Memoryused_memory:866720127.0.0.1:6379> set teststr zhangsanOK127.0.0.1:6379> info memory# Memory 消耗72字节used_memory:866792127.0.0.1:6379> set teststr1 zhangsanOK127.0.0.1:6379> info memory# Memory 消耗72字节used_memory:866864
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3分钟体验Deepin,热门国产桌面系统之一,win用户可无缝使用
- python算法基础之贪心算法
- 足球|全球最贵球衣诞生! 马拉多纳上帝之手球衣5900万元成交
- |敢去这里钓鱼,回家直接搓衣板!涉赌之后涉*了?
- 网络编程之网络丢包故障如何定位?如何解决?
- 红茶之回味,功夫红茶能泡多久
- Redmi|挑战中端性能之王!Redmi Note 11T官宣:5月见
- Redmi|天玑9000性价之王!Redmi K50 Pro首次降价:2949元起
- 中兴|呕心沥血之作!中兴Axon 40 Ultra来了:史上最完美全面屏
- 三大功夫红茶之首,演示泡红茶