国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Go Redis 管道和事務(wù)之 go-redis

這篇具有很好參考價(jià)值的文章主要介紹了Go Redis 管道和事務(wù)之 go-redis。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Go Redis 管道和事務(wù)之 go-redis

Go Redis 管道和事務(wù)官方文檔介紹

Redis pipelines(管道) 允許一次性發(fā)送多個(gè)命令來提高性能,go-redis支持同樣的操作, 你可以使用go-redis一次性發(fā)送多個(gè)命令到服務(wù)器,并一次讀取返回結(jié)果,而不是一個(gè)個(gè)命令的操作。

Go Redis 管道和事務(wù): https://redis.uptrace.dev/zh/guide/go-redis-pipelines.html

  • 管道

  • Watch 監(jiān)聽

  • 事務(wù)

#管道

通過 go-redis Pipeline 一次執(zhí)行多個(gè)命令并讀取返回值:

pipe := rdb.Pipeline()

incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)

cmds, err := pipe.Exec(ctx)
if err != nil {
	panic(err)
}

// 結(jié)果你需要再調(diào)用 Exec 后才可以使用
fmt.Println(incr.Val())

或者你也可以使用 Pipelined 方法,它將自動(dòng)調(diào)用 Exec:

var incr *redis.IntCmd

cmds, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
	incr = pipe.Incr(ctx, "pipelined_counter")
	pipe.Expire(ctx, "pipelined_counter", time.Hour)
	return nil
})
if err != nil {
	panic(err)
}

fmt.Println(incr.Val())

同時(shí)會(huì)返回每個(gè)命令的結(jié)果,你可以遍歷結(jié)果集:

cmds, err := rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
	for i := 0; i < 100; i++ {
		pipe.Get(ctx, fmt.Sprintf("key%d", i))
	}
	return nil
})
if err != nil {
	panic(err)
}

for _, cmd := range cmds {
    fmt.Println(cmd.(*redis.StringCmd).Val())
}

#Watch 監(jiān)聽

使用 Redis 事務(wù), 監(jiān)聽key的狀態(tài),僅當(dāng)key未被其他客戶端修改才會(huì)執(zhí)行命令, 這種方式也被成為 樂觀鎖。

Redis 事務(wù):https://redis.io/docs/manual/transactions/

樂觀鎖:

WATCH mykey

val = GET mykey
val = val + 1

MULTI
SET mykey $val
EXEC

#事務(wù)

你可以使用 TxPipelinedTxPipeline 方法,把命令包裝在 MULTI 、 EXEC 中, 但這種做法沒什么意義:

cmds, err := rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
	for i := 0; i < 100; i++ {
		pipe.Get(ctx, fmt.Sprintf("key%d", i))
	}
	return nil
})
if err != nil {
	panic(err)
}

// MULTI
// GET key0
// GET key1
// ...
// GET key99
// EXEC

你應(yīng)該正確的使用 Watch + 事務(wù)管道, 比如以下示例,我們使用 GET, SETWATCH 命令,來實(shí)現(xiàn) INCR 操作, 注意示例中使用 redis.TxFailedErr 來判斷失?。?/p>

const maxRetries = 1000

// increment 方法,使用 GET + SET + WATCH 來實(shí)現(xiàn)Key遞增效果,類似命令 INCR
func increment(key string) error {
	// 事務(wù)函數(shù)
	txf := func(tx *redis.Tx) error {
   // // 獲得當(dāng)前值或零值 
		n, err := tx.Get(ctx, key).Int()
		if err != nil && err != redis.Nil {
			return err
		}

		n++  // 實(shí)際操作

    // 僅在監(jiān)視的Key保持不變的情況下運(yùn)行
		_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			pipe.Set(ctx, key, n, 0)
			return nil
		})
		return err
	}
	
	for i := 0; i < maxRetries; i++ {
		err := rdb.Watch(ctx, txf, key)
		if err == nil {
			// Success.
			return nil
		}
		if err == redis.TxFailedErr {
			// 樂觀鎖失敗
			continue
		}
		return err
	}

	return errors.New("increment reached maximum number of retries")
}

Go Redis 管道和事務(wù) 實(shí)操

package main

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

// 聲明一個(gè)全局的 rdb 變量
var rdb *redis.Client

// 初始化連接
func initRedisClient() (err error) {
	// NewClient將客戶端返回給Options指定的Redis Server。
	// Options保留設(shè)置以建立redis連接。
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 沒有密碼,默認(rèn)值
		DB:       0,  // 默認(rèn)DB 0 連接到服務(wù)器后要選擇的數(shù)據(jù)庫。
		PoolSize: 20, // 最大套接字連接數(shù)。 默認(rèn)情況下,每個(gè)可用CPU有10個(gè)連接,由runtime.GOMAXPROCS報(bào)告。
	})

	// Background返回一個(gè)非空的Context。它永遠(yuǎn)不會(huì)被取消,沒有值,也沒有截止日期。
	// 它通常由main函數(shù)、初始化和測(cè)試使用,并作為傳入請(qǐng)求的頂級(jí)上下文
	ctx := context.Background()

	_, err = rdb.Ping(ctx).Result()
	if err != nil {
		return err
	}
	return nil
}

// watchDemo 在key值不變的情況下將其值+1
func watchKeyDemo(key string) error {
	ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
	defer cancel()

	// Watch準(zhǔn)備一個(gè)事務(wù),并標(biāo)記要監(jiān)視的密鑰,以便有條件執(zhí)行(如果有密鑰的話)。
	// 當(dāng)fn退出時(shí),事務(wù)將自動(dòng)關(guān)閉。
	// func (c *Client) Watch(ctx context.Context, fn func(*Tx) error, keys ...string)
	return rdb.Watch(ctx, func(tx *redis.Tx) error {
		// Get Redis `GET key` command. It returns redis.Nil error when key does not exist.
		// 獲取 Key 的值 n
		n, err := tx.Get(ctx, key).Int()
		if err != nil && err != redis.Nil {
			fmt.Printf("redis get failed, err: %v\n", err)
			return err
		}
		// 假設(shè)操作耗時(shí)5秒
		// 5秒內(nèi)我們通過其他的客戶端修改key,當(dāng)前事務(wù)就會(huì)失敗
		time.Sleep(5 * time.Second)
		// txpipeline 執(zhí)行事務(wù)中fn隊(duì)列中的命令。
		// 當(dāng)使用WATCH時(shí),EXEC只會(huì)在被監(jiān)視的鍵沒有被修改的情況下執(zhí)行命令,從而允許檢查和設(shè)置機(jī)制。
		// Exec總是返回命令列表。如果事務(wù)失敗,則返回TxFailedErr。否則Exec返回第一個(gè)失敗命令的錯(cuò)誤或nil
		_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			// 業(yè)務(wù)邏輯 如果 Key 沒有變化,則在原來的基礎(chǔ)上加 1
			pipe.Set(ctx, key, n+1, time.Hour)
			return nil
		})
		return err
	}, key)
}

func main() {
	if err := initRedisClient(); err != nil {
		fmt.Printf("initRedisClient failed: %v\n", err)
		return
	}
	fmt.Println("initRedisClient started successfully")
	defer rdb.Close() // Close 關(guān)閉客戶端,釋放所有打開的資源。關(guān)閉客戶端是很少見的,因?yàn)榭蛻舳耸情L(zhǎng)期存在的,并在許多例程之間共享。


	err := watchKeyDemo("watch_key")
	if err != nil {
		fmt.Printf("watchKeyDemo failed: %v\n", err)
		return
	}
	fmt.Printf("watchKeyDemo succeeded!\n")
}

運(yùn)行

Code/go/redis_demo via ?? v1.20.3 via ?? base 
? go run main.go
initRedisClient started successfully
watchKeyDemo succeeded!

Code/go/redis_demo via ?? v1.20.3 via ?? base took 6.5s 
? go run main.go
initRedisClient started successfully
watchKeyDemo failed: redis: transaction failed

Code/go/redis_demo via ?? v1.20.3 via ?? base took 6.2s 
? 

Redis 操作文章來源地址http://www.zghlxwxcb.cn/news/detail-486505.html

27.0.0.1:6379> get watch_key
(nil)
127.0.0.1:6379> set watch_key 9
OK
127.0.0.1:6379> get watch_key
"9"
127.0.0.1:6379> get watch_key
"10"
127.0.0.1:6379> set watch_key 99
OK
127.0.0.1:6379>

到了這里,關(guān)于Go Redis 管道和事務(wù)之 go-redis的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • redis 事務(wù)與管道

    redis 事務(wù)與管道

    1.1 什么是事務(wù): 指可以一次執(zhí)行多個(gè)命令,本質(zhì)是一組命令的集合。 一個(gè)事務(wù)中的所有命令都會(huì)序列化, 按順序的串行化執(zhí)行而不會(huì)被其他命令插入,不許加塞 。 即: 一個(gè)隊(duì)列中,一次性、順序性、排他性的執(zhí)行一系列命令 。 1.2 與傳統(tǒng)關(guān)系型數(shù)據(jù)庫的事務(wù)相比redis事務(wù)

    2024年02月04日
    瀏覽(32)
  • Redis---事務(wù)&管道

    Redis---事務(wù)&管道

    目錄 一、Redis的事務(wù)是什么? 1.1 Redis和關(guān)系型數(shù)據(jù)庫事務(wù)的區(qū)別 ?二、怎么玩Redis事務(wù)? ?2.1? 正常執(zhí)行: ?2.2 放棄事務(wù) ?2.3? 全體連坐 ?2.4? 冤頭債主 ?2.5? watch監(jiān)控 三、管道 3.1? 為什么會(huì)引入管道這個(gè)概念呢?我們首先來看一道面試題 3.2? ?管道是什么? ?3.3? 管道的

    2024年02月03日
    瀏覽(14)
  • 4.redis-事務(wù)和管道

    目錄 一.事務(wù) ? 1.特性 ? 2.命令 二.管道 pipe ? 1.操作 ? 2.與原生批量命令對(duì)比 ? 4.注意事項(xiàng) ? 1.特性 ? ? 1) 單獨(dú)的隔離操作 ? ? ? Redis的事務(wù)僅僅是保證事務(wù)里的操作會(huì)被連續(xù)獨(dú)占得執(zhí)行,redis命令執(zhí)行是單線程架構(gòu),在執(zhí)行完事事務(wù)內(nèi)所有指令是不可能再去同時(shí)執(zhí)行其他客

    2023年04月09日
    瀏覽(16)
  • Redis 7 第五講 事務(wù)、管道、發(fā)布訂閱 過渡篇

    Redis 7 第五講 事務(wù)、管道、發(fā)布訂閱 過渡篇

    ?????????可以一次執(zhí)行多個(gè)命令,本質(zhì)是一組命令的集合。一個(gè)事務(wù)中的所有命令都會(huì)序列化,按順序地串行化執(zhí)行而不會(huì)被其它命令插入,不許加塞 ?????? ??一個(gè)隊(duì)列中,一次性、順序性、排他性的執(zhí)行一系列命令 單獨(dú)的隔離操作 Redis的事務(wù)僅僅是保證事務(wù)里的操

    2024年02月10日
    瀏覽(42)
  • Go學(xué)習(xí)第十一章——協(xié)程goroutine與管道channel

    Go學(xué)習(xí)第十一章——協(xié)程goroutine與管道channel

    1 協(xié)程goroutine 1.1 基本介紹 前置知識(shí):“進(jìn)程和線程”,“并發(fā)與并行” 協(xié)程的概念 協(xié)程(Coroutine)是一種用戶態(tài)的輕量級(jí)線程,不同于操作系統(tǒng)線程,協(xié)程能夠在單個(gè)線程中實(shí)現(xiàn)多任務(wù)并發(fā),使用更少的系統(tǒng)資源。協(xié)程的運(yùn)行由程序控制,不需要操作系統(tǒng)介入,因此協(xié)程之

    2024年02月08日
    瀏覽(31)
  • Go語言-無限可能的管道協(xié)程:解鎖并發(fā)編程的新境界

    在Go語言中,協(xié)程(Goroutine)是一種輕量級(jí)的并發(fā)執(zhí)行單位,它可以與其他協(xié)程并發(fā)執(zhí)行,但不同于操作系統(tǒng)級(jí)別的線程。Go語言的協(xié)程由Go運(yùn)行時(shí)(Go runtime)來調(diào)度,可以在相同的地址空間中并發(fā)執(zhí)行,并且具有非常小的切換開銷。 以下是一些關(guān)于Go協(xié)程的重要特點(diǎn)和用法:

    2024年01月24日
    瀏覽(20)
  • Go 語言實(shí)現(xiàn) MySQL 數(shù)據(jù)庫事務(wù)

    MySQL事務(wù)是指一組數(shù)據(jù)庫操作,它們被視為一個(gè)邏輯單元,并且要么全部成功執(zhí)行,要么全部回滾(撤銷)。事務(wù)是數(shù)據(jù)庫管理系統(tǒng)提供的一種機(jī)制,用于確保數(shù)據(jù)的一致性和完整性。 事務(wù)具有以下特性(通常由ACID原則定義): 原子性(Atomicity):事務(wù)中的所有操作要么全

    2024年02月08日
    瀏覽(21)
  • 使用go語言構(gòu)建區(qū)塊鏈 Part4.事務(wù)1

    使用go語言構(gòu)建區(qū)塊鏈 Part4.事務(wù)1

    英文源地址 事務(wù)是比特幣的核心, 區(qū)塊鏈的唯一目的是以安全可靠的方式存儲(chǔ)交易, 因此在交易創(chuàng)建后沒有人可以修改. 今天我們開始實(shí)現(xiàn)事務(wù), 但由于這是一個(gè)相當(dāng)大的主題, 我將它分成兩部分: 在這一部分中, 我們將實(shí)現(xiàn)事務(wù)的通用機(jī)制, 在第二部分中, 我們將研究細(xì)節(jié). 此外

    2024年02月06日
    瀏覽(18)
  • Go重寫Redis中間件 - Go實(shí)現(xiàn)Redis集群

    Go重寫Redis中間件 - Go實(shí)現(xiàn)Redis集群

    這章的內(nèi)容是將我們之前實(shí)現(xiàn)的單機(jī)版的Redis擴(kuò)充成集群版,給Redis增加集群功能,在增加集群功能之前,我們先學(xué)習(xí)一下在分布式系統(tǒng)中引用非常廣泛的技術(shù)一致性哈希,一致性哈希在我們項(xiàng)目里就應(yīng)用在我們Redis集群的搭建這塊 詳解一致性哈希 Redis集群需求背景 單臺(tái)服務(wù)

    2024年02月13日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包