這篇文章帶大家了解一下Redis資料類型中的String,聊聊String資料類型的儲存原理,希望對大家有幫助!
Redis是工作中使用比較多的中間件,它支援豐富的資料結構,擁有極強的讀寫效能,tps可以達到10w 。
今天這篇文章來分析和總結String類型也是使用最多的一種資料結構之一。本文以redis5.0進行分析。 【相關推薦:Redis影片教學】
set key value [EX seconds] [PX milliseconds] [NX|XX]
1、set是語法,key是指定名稱, value是需要儲存的值
2、EX 指定過期的秒時間,PX指定過期的毫秒時間
3、NX:只有key不存在的時候,才設定成功
#4、XX:只有key存在的時候,才設定成功
總結:5.0支援set指令指定過期時間與不存在的時候才設定成功,也就是透過一條指令就可以實現分散式鎖定加鎖的功能,以前的版本設定key和設定過期時間需要分成兩個指令,原子性保證難度更高。
1、熱點資料快取,分散式session
2、Setnx 分散式鎖定
3、incr 計數器
4、Incr 全域id
#5、Incr 限流
6、bit 運算,點陣圖功能,線上用戶統計0/1標記
整數型,字元型,float(單浮點型)
##四、不同的編碼類型
五、String儲存原理
在Redis中,資料儲存在一個RedisObject類別中typedef struct redisObject { //这个类型可以是string,也可以是hash,zset等等 unsigned type:4; unsigned encoding:4; //记录lru,lfu淘汰算法依赖的访问时间和访问频率 unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 bits access time). */ //引用计数器 int refcount; //指向真实数据结构对象 void *ptr; } robj;
對於String,Redis自訂了一個簡單動態字串的資料結構來儲存字串數。
原始碼實作:多種資料結構,分別表示可以儲存不同長度的字串。
len:代表已經使用的長度
flags:代表儲存類型
分配一次記憶體
,銷毀時釋放一次記憶體
,尋找方便2、raw則RedisObject,SDS記憶體不在一塊,需要建立時3、embstr的結構,決定了當他需要增加長度時,RedisObject,SDS都需要重新分配記憶體。因此
embstr編碼的資料是不能修改的,只讀的
#1、int型別的資料不再是int型別,轉成raw
3、embstr字元超過44字節,轉成raw 八、SDS資料結構的優點
二進位安全的 可以儲存圖片整形,浮點型
儲存8個位元組長整形long ,2^63-1Embstr
embstr格式的SDS simple Dynamic String 記憶體空間是連續的,唯讀的,只要執行修改就會轉成raw
Raw
不用擔心記憶體溢出,sds具備自動擴容能力
取得字串長度時間複雜度O(1),儲存了len屬性
空間預先分配和
惰性空間釋放
6、判斷是否結束使用len屬性,可以包含'\0' ,操作字串。
通过源码分析,扩容策略是字符串在长度小于 SDS_MAX_PREALLOC 之前,扩容空间采用加倍策略,也就是保留 100% 的冗余空间。当长度超过 SDS_MAX_PREALLOC 之后,为了避免加倍后的冗余空间过大而导致浪费,每次扩容只会多分配 SDS_MAX_PREALLOC大小的冗余空间。
惰性空间释放用于优化 SDS 的字符串缩短操作:当 SDS 的 API 需要缩短 SDS 保存的字符串时, 程序并不立即使用内存重分配来回收缩短后多出来的字节, 而是使用 free 属性将这些字节的数量记录起来,并等待将来使用。
//仅仅设置长度,没有真正清除数据 void sdsclear(sds s) { //单纯设置长度为0 sdssetlen(s, 0); //第一个字符设置为结束符 s[0] = '\0'; }
真正的清除空间
sds sdsRemoveFreeSpace(sds s) { struct sdshdr *sh; sh = (void*) (s-(sizeof(struct sdshdr))); // 进行内存重分配,让 buf 的长度仅仅足够保存字符串内容 sh = zrealloc(sh, sizeof(struct sdshdr)+sh->len+1); // 空余空间为 0 sh->free = 0; return sh->buf; }
以上便是关于string的知识点记录,string的设计很多地方都非常巧妙,比如不同的结构体存储不同长度的字符串,不同编码类型存储不同长度的字符串,
空间预分配,空间惰性释放等,从存储结构,编码类型,内存分配策略和回收策略,作者都从性能方面做了非常多的考量设计,可想而知这也是redis为什么性能极高的原因,工作中也要学习这种追求极致性能的优良风格和设计风格。
更多编程相关知识,请访问:编程入门!!
以上是Redis資料類型學習之聊聊String原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!