redis client原理分析
- 1:连接池
- 2:发送命令
- 3:解析结果
type Pool struct {
// Dial is an application supplied function for creating and configuring a
// connection.
//
// The connection returned from Dial must not be in a special state
// (subscribed to pubsub channel, transaction started, ...).
Dial func() (Conn, error) //生成网络连接对象
// TestOnBorrow is an optional application supplied function for checking
// the health of an idle connection before the connection is used again by
// the application. Argument t is the time that the connection was returned
// to the pool. If the function returns an error, then the connection is
// closed.
TestOnBorrow func(c Conn, t time.Time) error //测试连接是否通畅
// Maximum number of idle connections in the pool.
MaxIdle int //最大空闲连接数
// Maximum number of connections allocated by the pool at a given time.
// When zero, there is no limit on the number of connections in the pool.
MaxActive int //最大活动(正在执行任务)连接数
// Close connections after remaining idle for this duration. If the value
// is zero, then idle connections are not closed. Applications should set
// the timeout to a value less than the server's timeout.
IdleTimeout time.Duration //空闲连接超时时间,超时会释放
// If Wait is true and the pool is at the MaxActive limit, then Get() waits
// for a connection to be returned to the pool before returning.
Wait bool //当到达最大活动连接时,是否阻塞
chInitialized uint32 // set to 1 when field ch is initialized 初始化标记
mu sync.Mutex // mu protects the following fields 锁
closed bool // set to true when the pool is closed. 连接池关闭标记
active int // the number of open connections in the pool 连接总数
ch chan struct{} // limits open connections when p.Wait is true 用于实现阻塞逻辑
idle idleList // idle connections 双向链表,存放空闲连接
}
type idleList struct { //空闲连接链表
count int //空闲连接数
front, back *idleConn //空闲连接信息
}
type idleConn struct { //空闲连接信息
c Conn //连接接口
t time.Time //加入空闲队列的时间,用于判断空闲超时
next, prev *idleConn //双向链表指针
}
func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
return c.DoWithTimeout(c.readTimeout, cmd, args...)
}
func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
c.mu.Lock()
pending := c.pending
c.pending = 0
c.mu.Unlock()
if cmd == "" && pending == 0 {
return nil, nil
}
//设置写超时时间
if c.writeTimeout != 0 {
c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
}
//发送命令内容
if cmd != "" {
if err := c.writeCommand(cmd, args); err != nil {
return nil, c.fatal(err)
}
}
if err := c.bw.Flush(); err != nil {
return nil, c.fatal(err)
}
var deadline time.Time
if readTimeout != 0 {
deadline = time.Now().Add(readTimeout)
}
//设置读超时时间
c.conn.SetReadDeadline(deadline)
if cmd == "” {
//获取server回复信息并解析
reply := make([]interface{}, pending)
for i := range reply {
r, e := c.readReply()
if e != nil {
return nil, c.fatal(e)
}
reply[i] = r
}
return reply, nil
}
var err error
var reply interface{}
for i := 0; i <= pending; i++ {
var e error
if reply, e = c.readReply(); e != nil {
return nil, c.fatal(e)
}
if e, ok := reply.(Error); ok && err == nil {
err = e
}
}
return reply, err
}
redis请求协议格式
set命令消息格式:
*3\r\n$3\r\nSET\r\n$4\r\nhlxs\r\n$28\r\nhttps://www.cnblogs.com/hlxs\r\n 注释如下:
*3 //参数个数是*开头,3个参数
$3 //参数长度是$开头,命令长度
SET //命令名称SET
$5 //参数长度是$开头,key长度
mykey //key的内容
$28 //参数长度是$开头,value长度
https://www.cnblogs.com/hlxs //value内容
* 状态回复(status reply)的第一个字节是 “+”,如:+ok\r\n
* 错误回复(error reply)的第一个字节是 “-“,如:-ERR unknown command xxx\r\n
在 "-" 之后,直到遇到第一个空格或新行为止,这中间的内容表示所返回错误的类型
* 整数回复(integer reply)的第一个字节是 “:”,如::1000\r\n
* 批量回复(bulk reply)的第一个字节是 “$”,如:$6\r\nfoobar\r\n,也是长度加内容的风格
* 多条批量回复(multi bulk reply)的第一个字节是 “*”,如:*5\r\n:1\r\n:2\r\n:3\r\n:4\r\n$6\r\nfoobar\r\n,前面多了数量
接收命令其实就是解析以上格式
redis client原理分析的更多相关文章
- Redis事务原理分析
Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...
- 一、Redis事务原理分析
一.Redis事务原理分析 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD.通过 ...
- Redis Pipeline原理分析
转载请注明出处:http://www.cnblogs.com/jabnih/ 1. 基本原理 1.1 为什么会出现Pipeline Redis本身是基于Request/Response协议的,正常情况 ...
- Redis数据持久化机制AOF原理分析一---转
http://blog.csdn.net/acceptedxukai/article/details/18136903 http://blog.csdn.net/acceptedxukai/artic ...
- Redis核心原理与实践--事务实践与源码分析
Redis支持事务机制,但Redis的事务机制与传统关系型数据库的事务机制并不相同. Redis事务的本质是一组命令的集合(命令队列).事务可以一次执行多个命令,并提供以下保证: (1)事务中的所有命 ...
- redis原理分析
基本全是参考http://blog.csdn.net/a600423444/article/details/8944601 redis的使用大家都很熟悉,可能除了watch 锁,pipelin ...
- Redis有序集内部实现原理分析(二)
Redis技术交流群481804090 Redis:https://github.com/zwjlpeng/Redis_Deep_Read 本篇博文紧随上篇Redis有序集内部实现原理分析,在这篇博文 ...
- 【Redis】跳跃表原理分析与基本代码实现(java)
最近开始看Redis设计原理,碰到一个从未遇见的数据结构:跳跃表(skiplist).于是花时间学习了跳表的原理,并用java对其实现. 主要参考以下两本书: <Redis设计与实现>跳表 ...
- Redis核心原理与实践--Redis启动过程源码分析
Redis服务器负责接收处理用户请求,为用户提供服务. Redis服务器的启动命令格式如下: redis-server [ configfile ] [ options ] configfile参数指 ...
随机推荐
- 浅谈 Java线程状态转换及控制
线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)这五 ...
- python 系统设置
1. 设置python运行环境为utf-8 import sys #引用sys模块 reload(sys) #重新加载sys sys.setdefaultencoding("utf-8&qu ...
- 0923 lca练习
P1967 货车运输 题目描述 A 国有 nnn 座城市,编号从 11 1 到 n nn,城市之间有 mmm 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 qqq 辆货车在运输货物, ...
- 软件定义网络实验记录③--Mininet 实验——测量路径的损耗率
一.实验目的 在实验 2 的基础上进一步熟悉 Mininet 自定义拓扑脚本,以及与损耗率相关的设定: 初步了解 Mininet 安装时自带的 POX 控制器脚本编写,测试路径损耗率. 二.实验任务 ...
- 安卓app功能或自动化测试覆盖率统计(不用instrumentation启动app)
一文带你揭秘如何采取非instrumentation启动app,打造实时统计覆盖率,一键触发覆盖率测试报告. 在上篇文章,一文带你解决Android app手工测试或者自动化测试覆盖率统计(撸代码版) ...
- 手把手教你AspNetCore WebApi:入门
需求 前几天,马老板给小明和小红一个"待办事项"网站,小明负责后端,小红负责前端,并要求网站可以同时在 Windows.和 Linux 上运行. 小明整理了一下"待办事项 ...
- 实验一 C运行环境与最简单的程序设计
实验一: #include<stdio.h> int main() { int a1,a2; int sum; a1 =123; a2 = 456; sum = a1+ ...
- 062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用
062 01 Android 零基础入门 01 Java基础语法 07 Java二维数组 01 二维数组应用 本文知识点:二维数组应用 二维数组的声明和创建 ? 出现空指针异常 数组的名字指向数组的第 ...
- #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
转载:https://www.cnblogs.com/cvwyh/p/10570920.html 错误 在使用VS编译文件时出现了如下错误: #error: Building MFC applicat ...
- VSCode搭建golang环境
安装对应版本的Golang 略 VSCode安装对应 Go 插件 在应用商店安装即可:go VSCode安装 Go 工具: 在VSCode输入:Crtl + Shift + P 在弹出框输入:inst ...