佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 在Golang中使用Redis的方法示例

在Golang中使用Redis的方法示例

熱門標簽:呼叫中心市場需求 鐵路電話系統(tǒng) Linux服務器 AI電銷 網(wǎng)站排名優(yōu)化 百度競價排名 服務外包 地方門戶網(wǎng)站

周五上班的主要任務是在公司老平臺上用redis處理一個隊列問題,順便復習了一下redis操作的基礎知識,回來后就想著在自己的博客demo里,用redis來優(yōu)化一些使用場景,學習一下golang開發(fā)下redis的使用。

Redis簡單介紹

簡介

關于Redis的討論,其實在現(xiàn)在的后臺開發(fā)中已經(jīng)是個老生常談的問題,基本上也是后端開發(fā)面試的基本考察點。其中 Redis的背景介紹和細節(jié)說明在這里就不贅述。不管怎么介紹,核心在于Redis是一個基于內(nèi)存的key-value的多數(shù)據(jù)結構存儲,并可以提供持久化服務。基于內(nèi)存的特性決定了Redis天然適合高并發(fā)的數(shù)據(jù)讀寫緩存優(yōu)化,同時也帶來了內(nèi)存開銷過大的問題。所以在一些特定情景下,Redis是一把無往不利的大殺器,值得深入學習。

學習Redis的一個難點或者說入門點,我個人感覺在于對象存儲理念的轉變。剛接觸 Redis 時,我剛從大學畢業(yè),腦子里基本都是關系型數(shù)據(jù)存儲的理念,使用時總想著靠數(shù)據(jù)內(nèi)的關系來建立數(shù)據(jù)之間的聯(lián)系,用起來很不順手。后來慢慢入門了才感受到了一些操作的好處。舉個栗子,比如查詢用戶在某個文章下的評論,用 sql 的思路就是搜索評論表里面用戶ID和文章ID匹配的數(shù)據(jù),有時還需要聯(lián)合查詢出其他信息,但是如果是 Redis 操作,以'前綴:文章ID:用戶ID'為key,比如'comment:666:888'就可以快速取出用戶評論,十分方便。 Redis 的強大遠不僅如此,可以在實踐中慢慢體會。

主要數(shù)據(jù)結構

Redis主要有五種基本數(shù)據(jù)結構,滿足了絕大多數(shù)緩存結構的需要,如果你在使用一種結構存儲時感覺別扭時,很有可能是選錯了存儲結構,可以考慮一下其他結構的正確實現(xiàn)。

  1. String ,可以是字符串、整數(shù)和浮點數(shù)。如果是序列化數(shù)據(jù),并涉及到修改操作的話,不推薦用 string ,可以考慮用 Hash
  2. Hash, key-value 對象,可以存放對象數(shù)據(jù),比如用戶信息之類。
  3. List,有序數(shù)據(jù)集合,元素可以重復,用 LPUSH LPOP 、 RPUSH 、 RPOP 等指令組合可以實現(xiàn)棧和隊列操作。
  4. Set,無序集合,元素唯一。
  5. Sorted Set,Sort的有序版,可以設定 Score 值來決定元素排序,適合用戶排名這樣的業(yè)務場景。

常見使用場景

  1. 高并發(fā)下數(shù)據(jù)緩存。 比如在某個場景下,大量日志同時寫入數(shù)據(jù)庫會給服務器帶來巨大壓力,這時可以先將數(shù)據(jù)寫入 redis 中,再由 redis 寫入數(shù)據(jù)庫,減輕同時寫入壓力。
  2. 熱點信息快速顯示。假設現(xiàn)在有一個新聞首頁,需要快速顯示各欄目前20條熱點新聞,如果直接查詢數(shù)據(jù)庫,在大量用戶同時訪問下,會消耗極大數(shù)量的數(shù)據(jù)庫請求。這時就可以用 redis 來優(yōu)化,在新聞錄入的時候將標題、時間和來源寫入 redis 中,客戶端訪問時,可以從內(nèi)存中一次性取出當天熱單新聞列表,極大地提高請求速度和節(jié)約了服務器開銷。
  3. 保存會話信息??梢詫⒌卿浐笥脩粜畔⒕彺嫒?redis 并同時設置 key 過期時間,這樣后臺 api 過濾請求時,就可以從內(nèi)存中讀取用戶信息,而且 redis 的過期機制,天然支持用戶身份有效期校驗,用起來十分方便。
  4. 統(tǒng)計計數(shù)。比如系統(tǒng)中常見一個功能是限制同一用戶固定時間段內(nèi)的登錄次數(shù)或者所有請求次數(shù),這時就可以以用戶id為key,次數(shù)值為value,將計數(shù)信息緩存起來,并且有 INCRBY 命令原生支持。
  5. 其他。Redis的應用場景十分廣發(fā),隊列、發(fā)布訂閱、統(tǒng)計分析等等,可以看看其他文章的介紹說明。

Golang連接Redis

使用 Golang 開發(fā)的一大直觀感受就是,基本上你日常遇到的開發(fā)問題,都有官方或者第三方包幫你輔助實現(xiàn),同時這些包都是開源的,只要你感興趣,都可以深入到包的內(nèi)部實現(xiàn)去學習理解包的實現(xiàn)思路和方法。當然這也有利有弊,第三包的不穩(wěn)定和質量參差不齊也增加了一些開發(fā)成本,目前還是感受利大于弊。研究好的包源碼實現(xiàn),也是目前我的一個學習方向。

garyburd/redigo 包簡介

garyburd/redigo 包是網(wǎng)上很多博文都在推薦使用的一個高Star的 Redis 連接包,但是當我自己去 Github 的項目地址 garyburd/redigo 上查看 API 時,發(fā)現(xiàn)這個項目目前是歸檔狀態(tài),項目已經(jīng)遷移到了 gomodule/redigo ,同時包的獲取也理所當然地改成了 go get github.com/gomodule/redigo/redis ,這已經(jīng)不是我第一次感受了第三方包的不穩(wěn)定,之前用 dep 進行包管理時,就遇到過 dep 拉取的包版本和本地包版本 API 沖突的問題,這個有時間單獨再說??傊?,暫時不管這兩個包的詳細區(qū)別,以下就以新包為準,介紹下 redigo 包使用。

建立連接池

Redigo Pool 結構維護一個 Redis 連接池。應用程序調(diào)用 Get 方法從池中獲取連接,并使用連接的 Close 方法將連接的資源返回到池中。一般我們在系統(tǒng)初始化時聲明一個全局連接池,然后在需要操作 redis 時獲得連接,執(zhí)行指令。

pool := redis.Pool{
    MaxIdle:   3, /*最大的空閑連接數(shù)*/
    MaxActive:  8, /*最大的激活連接數(shù)*/
    Dial: func() (redis.Conn, error) {
      c, err := redis.Dial("tcp", '鏈接地址,例如127.0.0.1:6379', redis.DialPassword('密碼'))
      if err != nil {
        return nil, err
      }
      return c, nil
    }
}
c:=pool.Get()
defer c.Close()

執(zhí)行指令

查看源碼,發(fā)現(xiàn) Conn 接口有一個執(zhí)行 Redis 命令的通用方法:

```

//gomodule/redigo/redis/redis.go

// Conn represents a connection to a Redis server.

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)

// 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)
}

```

http://redis.io/commands 中的 Redis 命令參考列出了可用的命令。 do 的參數(shù)和 redis-cli 命令參數(shù)格式一致,比如 SET key value EX 360 對應函數(shù)調(diào)用為 Do("SET", "key", "value","EX",360) ,常用的命令示例有:

c:=pool.Get()
defer c.Close()
//存值,
_, err := c.Do("SET", "key", "value")
//設置過期時間
_, err := c.Do("SET", "key", "value","EX",360)
//存int
_, err := c.Do("SET", "key", 2)

//取值
v,err:=redis.String(c.Do("GET","key"))
bytes, err := redis.Bytes(c.Do("GET", "key"))

總結

golang 中連接使用 redis 相對比較簡單,所以暫時也沒什么其他好說的,如果后面自己使用過程中發(fā)現(xiàn)有遺漏再進行補充,關鍵還是在于熟悉 redis-cli 原生的指令操作。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Golang連接Redis數(shù)據(jù)庫的方法
  • Golang使用lua腳本實現(xiàn)redis原子操作
  • golang實現(xiàn)redis的延時消息隊列功能示例
  • Golang 實現(xiàn) Redis系列(六)如何實現(xiàn) pipeline 模式的 redis 客戶端

標簽:湖南 蘭州 衡水 銅川 黃山 崇左 湘潭 仙桃

巨人網(wǎng)絡通訊聲明:本文標題《在Golang中使用Redis的方法示例》,本文關鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    玉环县| 民乐县| 开封市| 双牌县| 孟津县| 灵璧县| 舞钢市| 康保县| 邵东县| 如皋市| 阿拉善左旗| 卓资县| 武鸣县| 大荔县| 怀化市| 正安县| 阿瓦提县| 德安县| 汕头市| 洞口县| 米易县| 资阳市| 西充县| 英德市| 襄城县| 桂阳县| 桂东县| 罗定市| 铜山县| 高陵县| 揭阳市| 静乐县| 黎平县| 靖江市| 图木舒克市| 滦平县| 株洲市| 合江县| 紫阳县| 略阳县| 乐都县|