大部分互聯網公司都會有Mysql或者Oracle的DBA,可是在Nosql方面通常不會設置專門的DBA。不過對於一些知名的互聯網公司來講,Nosql的使用量是巨大的,因此一般讓Mysql的DBA或者單獨聘請工程師來維護一些Nosql數據庫,好比:java
Redis, Hbase, Memcache(其實嚴格講不是nosql), Mongodb, Cassandra。從講座看美團網應該是有專職的Redis DBA。因此做爲業務開發人員不須要本身安裝、配置、運維Redis,只須要找Redis DBA來申請就能夠了。mysql
這裏爲了簡化說明:Redis DBA提供的服務叫作Redis雲,業務開發人員叫作業務端(redis的使用者)redis
業務端在使用redis雲提供的redis服務後,常常出現connect timeout:sql
#java代碼 redis.clients.jedis.exceptions.JedisConnectionException java.net.SocketException java.net.SocketTimeoutException:connect time out
業務端通常認爲redis出現問題,就是redis雲有問題,人的「正常」思惟:看別人錯誤容易,發現本身難,扯多了, 出現這個有不少緣由:數據庫
(1). 網絡緣由:好比是否存在跨機房、網絡割接等等。服務器
(2). 慢查詢,由於redis是單線程,若是有慢查詢的話,會阻塞住以後的操做。 網絡
(3). value值過大?好比value幾十兆,固然這種狀況比較少,其實也能夠看作是慢查詢的一種運維
(4). aof重寫/rdb fork發生?瞬間會堵一下Redis服務器。nosql
(5). 其餘..................tcp
演講者一開始懷疑是網絡問題,可是並未發現問題,觀察各類對比圖表,tcp listenOverFlow和timeout常常週期出現。(贊一下這個監控,咱們監控如今尚未這個層面的)
有關listenOverFlow:
查看現有的鏈接數是否大於設置的backlog,若是大於就丟棄,並相應的參數值加1。其中backlog是由程序和系統參數net.core.somaxconn共同設置,當backlog的值大於系統設置的net.core.somaxconn時則取net.core.somaxconn的值,不然取程序設置的backlog值。這種出錯的方式也被記錄在TcpListenOverflows中(其只記錄了鏈接個數不足而產生溢出錯誤的次數!)。
以爲可能和TCP相關,因而分析了Tcp三次握手:最後一次握手客戶端的請求會進入服務器端的一個隊列(能夠認爲是下三圖)中,若是這個隊列滿了,就會發生上面的異常。(accept)
(1) TCP三次握手:
(2) redis客戶端與redis服務器交互的過程(本質就是TCP請求)
(3) I/O 多路複用程序經過隊列向文件事件分派器傳送套接字的過程
(4) 和redis有什麼關係呢?
因爲Redis的單線程模型(對命令的處理和鏈接的處理都是在一個線程中),若是存在慢查詢的話,會出現上面的這種狀況,形成新的accept的鏈接進不了隊列。
一、對慢查詢進行持久化,好比定時存放到mysql之類。(redis的慢查詢只是一個list,超過list設置的最大值,會清除掉以前的數據,也就是看不到歷史)
二、對慢查詢進行報警(頻率、數量、時間)等等因素
三、其實應該作的是:對業務端進行培訓,告訴他們一下redis開發的坑,redis不是萬金油,這個和Mysql DBA要培訓Mysql使用者同樣,不然防不勝防。好比他執行了 monitor, keys *, flushall, drop table, update table set a=1; 這種也是防不勝防的(固然也能夠作限制,利用rename-command一個隨機數),可是提升工程師的水平纔是關鍵。