我已閱讀了可在此處找到的整個Redigo文檔。 https://godoc.org/github.com/garyburd/redigo/redis#pkg-variables有關Redigo和併發性的一些問題
這裏的文檔明確指出連接不支持對Send(),Flush()或Receive()方法的併發調用。
連接不支持併發調用寫入方法 (發送,刷新)或併發調用讀取方法(接收)。 連接允許併發讀寫器。
然後它聲明由於Do方法可以是Send(),Flush()和Receive()的組合,所以我們不能同時使用Do()和其他方法。
因爲該做的方法將發送的功能,沖洗和 接收,該做的方法不能與其他 方法同時調用。
這是否意味着我們可以單獨使用存儲在全局變量中的單個連接同時使用Do(),只要我們不將它與其他方法混合?
例如像這樣:
var (
// Redis Conn.
redisConn redis.Conn
// Redis PubSubConn wraps a Conn with convenience methods for subscribers.
redisPsc redis.PubSubConn
)
func redisInit() {
c, err := redis.Dial(config.RedisProtocol, config.RedisAddress)
if err != nil {
log.Fatal(err)
}
c.Do("AUTH", config.RedisPass)
redisConn = c
c, err = redis.Dial(config.RedisProtocol, config.RedisAddress)
if err != nil {
log.Fatal(err)
}
c.Do("AUTH", config.RedisPass)
redisPsc = redis.PubSubConn{c}
for {
switch v := redisPsc.Receive().(type) {
case redis.Message:
// fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
socketHub.broadcast <- v.Data
case redis.Subscription:
// fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
case error:
log.Println(v)
}
}
}
,然後調用DO()方法中有些走程序是這樣的:
if _, err = redisConn.Do("PUBLISH", fmt.Sprintf("user:%d", fromId), message); err != nil {
log.Println(err)
}
if _, err = redisConn.Do("PUBLISH", fmt.Sprintf("user:%d", toId), message); err != nil {
log.Println(err)
}
再後來的文件說,爲滿併發訪問Redis,我們需要創建一個池並從池中獲取連接,並在完成後釋放它們。
這是否意味着我可以使用,發送(),同花順()和接收(),因爲我想,只要我從池中的連接?換句話說,每次我需要在去例行程序中執行某些操作時,我必須從池中獲取新連接,而不是重新使用全局連接?這是否意味着只要我從池中獲得一個新的連接,就可以將Do()方法用於例如Send()?
所以總結起來:
1)我可以同時使用DO()方法,只要我不發送使用它,同花順和接收方法呢?
2)我可以使用一切,我想只要我從池中獲取一個新的連接,並釋放它,當我做了什麼?
3)如(1)爲真,這是否會影響性能?在我提供的例子中,只使用Do()方法併發使用全局連接,而不是將Sending,Flush和Receive混合起來更好嗎?
我同時運行redisInit(),像「go redisInit()」,我有兩個連接。一個redisConn redis.Conn執行發佈命令一個redisPsc redis.PubSubConn來訂閱和取消訂閱。 – Alex
查看更新的答案。 –
我目前沒有使用池。但是,如果我理解正確,我不能使用Do()來發布內容,因爲當我發佈內容時,我也同時收到相同的命令? – Alex