IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> redis-----08-----redigo管道以及事务-管道 -> 正文阅读

[大数据]redis-----08-----redigo管道以及事务-管道

1 Redis 管道

在这里插入图片描述
正常的情况下,redis是请求响应模式,一条请求后那么正常就会返回一个响应,例如上图。但是只存在这种情况是无法满足我们开发的需求的。所以redis给我们提供了管道。

redis的管道(pipeline )相关特点:

  • 1)redis的管道pipeline配合事务,可以实现原子操作,保证一次执行多条命令。注意:管道本身不具有原子操作,只是单纯提高传输性能,而原子操作还是由事务和lua脚本实现。
  • 2)它一次可以发送多次请求,然后返回多个响应,这个响应的顺序会依照你请求的顺序进行返回。
  • 3)管道作用:一次可以发送多条请求,并可以一次返回多个响应,例如下图,所以节省大量的网络耗时,减少与redis的交互,主要体现在TCP三次握手与四次挥手。如果将多个请求拆开,势必会效率大打折扣。
  • 4)redis pipeline 是一个由客户端提供的,而不是服务端提供的。
    在这里插入图片描述

下面我们来看一下redigo提供了哪些接口给我们。

type Conn interface { 
	// Close closes the connection. 
	Close() error 
	
	// Err returns a non-nil value when the connection is not usable. 
	Err() error 
	
	// Do sends a command to the server and returns the received reply. 
	Do(commandName string, args ...interface{}) (reply interface{}, err error)
	
	// Do = Send + Flush + Receive 
	
	// Send writes the command to the client's output buffer. 
	Send(commandName string, args ...interface{}) error 
	
	// Flush flushes the output buffer to the Redis server. 
	Flush() error 
	
	// Receive receives a single reply from the Redis server 
	Receive() (reply interface{}, err error) 
}

重点讲解Do和Send、Flush、Receive的关系。

  • 1)Do等价于执行了一次Send、Flush、Receive。
  • 2)Send函数代表往redigo的缓冲区发送消息,相当于写到缓冲区,此时并未发送到redis服务器。
  • 3)Flush函数代表真正的将redigo的缓冲区的内容往redis服务器发送。
  • 4)Receive函数代表从redis服务器中接收返回的信息。

2 管道作用

redis的主要作用上面也说过,就是节省大量的网络耗时,减少与redis的交互,主要体现在TCP三次握手与四次挥手。

3 管道使用技巧

// 1. 批量发送,批量接收。
c.Send(cmd1, ...) 
c.Send(cmd2, ...) 
c.Send(cmd3, ...) 
c.Flush() 	// 将上面的三个命令发送出去 
c.Receive() // cmd1 的返回值 
c.Receive() // cmd2 的返回值 
c.Receive() // cmd3 的返回值 

// 2. 如果不需要关注返回值。
c.Send(cmd1, ...) 
c.Send(cmd2, ...) 
c.Send(cmd3, ...) 
c.Do("") 
// 简单分析Do(""):
// Do=Send、Flush、Receive。而此时传空字符串,那么此时的Send相当于没命令即没意义,
// 那么此时的Do("")等价于连续执行了c.Flush()与c.Receive(),并不关心返回值。

// 3. 如果只关注最后一个命令的返回值。
// 一般这种情况前两条是写,第三条语句是读。
c.Send(cmd1, ...) 
c.Send(cmd2, ...) 
c.Do(cmd3, ...)

但是注意,上面每次调用函数后,都应该去判断返回值,养成良好的习惯,不是说忽略了redis的返回值就不判断错误。
例如忽略返回值但判断错误情况:

ifi( _, err := c.Do("")); err != nil{
	// 错误处理
} 

4 管道代码例子

package main

import (
	"fmt"
	"math/rand"
	"time"

	"github.com/garyburd/redigo/redis"
)

func main() {
	//c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", 6379))
	c, err := redis.Dial("tcp", "192.168.1.9:6379", redis.DialPassword("123456"))
	if err != nil {
		panic(err)
	}
	defer (func() {
		fmt.Println("connection close")
		c.Close()
	})()

	// 1. 批量发送,批量接收。
	if false {
		c.Send("del", "set", "list", "zset")
		c.Send("sadd", "set", "tyy", "hc", "lqq")
		c.Send("lpush", "list", 10001, 10002, 10003)
		c.Send("smembers", "set")
		c.Send("lrange", "list", 0, -1)
		c.Flush()
		c.Receive() // 忽略del的返回值。
		c.Receive() // 忽略sadd的返回值。
		c.Receive() // 忽略lpush的返回值。

		mbrs, err := redis.Strings(c.Receive()) // 接收smembers返回值。
		if err != redis.ErrNil {
			fmt.Println(mbrs)
		}
		lsts, err := redis.Ints(c.Receive()) // 接收lrange返回值。
		if err != redis.ErrNil {
			fmt.Println(lsts)
		}
	}

	// 2. 如果不需要关注返回值。
	if false {
		c.Send("del", "set", "list", "zset")
		c.Send("sadd", "set", "tyy", "hc", "lqq")
		c.Send("lpush", "list", 10001, 10002, 10003)
		c.Do("")
	}

	// 3. 如果只关注最后一个命令的返回值。
	if false {
		rand.Seed(time.Now().UnixNano())
		c.Send("del", "set", "list", "zset")
		c.Send("sadd", "set", "tyy", "hc", "lqq")
		{
			args := redis.Args{}.Add("zset")
			args = args.Add(rand.Intn(100)).Add("tyy")
			args = args.Add(rand.Intn(100)).Add("hc")
			args = args.Add(rand.Intn(100)).Add("lqq")
			c.Send("zadd", args...)
		}

		// 只关注最后一个命令的返回值。
		{
			args := redis.Args{}.Add("zset")
			args = args.Add(0).Add(-1).Add("withscores")
			vals, err := redis.Values(c.Do("zrange", args...))
			if err != nil {
				panic(err)
			}
			var rets []struct {
				Name  string
				Score int
			}
			if err = redis.ScanSlice(vals, &rets); err != nil {
				panic(err)
			}
			fmt.Println(rets)
		}
	}

}

测试方法:将上面的3个if添加中的false逐个改成true即可测得下面结果。
分别对应上面的结果:

  • 1)
    在这里插入图片描述

  • 2)此时因为程序不关心返回值,所以此时执行完程序结果只会打印connection close,所以我们可以去xshell命令行使用redis-cli查看结果。
    在这里插入图片描述

  • 3)这个结果可能大家都不一样,因为score是使用rand.Intn(100)随机生成的,所以排序可能会不一样。
    在这里插入图片描述

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:39:43  更:2022-03-04 15:43:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:30:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码