redis 1.2以后的协议中部分命令已经开始使用新的协议格式了(比如MSET),总之目前还是把包含边界字符当成非法的key,另外关于key的一个格式约定介绍下,object-type:id:field。比如user:1000:password,blog:xxidxx:title
2、string
string是redis最基本的类型,而且string类型是二进制安全的。意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。从内部实现来看其实string可以看作byte数组,最大上限是1G字节。
struct sdshdr {
long len;
long free;
char buf[];
};
buf是个char数组用于存贮实际的字符串内容。其实char和c#中的byte是等价的,都是一个字节 ,len是buf数组的长度,free是数组中剩余可用字节数。 由此可以理解为什么string类型是二进制安全的了。因为它本质上就是个byte数组。当然可以包含任何数据了。 另外string类型可以被部分命令按int处理,比如incr等命令,redis的其他类型像list,set,sorted set ,hash它们包含的元素与都只能是string类型。
编码
字符串对象的编码可以是 INT、RAW 或 EMBSTR。如果保存的是整数值并且可以用long表示,那么编码会设置为INT。当字符串值得长度大于44字节使用RAW,小于等于44字节使用EMBSTR。
Redis在3.0引入EMBSTR编码,这是一种专门用于保存短字符串的一种优化编码方式,这种编码和RAW编码都是用sdshdr简单动态字符串结构来表示。RAW编码会调用两次内存分配函数来分别创建redisObject和sdshdr结构,而EMBSTR只调用一次内存分配函数来分配一块连续的空间保存数据,比起RAW编码的字符串更能节省内存,以及能提升获取数据的速度。
不过要注意!EMBSTR是不可修改的,当对EMBSTR编码的字符串执行任何修改命令,总会先将其转换成RAW编码再进行修改;而INT编码在条件满足的情况下也会被转换成RAW编码。
两种字符串对象编码方式的区别
/* Create a string object with EMBSTR encoding if it is smaller than
* REIDS_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
* used.
*
* The current limit of 39 is chosen so that the biggest string object
* we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
//sdshdr8的大小为3个字节,加上1个结束符共4个字节
//redisObject的大小为16个字节
//redis使用jemalloc内存分配器,且jemalloc会分配8,16,32,64等字节的内存
//一个embstr固定的大小为16+3+1 = 20个字节,因此一个最大的embstr字符串为64-20 = 44字节
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44
// 创建字符串对象,根据长度使用不同的编码类型
// createRawStringObject和createEmbeddedStringObject的区别是:
// createRawStringObject是当字符串长度大于44字节时,robj结构和sdshdr结构在内存上是分开的
// createEmbeddedStringObject是当字符串长度小于等于44字节时,robj结构和sdshdr结构在内存上是连续的
robj *createStringObject(const char *ptr, size_t len) {
if (len <= OB