# Redis配置文件
# 启用AOF持久化
appendonly yes
# 当AOF文件增长 100% 时重写AOF文件
auto-aof-rewrite-percentage 100
# 当AOF文件大于 64M 时重写AOF文件
auto-aof-rewrite-min-size 64mb
Redis序列化协议 RESP
Redis Serialization Protocol
(RESP
)是Redis客户端
和服务器
之间使用的通信协议。它是一种简单、高效的文本协议,易于实现和解析。
Redis主从数据同步
有一个常见的问题,Redis是如何实现高可用的?
(1) 如何实现高可用
在分布式环境中,有可能出现某台机器挂了,为了保障高可用,首先要提高服务的分区容错性,一般都会通过冗余来实现。
Redis主从是冗余的一种体现。
Redis的高可用是通过主从
、哨兵
来保障的。在主库挂了以后,哨兵
可以把流量切到从库
,让从库顶上去,来保障服务可用。
那就有一个问题了,顶上去的从库的数据和主库数据一样吗?还有Redis是如何实现主从数据同步的?
(2) Redis主从数据同步
Redis多个副本(主库和从库)之间的数据如何保持一致呢?
数据读写操作可以发给所有的实例吗?
(2.1) 新增数据是如何保存到Redis副本
Redis是通过读写分离的方式,通过主从库模式来保障多个副本数据一致。 (MySQL、Kafka也是类似)
为什么要采用读写分离的方式呢?
set key v1
set key v2
如果允许所有副本接收写操作(新增 修改 删除),数据在这多个副本可能就不一致了(分别是 v1 和 v2)。
如果必须保障新增的数据在多个副本上一致,就要涉及到加锁
、实例间协商是否完成修改
等一系列操作,但这会带来巨额的开销,当然是不太能接受的。
Redis IO多线程
Redis key 惰性删除
Redis执行模型-Redis是单线程的吗?
Redis事件驱动框架
Redis 对象 Stream
Redis Server 启动
Redis整体架构
Redis是典型的 Client-Server
架构,类似于MySQL和RPC框架。
Redis Server类似于RPC框架Server,在客户端使用前需要先启动Redis Server。那么有一个问题,Redis Server启动后会做哪些操作?需要哪些配置,有没有什么坑?
(1) Redis Server启动入口-main函数
源码地址 https://github.com/redis/redis/blob/6.0/src/server.c
//file: src/server.c
// #L5297 5297行
int main(int argc, char **argv) {
// 1. 初始化配置 设置默认值
initServerConfig();
/* We need to init sentinel right now as parsing the configuration file
* in sentinel mode will have the effect of populating the sentinel
* data structures with master nodes to monitor. */
// 2. 判断server是否设置为哨兵模式
if (server.sentinel_mode) {
initSentinelConfig();
// 初始化哨兵
initSentinel();
}
/* Check if we need to start in redis-check-rdb/aof mode. We just execute
* the program main. However the program is part of the Redis executable
* so that we can easily execute an RDB check on loading errors. */
// 3. 持久化 rdb aof
if (strstr(argv[0],"redis-check-rdb") != NULL)
redis_check_rdb_main(argc,argv,NULL);
else if (strstr(argv[0],"redis-check-aof") != NULL)
redis_check_aof_main(argc,argv);
// 4. 加载Server配置
loadServerConfig(configfile,options);
// 5. 启动RedisServer时 初始化配置及资源
initServer();
// 6. 循环处理请求及事件,直到服务器关闭为止
aeMain(server.el);
}
Redis 对象 有序集合 / Sorted Set / zset
有序集合(Sorted Set)是Redis中的一种对象,它本身是集合类型,同时也可以支持集合中的元素带有权重,并按权重排序。
(1) 有序集合(Sorted Set)是什么
/*
* ZSET 是有序集合,使用两个数据结构来保存相同的元素,以便将 O(log(N)) INSERT 和 REMOVE 操作放入已排序的数据结构中。
*
* 这些元素被添加到将 Redis 对象映射到分数的哈希表中。
* 同时,将元素添加到将分数映射到 Redis 对象的跳跃列表(因此对象在此“视图”中按分数排序)。
*
* 请注意,为了节省内存,表示元素的 SDS 字符串在哈希表和跳表中都是相同的。
* 为了更容易地管理共享的 SDS 字符串,我们所做的是仅在 zslFreeNode() 中释放 SDS 字符串。
* 字典没有设置无值方法。
* 所以我们应该总是从字典中删除一个元素,然后再从跳过列表中删除。
*/
(1.1) 有序集合结构
/*
* 有序集合 zset 结构体
*/
typedef struct zset {
dict *dict; // 字典
zskiplist *zsl; // 跳表
} zset;
Sorted Set 同时采用跳表
和哈希表
两个索引结构
利用了跳表高效支持范围查询(如 ZRANGEBYSCORE 操作),以及哈希表高效支持单点查询(如 ZSCORE 操作)的特征
可以在一个数据类型中,同时高效支持范围查询和单点查询,这是单一索引结构比较难达到的效果。