redis的key 底层都是String
C语言标识字符串:
char data[] = “Strig\0” : \0结尾标识
redis定义的字符串类型
len:6
char buf[] = “string\0jaa”
依据len长度取值,
1:二进制安全的数据结构
2:提供内存预分配机制,避免频繁内存分配
3:兼容C语言函数库
后面会加上\0
free: buff还有多少可用空间
key扩容
成倍的扩容
(len + addlen ) 2
append命令
setbit命令涉及 key扩容
*长度=1024时,只会成倍扩容
String
数据结构
// redis 3.2 以前struct sdshdr {int len;int free;char buf[];};
3.2提供了5种区分不同的长度,应对不同的场景
typedef char *sds;struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];};struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* used */uint8_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];};struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];};struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];};struct __attribute__ ((__packed__)) sdshdr64 {........#define SDS_TYPE_5 0#define SDS_TYPE_8 1#define SDS_TYPE_16 2#define SDS_TYPE_32 3#define SDS_TYPE_64 4static inline char sdsReqType(size_t string_size) {if (string_size < 32)return SDS_TYPE_5;if (string_size < 0xff) //2^8 -1return SDS_TYPE_8;if (string_size < 0xffff) // 2^16 -1return SDS_TYPE_16;if (string_size < 0xffffffff) // 2^32 -1return SDS_TYPE_32;return SDS_TYPE_64;}
key
value:
: String ,hash set ,sorted set list
map —> dict
数据库:海量数据的存储
redis 使用了下面两种数据结构
1:数组: O(1)
2:链表:O(n)
hash(key) -> 自然数 %4 获取 arr的坐标值
1:任意仙童的输入,一定得到相同的输出
2:不同的输入可能会有相同的输出
hash碰撞
解决方案:链表法 类型hashmap,开放地址法(用的少)
redisDb
typedef struct redisDb {dict *dict; // key -valuedict *expires; //过期时间dict *blocking_keys;dict *ready_keys;dict *watched_keys;int id;long long avg_ttl;unsigned long expires_cursor;list *defrag_later;} redisDb;
typedef struct dictEntry {void *key; // 指针,sds对象union { // 值,只会用到下面的一个void *val; //执行一个value 对象 执行不同的类型,执行任意对象,redisObjectuint64_t u64;int64_t s64;double d;} v;struct dictEntry *next; //链表,hash冲突时} dictEntry;
typedef struct dict {dictType *type;void *privdata;dictht ht[2];long rehashidx;unsigned long iterators;} dict;
typedef struct redisObject {unsigned type:4; //标识value对象类型,string,hash,约束value类型unsigned encoding:4; //底层编码:命令: > Objectunsigned lru:LRU_BITS;int refcount; //: 对象引用,回收用的void *ptr; //value的真实内存指向} robj;

typedef struct dictht {dictEntry **table;unsigned long size; //hashTabl容量unsigned long sizemask; = size-1 求模用unsigned long used;} dictht;
扩容不是一次全部都转移,而是分批次的
String结构
embstr嵌入式string 45一下
raw类型 45以上
bitmap
一亿级日活统计,
key: 日期
value : offset
setbit key offset 0/1 setbit a-bit-map 0 1 对key a-bit-map 的第0 位设为1
bitcount a-bit-map 统计bit=1的个数 bitcount a-bit-map 0 12 统计0-12范围的位等于1的个数
bitcount and login-11-5-6 login-11-
bitop and newkey login11-5-6 login11-5-7 把后面的key 位与运算存在new key中 然后在 bitcount newkey 得到位1的总算 bitop or newkey key1 key2 然后在 bitcount newkey 统计

