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参数指 ... 
随机推荐
- 高德AR & 车道级导航技术演进与实践
			2020云栖大会于9月17日-18日在线上举行,阿里巴巴高德地图携手合作伙伴精心组织了"智慧出行"专场,为大家分享高德地图在打造基于DT+AI和全面上云架构下的新一代出行生活服务平 ... 
- Quartz.NET集成UI版
			Quartz.NET Quartz.NET是NET的开源作业调度系统. Quartz.NET是一个功能齐全的开源作业调度系统,可用于从最小的应用程序到大型企业系统. Quartz.NET目前支持NET ... 
- eureka源码--服务的注册、服务续约、服务发现、服务下线、服务剔除、定时任务以及自定义注册中心的思路
			微服务注册后,在注册中心的注册表结构是一个map: ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>& ... 
- SpringBoot整合SpringDataJPA,今天没啥事情就看了一下springboot整合springdataJPA,实在是香啊,SQL语句都不用写了
			SpringBoot整合SpringDataJPA 1.JPA概念 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映 ... 
- Arduino 串口库函数
			库函数目录 if (Serial) available() availableForWrite() begin() end() find() findUntil() flush() parseFloa ... 
- Android高级控件(下)
			计时器(Chronometer) getBase() 基准时间 setFormat() 设置显示格式 start() 开始计时 stop() 停止计时 setOnChronometerListener ... 
- 深入理解golang:Context
			一.背景 在golang中,最主要的一个概念就是并发协程 goroutine,它只需用一个关键字 go 就可以开起一个协程,并运行. 一个单独的 goroutine运行,倒也没什么问题.如果是一个go ... 
- try-finally的时候try里面带return
			最近学习的JVM小册中老师提了个问题: 最开始我觉得是1,结果程序跑出来是0,感到很疑惑,于是查看了下字节码: 从字节码可以看出: 0:定义变量0 1:将0存入本地变量表slot-0 2:加载slot ... 
- ubuntu20 使用命令安装 nginx
			安装 nginx sudo apt-get install nginx -y 配置文件 nginx 服务管理 # 启动 nginx 服务 service nginx start # 关闭 nginx ... 
- Apache Hudi与Apache Flink集成
			感谢王祥虎@wangxianghu 投稿 Apache Hudi是由Uber开发并开源的数据湖框架,它于2019年1月进入Apache孵化器孵化,次年5月份顺利毕业晋升为Apache顶级项目.是当前最 ... 
