redis服务器是一个一对多的架构,服务端通过I/O 多路复用技术实现的文件事件处理,采用单线程单进程的方式来处理和
多个client的请求.
struct redisServer {
// 保存了所有客户端状态结构
list *clients; /* List of active clients */
// 链表,保存了所有待关闭的客户端
list *clients_to_close; /* Clients to close asynchronously */
}
从redis中表示server端的redisServer结构体可以看出,在server端所有的client都是保存在clients 这个list中.
client 可以分成两类一类是fake clint,这类clint 不用套接字连接,主要用于载入AOF和Lua脚本执行的过程
在redisClient 这个结构体中如果是fake clent则fd=-1,另外一种就是fd不等于-1,表示正常的client
可以通过CLIENT list 列出当前的client,
typedef struct redisClient {
// fake client的话,fd等于-1
int fd;
// 客户端的名字,可以通过clint list来查询
robj *name; /* As set by CLIENT SETNAME */
// 保存客户端发送的命令请求
sds querybuf;
// 查询缓冲区长度峰值
size_t querybuf_peak; /* Recent (100ms or more) peak of querybuf size */
// 参数数量
int argc;
// 参数对象数组
robj **argv;
// 记录被客户端执行的命令
struct redisCommand *cmd, *lastcmd;
// 客户端状态标志,揭示目前clint 处于的状态
int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
// 表示client是否被认证,0表示没有被认证,没有被认证的话,只能执行AUTH 这个命令.
int authenticated; /* when requirepass is non-NULL */
/* Response buffer */
// 回复偏移量
int bufpos;
// 执行命令所得的命令回复会被保存到这个缓冲区中,每个clint 有两个缓冲区,一个固定缓冲区16k。
// 固定缓冲区就用buf这个数组表示,另外一个是动态缓冲区 list *reply 来表示
char buf[REDIS_REPLY_CHUNK_BYTES];
} redisClient;
1.redis中用户可以通过slaveeof命令或者设置slaveof 选项,来让一个服务器去复制另外一个服务器.
2.redis的赋值功能分为sync和command propagate 两个操作。当从服务器发送sync 给主服务器是,主服务器
会通过bgsave 名声生成一个rbd文件发送给从服务器,从服务器会在载入这个rbd文件,与此同时主服务器会将记录
在缓冲区中的所有写命令发送给从服务器,从服务器在载入rbd,并执行主服务器发送的写命令后,其状态就和主服务器 一样
了,后续主服务器会持续发送缓冲期中的命令给从服务器
3.在redis 2.8 中实现了psync 命令可以实现完成重同步和部分重同步,
其中的部分重同步是由下面三部分组成
1):主从服务器的复制偏移量
2):主服务器的复制积压缓冲区,这是一个固定出的的FIFO,默认大小是1M
3):服务器运行的ID,是由40个随机的16进制字符组成
4:sentinel 是redis 的高可靠性的解决方案.
5:sentinel 是将一部分普通redis服务器用的代码换成sentinel的专用代码,因此sentinel 本质还是服务器
例如普通服务器支持的命令在redis. 中的redisCommandTable 中实现的
struct redisCommand redisCommandTable[] = {
{"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
{"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0},
{"setnx",setnxCommand,3,"wm",0,NULL,1,1,1,0,0},
{"setex",setexCommand,4,"wm",0,NULL,1,1,1,0,0},
{"psetex",psetexCommand,4,"wm",0,NULL,1,1,1,0,0},
{"append",appendCommand,3,"wm",0,NULL,1,1,1,0,0},
{"strlen",strlenCommand,2,"r",0,NULL,1,1,1,0,0},
{"del",delCommand,-2,"w",0,NULL,1,-1,1,0,0},
{"exists",existsCommand,2,"r",0,NULL,1,1,1,0,0},
{"setbit",setbitCommand,4,"wm",0,NULL,1,1,1,0,0},
{"getbit",getbitCommand,3,"r",0,NULL,1,1,1,0,0},
。。。
}
但是sentinel支持的命令在sentinel.c 中且支持下面这些命令
struct redisCommand sentinelcmds[] = {
{"ping",pingCommand,1,"",0,NULL,0,0,0,0,0},
{"sentinel",sentinelCommand,-2,"",0,NULL,0,0,0,0,0},
{"subscribe",subscribeCommand,-2,"",0,NULL,0,0,0,0,0},
{"unsubscribe",unsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
{"psubscribe",psubscribeCommand,-2,"",0,NULL,0,0,0,0,0},
{"punsubscribe",punsubscribeCommand,-1,"",0,NULL,0,0,0,0,0},
{"publish",sentinelPublishCommand,3,"",0,NULL,0,0,0,0,0},
{"info",sentinelInfoCommand,-1,"",0,NULL,0,0,0,0,0},
{"shutdown",shutdownCommand,-1,"",0,NULL,0,0,0,0,0}
};
可以看出sentinel支持的命令要比普通服务器少很多
6:sentinelState 主要保存和sentinel 功能有关的状态
7:每个sentinelRedisInstance 代表一个本sentinel监视的redis服务器实例
8:每个被sentinel 监视的主服务器会创建命令连接和订阅连接.
9:sentinel 默认会以10s一次的频率向北监视的主服务器发起发送info命令,通过
分析info命令的回复来获取主服务器的当前信息
10:sentinel 会以每秒一次的频率向其他实例,包括主服务器,从服务器,其他sentinel发送ping 命令,
根据对ping命令的回复判断实例是否在线.
11:redis 集群可能通过cluster meet ip + port 来组建
12:redis集群中的节点会继续使用所有在单机模式中使用的服务器组建.节点的数据会奥村在clusterNode结构中
13:节点之间是根据slot来区分目前数据是保存到哪个节点上的,平时可以通过cluster info来查看节点信息,
通过cluster addslots 来添加slot.总共有16383个slot.
14:可以增加新的节点,这会导致slot的重新分配,这叫做分片.
redis中的server/client/sentinel/集群
最新推荐文章于 2023-06-29 01:38:57 发布