什么是Redis?
Redis是用C语言开发的一个开源免费的高性能键值对(key-value)内存数据库,遵守BSD协议。
Redis特点:
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供String,list,set,zset,hash等数据结构的存储。
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe, 通知, 设置key有效期等等特性。
Redis数据存储原理
redisDb
redis 中以redisDb作为整个缓存存储的核心,保存着我们客户端需要的缓存数据
typedef struct redisDb {
dict *dict;
dict *expires;
dict *blocking_keys;
dict *ready_keys;
dict *watched_keys;
int id;
long long avg_ttl;
list *defrag_later;
} redisDb;
dictht
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
dict
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx;
int iterators;
} dict;
dictEntry
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next;
} dictEntry;
redisDB、dict、dictht、dictEntry、RedisObject的存储结构关系如图:
dictEntry :16字节
RedisObject:12字节
sds:8字节 + 字符串长度
我们现在思考,如果一个10字节的key,需要多少存储空间呢?
16+12+8+10+1=47*2(exprires也需要同样的空间所以乘以倍数)
所以在日常使用中设置key的时候尽量的少的字节,避免空间的浪费。
内存清理方式
定期清理:
随机取样的方式,如果清理的比例大于25%。
惰性删除:
被动删除策略,访问时判断;
LFU
volatile-lfu:对有过期时间的key采用LFU淘汰算法;
allkeys-lfu:对全部key采用LFU淘汰算法;
LRU
volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放;
allkeys-lru:从数据集中选择最近最久未使用的数据释放。
Redis可靠性保障
主从模式:
启动时,全量同步Slave。增量同步,运行ID(Master启动时生成),同步给Slave,通过复制偏移量确定具体同步位置:
哨兵模式:
不断地检查Master和Slave是否运作正常,发现故障通知管理员和客户端,自动主从切换,更新配置信息,客户端应用初始化时连接Sentinel获取节点信息;
集群模式
无需Sentinel哨兵,支持水平扩容,自动迁移。