亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

Redis字符串對象實用筆記

2020-10-28 21:30:43
字體:
來源:轉載
供稿:網友

字符串對象

字符串數據類型是Redis里最常用的類型了,它的鍵和值都是字符串,使用起來非常的方便。雖然字符串數據類型的值都統稱為字符串了,但是在實際存儲時會根據值的不同自動選擇合適的編碼。字符串對象的編碼一共有三種:int、raw、embstr。

Redis對象

Redis用統一的數據結構來表示一個對象,具體定義如下:

typedef struct redisObject { unsigned type:4; unsigned encoding:4; // 當內存超限時采用LRU算法清除內存中的對象 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;

其中type字段代表對象的類型,取值一共有7種:

/* A redis object, that is a type able to hold a string / list / set *//* The actual Redis Object */#define OBJ_STRING 0 /* 字符串對象. */#define OBJ_LIST 1  /* 列表對象. */#define OBJ_SET 2  /* 集合對象. */#define OBJ_ZSET 3  /* 有序集合對象. */#define OBJ_HASH 4  /* 哈希對象. *//* The "module" object type is a special one that signals that the object * is one directly managed by a Redis module. In this case the value points * to a moduleValue struct, which contains the object value (which is only * handled by the module itself) and the RedisModuleType struct which lists * function pointers in order to serialize, deserialize, AOF-rewrite and * free the object. * * Inside the RDB file, module types are encoded as OBJ_MODULE followed * by a 64 bit module type ID, which has a 54 bits module-specific signature * in order to dispatch the loading to the right module, plus a 10 bits * encoding version. */#define OBJ_MODULE 5 /* 模塊對象. */#define OBJ_STREAM 6 /* 流對象. */

然后是encoding字段,代表著對象值的實際編碼類型,取值一共有11種:

/* Objects encoding. Some kind of objects like Strings and Hashes can be * internally represented in multiple ways. The 'encoding' field of the object * is set to one of this fields for this object. */#define OBJ_ENCODING_RAW 0  /* 簡單動態字符串 */#define OBJ_ENCODING_INT 1  /* long類型的整數 */#define OBJ_ENCODING_HT 2  /* 字典 */#define OBJ_ENCODING_ZIPMAP 3 /* 壓縮字典 */#define OBJ_ENCODING_LINKEDLIST 4 /* 不再使用的舊列表,使用雙端鏈表. */#define OBJ_ENCODING_ZIPLIST 5 /* 壓縮列表 */#define OBJ_ENCODING_INTSET 6 /* 整數集合 */#define OBJ_ENCODING_SKIPLIST 7 /* 跳躍表和字典 */#define OBJ_ENCODING_EMBSTR 8 /* embstr編碼的簡單動態字符串 */#define OBJ_ENCODING_QUICKLIST 9 /* 編碼為ziplist的列表 */#define OBJ_ENCODING_STREAM 10 /* 編碼為listpacks的基數樹 */

前面已經提到字符串對象只用到了long類型的整數、簡單動態字符串、embstr編碼的簡單動態字符串這三種編碼。

OBJ_ENCODING_INT

當字符串對象的值是一個整數且可以用long來表示時,字符串對象的編碼就會是OBJ_ENCODING_INT編碼。

可以看到,當值非常大的時候還是用OBJ_ENCODING_RAW來存儲的。

OBJ_ENCODING_RAW

當字符串對象的值是一個字符串且長度大于44字節時,字符串對象的編碼就會是OBJ_ENCODING_RAW編碼。具體結構在下文。

OBJ_ENCODING_EMBSTR

當字符串對象的值是一個字符串且長度小于等于44字節時,字符串對象的編碼就會是OBJ_ENCODING_EMBSTR編碼。OBJ_ENCODING_EMBSTR編碼和OBJ_ENCODING_RAW編碼的區別主要有以下幾點:

  • OBJ_ENCODING_RAW編碼的對象在分配內存時會分配兩次,分別創建redisObject對象和SDS對象。而OBJ_ENCODING_EMBSTR編碼則是一次就分配好。
  • 同樣的,OBJ_ENCODING_RAW編碼的對象釋放內存也需要兩次,OBJ_ENCODING_EMBSTR編碼則是一次。
  • OBJ_ENCODING_EMBSTR編碼的數據都存儲在連續的內存上,OBJ_ENCODING_RAW編碼則不是。
/* Create a string object with EMBSTR encoding if it is smaller than * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is * used. * * 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. */#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44robj *createStringObject(const char *ptr, size_t len) { if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT)  return createEmbeddedStringObject(ptr,len); else  return createRawStringObject(ptr,len);}

SDS

字符串是Redis里非常常見的類型,而用C實現的Redis和Java不一樣。在C里字符串是用長度為N+1的字符數組實現的,且使用空字符串'/0'作為結束符號。獲取字符串的長度需要遍歷一遍,找到空字符串'/0'才知道字符串的長度,復雜度是O(N)。

如果有一個長度非常大的字符串,單線程的Redis獲取它的長度就可能會阻塞很久,這是不能接受的,所以Redis需要一種更高效的字符串類型。

Redis實現了一個叫SDS(simple dynamic string)的字符串類型,其中有兩個變量來分別代表字符串的長度和字符數組未使用的字符數量,這樣就可以用O(1)的復雜度來獲取字符串的長度了,而且同樣也是使用空字符串'/0'作為結束符號。

struct sdshdr { // 字符串長度 int len; // 字符數組未使用的字符數量 int free; // 保存字符串的字符數組 char buf[];}

擴容機制

SDS在字符數組空間不足于容納新字符串的時候會自動擴容。

如果把一個C字符串拼接到一個SDS后面,當字符數組空間不足時,SDS會先擴容到剛好可以容納新字符串的長度,然后再擴充新字符串的空字符長度,最終SDS的字符數組長度等于 2 * 新字符串 + 1(結束符號'/0')。不過當新字符串的大小超過1MB后,擴充的空字符長度大小會固定為1MB。

之所以會有這個機制,是因為Redis作為一個NoSQL數據庫,會頻繁的修改字符串,擴容機制相當于給SDS做了一個緩沖池。把SDS連續增長N次字符串需要內存重分配N次優化成了SDS連續增長N次字符串最多需要內存重分配N次,這其實和Java里的StringBuilder實現思想是一樣的。

后記

我看過兩本關于Redis的書,里面都是講Redis如何實戰的,并沒有講Redis的設計和實現。這也就導致了面試很尷尬,因為面試官最喜歡問原理相關的東西了,所以以后學習技術的時候不要從實戰類的書籍開始了,還是先看懂原理比較好。

參考資料

這是《Redis設計與實現》里字符串一節的總結。


總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产91久久久| 亚洲色图综合久久| 欧美在线视频网| 欧美日韩一区二区免费视频| 成人精品一区二区三区电影黑人| 欧洲成人在线观看| 亚洲精品小视频在线观看| 在线观看国产成人av片| 亚洲电影免费观看高清完整版| 午夜精品福利电影| 国产精品永久免费观看| 亚洲欧洲xxxx| 亚洲影院在线看| 欧美激情精品久久久久久大尺度| 国产精品入口日韩视频大尺度| 亚洲a在线播放| 国产精品久久在线观看| 久久精品久久精品亚洲人| 亚洲精品日韩av| 国产欧美日韩综合精品| 午夜精品一区二区三区在线播放| 在线丨暗呦小u女国产精品| 国产精品美女www| 91精品国产色综合| 久久综合免费视频影院| 国产日韩欧美成人| 韩日精品中文字幕| 亚洲热线99精品视频| 韩国一区二区电影| 欧美最猛性xxxxx亚洲精品| 亚洲午夜精品久久久久久久久久久久| 日韩av免费在线| 亚洲欧美999| 一区二区三区美女xx视频| 亚洲二区中文字幕| 一本久久综合亚洲鲁鲁| xxxxx成人.com| 国产精品久久久久久一区二区| 亚洲第一精品夜夜躁人人躁| 午夜精品久久久久久久久久久久久| 成人av资源在线播放| 亚洲视频视频在线| 丝袜亚洲另类欧美重口| 久久精品一本久久99精品| 精品亚洲一区二区三区在线观看| 超薄丝袜一区二区| 亚洲性av网站| 国产99视频精品免视看7| 日韩中文字幕久久| 国产欧美精品日韩精品| 97超级碰在线看视频免费在线看| 成人免费看吃奶视频网站| 国产欧美日韩精品丝袜高跟鞋| 777777777亚洲妇女| 亚洲免费av电影| 日韩电影在线观看永久视频免费网站| 欧美日韩精品中文字幕| 日韩亚洲一区二区| 日本高清视频一区| 国产精品久久久久久久久久尿| 日韩电影在线观看永久视频免费网站| 精品视频—区二区三区免费| 日韩在线中文视频| 精品人伦一区二区三区蜜桃网站| 91网站免费观看| 2018国产精品视频| 国产在线播放不卡| 亚洲人成人99网站| 精品久久久久久中文字幕大豆网| 日韩久久午夜影院| 亚洲国产精品推荐| 国产精品久久久久久久7电影| 久久国产天堂福利天堂| 91亚洲精品久久久久久久久久久久| 国模叶桐国产精品一区| 38少妇精品导航| 欧美激情视频在线观看| 91黑丝高跟在线| 日本中文字幕成人| 欧美成人免费视频| 日韩av片电影专区| 日本国产高清不卡| 亚洲欧洲一区二区三区久久| 欧美大片免费看| 国产香蕉一区二区三区在线视频| 日韩电影免费观看中文字幕| 91在线精品视频| 69影院欧美专区视频| 国内精品模特av私拍在线观看| 久久精品国产亚洲一区二区| 国产免费一区二区三区香蕉精| 亚洲日本欧美中文幕| 全色精品综合影院| 在线观看欧美日韩| 欧美另类老肥妇| 中文字幕欧美在线| 日韩成人在线观看| 久久69精品久久久久久国产越南| 欧美精品在线网站| 欧美性生活大片免费观看网址| 欧美在线播放视频| 欧美亚洲国产视频小说| 中文字幕欧美在线| 2021国产精品视频| 成人精品一区二区三区电影免费| 国产中文字幕日韩| 欧美激情亚洲精品| 久久成人在线视频| 亚洲深夜福利视频| 欧美一区二区三区艳史| 欧美黄色片视频| 在线播放日韩精品| 欧美激情网站在线观看| 午夜精品福利视频| 亚洲人免费视频| 亚洲最大福利网站| 精品中文字幕在线| 成人xvideos免费视频| 成人久久一区二区三区| 亚洲欧美一区二区三区久久| 久久大大胆人体| 中文字幕久精品免费视频| 国产精品678| 色偷偷888欧美精品久久久| 久久中国妇女中文字幕| 欧美整片在线观看| 欧美成人免费在线观看| 国产欧美欧洲在线观看| 欧美交受高潮1| 欧美精品在线播放| 国产综合视频在线观看| 久久精品91久久久久久再现| 日韩在线观看免费全集电视剧网站| 日韩精品在线视频美女| 国产日韩在线观看av| 亚洲美女av电影| 亚洲va久久久噜噜噜久久天堂| 亚洲伊人久久综合| 久久视频免费观看| 久久夜色精品国产| 国产精品久久久久久av下载红粉| 国产在线日韩在线| 国产精品www| 日本精品久久久久久久| 久久久91精品国产一区不卡| 成人伊人精品色xxxx视频| 久久亚洲私人国产精品va| 激情成人中文字幕| 久久久久一本一区二区青青蜜月| 成人美女av在线直播| 亚洲jizzjizz日本少妇| 日本亚洲欧美三级| 欧美小视频在线观看| 亚洲伦理中文字幕| 欧美丰满少妇xxxx| 97超级碰在线看视频免费在线看| 91精品中国老女人| 久久久久久久久久久久久久久久久久av| 欧美在线一区二区视频| 欧美日韩国内自拍| 精品久久久香蕉免费精品视频| 在线观看欧美视频| 亚州国产精品久久久| 亚洲精品久久久久久久久久久久|