新聞中心
從源碼深入理解Redis

創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供湯原網(wǎng)站建設(shè)、湯原做網(wǎng)站、湯原網(wǎng)站設(shè)計、湯原網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、湯原企業(yè)網(wǎng)站模板建站服務(wù),十多年湯原做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
Redis是一個開源的內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng),常用于緩存、消息隊列、持久化存儲等場景。它具有高性能、可擴展、支持豐富的數(shù)據(jù)類型等特點,被廣泛應(yīng)用于互聯(lián)網(wǎng)領(lǐng)域。為了更好地理解Redis,我們需要從源碼層面去探究Redis的實現(xiàn)。
Redis源碼的目錄結(jié)構(gòu)
Redis的源碼目錄結(jié)構(gòu)如下:

src目錄下是Redis的核心代碼,包含了Redis的命令實現(xiàn)、數(shù)據(jù)類型實現(xiàn)以及網(wǎng)絡(luò)事件處理等核心代碼。deps目錄下是Redis所依賴的第三方庫,如hiredis、Jemalloc等。tests目錄下是Redis的測試代碼,包含了Redis各個功能點的自動化測試用例。
Redis源碼中的數(shù)據(jù)結(jié)構(gòu)
Redis的內(nèi)部實現(xiàn)主要依賴于數(shù)據(jù)結(jié)構(gòu),下面我們將介紹Redis源碼中常見的四種數(shù)據(jù)結(jié)構(gòu):字符串、列表、哈希、集合。
1. 字符串
Redis中的字符串類型保存的是二進制安全的字符串。在Redis的源碼中,字符串類型的操作可以在src/string.c文件中找到,其中最常用的操作為set、get。
set操作的主要實現(xiàn)如下:
“`c
void setCommand(client *c) {
setGenericCommand(c,SET_NO_FLAGS);
}
void setGenericCommand(client *c, int flags) {
robj *expire = getExpire(c->db,c->argv,flags);
int j;
c->argv[c->argc] = expire ? expire : &shared.nullbulk;
c->argc++;
/* Store the value */
setKey(c->db,c->argv[1],c->argv[2]);
/* Signal modified key */
signalModifiedKey(c,c->db,c->argv[1]);
/* Notify a generic string-key BL pop event */
notifyKeyspaceEvent(NOTIFY_STRING,”set”,c->argv[1],c->db->id);
if (expire) setExpire(c,c->db,c->argv[1],expire);
server.dirty++;
}
get操作的主要實現(xiàn)如下:
```c
void getCommand(client *c) {
getGenericCommand(c);
}
void getGenericCommand(client *c) {
robj *o;
/* Try to get the value from the cache */
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
o == shared.sentinel)
return;
addReplyBulk(c,o);
}
2. 列表
Redis中的列表類型使用雙向鏈表實現(xiàn),支持在列表頭部和列表尾部插入和刪除元素。在Redis的源碼中,列表類型的操作可以在src/adlist.c文件中找到,其中最常用的操作為listAddNodeHead、listAddNodeTl、listDelNode。
listAddNodeHead操作的主要實現(xiàn)如下:
“`c
list *listAddNodeHead(list *list, void *value) {
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tl = node;
node->prev = node->next = NULL;
} else {
node->prev = NULL;
node->next = list->head;
list->head->prev = node;
list->head = node;
}
list->len++;
return list;
}
listDelNode操作的主要實現(xiàn)如下:
```c
list *listDelNode(list *list, listNode *node) {
/* Fix head pointer if needed. */
if (node->prev == NULL)
list->head = node->next;
else
node->prev->next = node->next;
/* Fix tl pointer if needed. */
if (node->next == NULL)
list->tl = node->prev;
else
node->next->prev = node->prev;
if (list->free) list->free(node->value);
zfree(node);
list->len--;
return list;
}
3. 哈希
Redis中的哈希類型使用字典結(jié)構(gòu)實現(xiàn),支持在哈希表中添加、刪除、查找元素。在Redis的源碼中,哈希類型的操作可以在src/dict.c文件中找到,其中最常用的操作為dictAdd、dictFind、dictDelete。
dictAdd操作的主要實現(xiàn)如下:
“`c
int dictAdd(dict *d, void *key, void *val)
{
dictht *ht;
dictEntry *entry;
if (dictIsRehashing(d)) _dictRehashStep(d);
/* Get the index of the new element, or -1 if
* the element already exists. */
if ((entry = dictFind(d,key)) == NULL) {
if (dictIsRehashing(d) && dictAdd(d->ht[1],key,val) == DICT_OK)
incrRefCount(key); /* Prevent ht[0] from freeing the key. */
else {
entry = dictCreateEntry(d,key);
dictSetEntryVal(entry,val);
dictHashTableInsert(d,entry);
}
return 1;
} else {
dictSetEntryVal(entry,val);
return 0;
}
}
dictDelete操作的主要實現(xiàn)如下:
```c
int dictDelete(dict *ht, const void *key) {
unsigned int h, idx;
dictEntry *he, *prevHe;
if (ht->size == 0) return DICT_ERR;
if (dictIsRehashing(ht)) _dictRehashStep(ht);
h = dictHashKey(ht,key);
/* Search in both tables if we are rehashing. */
for (idx = 0; idx
he = ht->table[idx] + (h & ht->sizemask);
prevHe = NULL;
while(he) {
if (key==he->key || dictCompareKeys(ht,key,he->key)) {
/* Unlink the element from the list */
if (prevHe)
prevHe->next = he->next;
else
ht->table[idx] = he->next;
if (ht->keyDestructor) {
ht->keyDestructor(he->key);
}
if (ht->valDestructor) {
ht->valDestructor(he->v.val);
}
zfree(he);
ht->used--;
return DICT_OK;
}
prevHe = he;
he = he->next;
}
if (!dictIsRehashing(ht)) break;
}
return DICT_ERR; /* not found */
}
4. 集合
Redis中的集合類型使用intset或者dict結(jié)構(gòu)實現(xiàn),使用dict結(jié)構(gòu)實現(xiàn)的集合稱為hashset。在Redis的源碼中,集合類型的操作可以在src/intset.c文件和src/dict.c文件中找到,其中最常用的操作為setAdd、setIsMember、setRemove。
setAdd操作的主要實現(xiàn)如下:
“`c
int setTypeAdd(robj *subject, robj *value) {
long long llval;
uint8_t success = 0;
if (subject->encoding == OBJ_INTSET) {
if (isObjectRepresentableAsLongLong(value,&llval) != C_OK)
return 0;
subject->ptr = intsetAdd((intset*)subject->ptr,llval,&success);
if (success) signalModifiedObject(subject);
return success;
} else if (subject->encoding == OBJ_HT) {
dict *ht = subject->ptr;
dictEntry *de;
de = dictAddOrFind(ht,value);
if (de == NULL)
return 0;
if (dictFind(ht,value) == NULL) {
incrRefCount(value);
dictSetKey(ht,de,value);
signalModifiedObject(subject);
}
return 1;
} else {
serverPanic(“Unknown set encoding”);
}
}
setRemove操作的主要實現(xiàn)如下:
```c
int setTypeRemove(robj *setobj, robj *value) {
long long llval;
dict *ht;
dictEntry *de;
if (setobj->encoding == OBJ_INTSET) {
if (isObjectRepresentableAsLongLong(value,&llval) != C_OK) return 0;
if (intsetRemove((intset*)setobj->ptr,llval,NULL)) {
if (intsetLen((intset*)setobj->ptr) == 0) {
setobj->ptr = intsetResize(setobj
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機、虛擬主機、域名注冊、VPS主機、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
新聞名稱:從源碼深入理解Redis(redis源碼深入理解)
文章地址:http://fisionsoft.com.cn/article/djepojh.html


咨詢
建站咨詢
