歪果人数码头像

深入剖析redis数据结构redisObject

来源:
       

  redis是key-value存储系统,其中key类型一般为字符串,而value类型则为redis对象(redisobject)。redis对象可以绑定各种类型的数据,譬如string、list和set。typedefstructredisObject{//刚刚好32bits//对象的类型,字符串/列表/集

  redis是key-value存储系统,其中key类型一般为字符串,而value类型则为redis对象(redisobject)。redis对象可以绑定各种类型的数据,譬如string、list和set。

  typedefstructredisObject{//刚刚好32bits//对象的类型,字符串/列表/集合/哈希表unsignedtype:4;//未使用的两个位unsignednotused:2;/Notused///编码的方式,redis为了节省空间,提供多种方式来保存一个数据//譬如:“123456789”会被存储为整数123456789unsignedencoding:4;//当内存紧张,淘汰数据的时候用到unsignedlru:22;/lrutime(relativetoserver.lruclock)///引用计数intrefcount;//数据指针voidptr;}robj;

  redis中定义了structredisObject,它是一个简单优秀的数据结构,因为在redisObject中数据属性和数据分开来了,其中,数据属性包括数据类型,存储编码方式,淘汰时钟,引用计数。下面一一展开:

  数据类型,标记了redis对象绑定的是什么类型的数据,有下面几种可能的值;

  /Objecttypes/#defineREDIS_STRING0#defineREDIS_LIST1#defineREDIS_SET2#defineREDIS_ZSET3#defineREDIS_HASH4

  存储编码方式,一个数据,可以以多种方式存储。譬如,数据类型为REDIS_SET的数据编码方式可能为REDIS_ENCODING_HT,也可能为REDIS_ENCODING_INTSET。

  /Objectsencoding.SomekindofobjectslikeStringsandHashescanbeinternallyrepresentedinmultipleways.The'encoding'fieldoftheobjectissettooneofthisfieldsforthisobject./#defineREDIS_ENCODING_RAW0/Rawrepresentation/#defineREDIS_ENCODING_INT1/Encodedasinteger/#defineREDIS_ENCODING_HT2/Encodedashashtable/#defineREDIS_ENCODING_ZIPMAP3/Encodedaszipmap/#defineREDIS_ENCODING_LINKEDLIST4/Encodedasregularlinkedlist/#defineREDIS_ENCODING_ZIPLIST5/Encodedasziplist/#defineREDIS_ENCODING_INTSET6/Encodedasintset/#defineREDIS_ENCODING_SKIPLIST7/Encodedasskiplist/

  淘汰时钟,redis对数据集占用内存的大小有「实时」的计算,当超出限额时,会淘汰超时的数据。

  引用计数,一个redis对象可能被多个指针引用。当需要增加或者减少引用的时候,必须调用相应的函数,程序员必须遵守这一准则。

  //增加redis对象引用voidincrRefCount(robjo){o->refcount++;}//减少redis对象引用。特别的,引用为零的时候会销毁对象voiddecrRefCount(robjo){if(o->refcount<=0)redisPanic("decrRefCountagainstrefcount<=0");//如果取消的是最后一个引用,则释放资源if(o->refcount==1){//不同数据类型,销毁操作不同switch(o->type){caseREDIS_STRING:freeStringObject(o);break;caseREDIS_LIST:freeListObject(o);break;caseREDIS_SET:freeSetObject(o);break;caseREDIS_ZSET:freeZsetObject(o);break;caseREDIS_HASH:freeHashObject(o);break;default:redisPanic("Unknownobjecttype");break;}zfree(o);}else{o->refcount--;}}

  得益于redis是单进程单线程工作的,所以增加/减少引用的操作不必保证原子性,这在memcache中是做不到的。

  structredisObject把最后一个指针留给了真正的数据。

  捣乱2014-6-18

  http://daoluan.net

  原文地址:深入剖析redis数据结构redisObject,感谢原作者分享。

上一篇:MySQL的utf8

下一篇:mongodb持久化(4)