在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費注冊]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>數(shù)值算法/人工智能>

關(guān)于 Redis連接池解析

大小:0.4 MB 人氣: 2017-10-12 需要積分:1
 一、關(guān)于連接池
  一個數(shù)據(jù)庫服務(wù)器只擁有有限的資源,并且如果你沒有充分使用這些資源,你可以通過使用更多的連接來提高吞吐量。一旦所有的資源都在使用,那么你就不能通過增加更多的連接來提高吞吐量。事實上,吞吐量在連接負載較大時就開始下降了。通常可以通過限制與可用的資源相匹配的數(shù)據(jù)庫連接的數(shù)量來提高延遲和吞吐量。
  如果不使用連接池,那么,每次傳輸數(shù)據(jù),我們都需要進行創(chuàng)建連接,收發(fā)數(shù)據(jù),關(guān)閉連接。在并發(fā)量不高的場景,基本上不會有什么問題,一旦并發(fā)量上去了,那么,一般就會遇到下面幾個常見問題:
  性能普遍上不去CPU 大量資源被系統(tǒng)消耗網(wǎng)絡(luò)一旦抖動,會有大量 TIME_WAIT 產(chǎn)生,不得不定期重啟服務(wù)或定期重啟機器服務(wù)器工作不穩(wěn)定,QPS 忽高忽低
  要想解決這些問題,我們就要用到連接池了。連接池的思路很簡單,在初始化時,創(chuàng)建一定數(shù)量的連接,先把所有長連接存起來,然后,誰需要使用,從這里取走,干完活立馬放回來。 如果請求數(shù)超出連接池容量,那么就排隊等待、退化成短連接或者直接丟棄掉。
  二、使用連接池遇到的坑
  最近在一個項目中,需要實現(xiàn)一個簡單的 Web Server 提供 Redis 的 HTTP interface,提供 JSON 形式的返回結(jié)果。考慮用 Go 來實現(xiàn)。
  首先,去看一下 Redis 官方推薦的 Go Redis driver。官方 Star 的項目有兩個:Radix.v2 和 Redigo。經(jīng)過簡單的比較后,選擇了更加輕量級和實現(xiàn)更加優(yōu)雅的 Radix.v2。
  Radix.v2 包是根據(jù)功能劃分成一個個的 sub package,每一個 sub package 在一個獨立的子目錄中,結(jié)構(gòu)非常清晰。我的項目中會用到的 sub package 有 redis 和 pool。
  由于我想讓這種被 fork 的進程最好簡單點,做的事情單一一些,所以,在沒有深入去看 Radix.v2 的 pool 的實現(xiàn)之前,我選擇了自己實現(xiàn)一個 Redis pool。(這里,就不貼代碼了。后來發(fā)現(xiàn)自己實現(xiàn)的 Redis pool 與 Radix.v2 實現(xiàn)的 Redis pool 的原理是一樣的,都是基于 channel 實現(xiàn)的, 遇到的問題也是一樣的。)
  不過在測試過程中,發(fā)現(xiàn)了一個詭異的問題。在請求過程中經(jīng)常會報 EOF 錯誤。而且是概率性出現(xiàn),一會有問題,一會又好了。通過反復的測試,發(fā)現(xiàn) bug 是有規(guī)律的,當程序空閑一會后,再進行連續(xù)請求,會發(fā)生3次失敗,然后之后的請求都能成功,而我的連接池大小設(shè)置的是3。再進一步分析,程序空閑300秒后,再請求就會失敗,發(fā)現(xiàn)我的 Redis server 配置了 timeout 300,至此,問題就清楚了。是連接超時 Redis server 主動斷開了連接。客戶端這邊從一個超時的連接請求就會得到 EOF 錯誤。
  然后我看了一下 Radix.v2 的 pool 包的源碼,發(fā)現(xiàn)這個庫本身并沒有檢測壞的連接,并替換為新的連接的機制。也就是說我每次從連接池里面 Get 的連接有可能是壞的連接。所以,我當時臨時的解決方案是通過增加失敗后自動重試來解決了。不過,這樣的處理方案,連接池的作用好像就沒有了。技術(shù)債能早點還的還是早點還上。
  三、使用連接池的正確姿勢
  想到我們的 ngx_lua 項目里面也大量使用 redis 連接池,他們怎么沒有遇到這個問題呢。只能去看看源碼了。
  經(jīng)過抽象分離, ngx_lua 里面使用 redis 連接池部分的代碼大致是這樣的:
  server { location /pool { content_by_lua_block { localredis = require“resty.redis”localred = redis:new() localok, err = red:connect(“127.0.0.1”, 6379) ifnotok thenngx.say(“failed to connect: ”, err) returnendok, err = red:set(“hello”, “world”) ifnotok thenreturnendred:set_keepalive(10000, 100) } } }
  發(fā)現(xiàn)有個 set_keepalive 的方法,查了一下官方文檔,方法的原型是 syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size) 貌似 max_idle_timeout 這個參數(shù),就是我們所缺少的東西,然后進一步跟蹤源碼,看看里面是怎么保證連接有效的。
  function_M.set_keepalive(self, 。..) local sock = self.sock ifnot sock then returnnil, “not initialized”end ifself.subscribed then returnnil, “subscribed state”end returnsock:setkeepalive(。..) end
  至此,已經(jīng)清楚了,使用了 tcp 的 keepalive 心跳機制。
  于是,通過與 Radix.v2 的作者一些討論,選擇自己在 redis 這層使用心跳機制,來解決這個問題。
  四、最后的解決方案
  在創(chuàng)建連接池之后,起一個 goroutine,每隔一段 idleTime 發(fā)送一個 PING 到 Redis server。其中,idleTime 略小于 Redis server 的 timeout 配置。
  連接池初始化部分代碼如下:
  p, err:= pool.New(“tcp”, u.Host, concurrency) errHndlr(err) go func() { for{ p.Cmd(“PING”) time.Sleep(idelTime * time.Second) } }()
  使用 redis 傳輸數(shù)據(jù)部分代碼如下:
  func redisDo(p *pool.Pool, cmd string, args 。..interface{}) (reply *redis.Resp, errerror) { reply = p.Cmd(cmd, args.。.) iferr= reply.Err; err!= nil { iferr!= io.EOF { Fatal.Println(“redis”, cmd, args, “err is”, err) } } return }
  其中,Radix.v2 連接池內(nèi)部進行了連接池內(nèi)連接的獲取和放回,代碼如下:
  // Cmd automatically gets oneclient fromthepool, executes thegiven command// (returning its result), and puts the client back in the poolfunc (p *Pool) Cmd(cmd string, args 。..interface{}) *redis.Resp { c, err := p.Get() iferr != nil { returnredis.NewResp(err) } defer p.Put(c) returnc.Cmd(cmd, args.。.) }
  這樣,我們就有了 keepalive 的機制,不會出現(xiàn) timeout 的連接了,從 redis 連接池里面取出的連接都是可用的連接了。看似簡單的代碼,卻完美的解決了連接池里面超時連接的問題。同時,就算 Redis server 重啟等情況,也能保證連接自動重連。
?

非常好我支持^.^

(1) 100%

不好我反對

(0) 0%

關(guān)于 Redis連接池解析下載

相關(guān)電子資料下載

      發(fā)表評論

      用戶評論
      評價:好評中評差評

      發(fā)表評論,獲取積分! 請遵守相關(guān)規(guī)定!

      ?
      主站蜘蛛池模板: 久久伊人草| 国产精品毛片在线大全| 视频h在线观看| 夜夜骑夜夜操| 精品国产一二三区在线影院| 五月在线观看| 欧美黄色录象| 777奇米影视一区二区三区| 欧美精品二区| 婷婷免费高清视频在线观看| 亚洲成人网页| 无遮挡很污很爽很黄的网站| 天天操操操操| 亚洲国产第一区二区香蕉| 狠狠涩| 欧美一区二区三区性| 婷婷天堂| 日本理论片www视频| 色香视频首页| 亚洲狠狠操| 91福利视频网站| 美女免费视频一区二区三区| xxxx日本69xxxxx| 国产福利免费观看| 免费又爽又黄1000禁片| 天天看天天操| 天天撸视频| 国产精品看片| 成人午夜免费剧场| 国产手机在线看片| 国产免费爽爽视频免费可以看| 黄色网免费| 一级毛片一级黄片| 一级欧美一级日韩| 色婷婷综合网| 国产一区二区高清在线| 国产专区视频| 国产成人教育视频在线观看| 国产成人精品日本| 色天天综合网| 加勒比啪啪|