十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了永城免費(fèi)建站歡迎大家使用!
redis
是一個(gè)key-value存儲(chǔ)系統(tǒng)。和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。
【1】案例一現(xiàn)象:
生產(chǎn)系統(tǒng)剛開始運(yùn)行階段,系統(tǒng)穩(wěn)定。但是運(yùn)行了一段時(shí)間后,發(fā)現(xiàn)部分時(shí)間段系統(tǒng)接口響應(yīng)變慢。查看客戶端日志經(jīng)常會(huì)出現(xiàn)如下錯(cuò)誤:
redis.clients.jedis.exception.JedisConnectionException:java.net.SocketTimeoutException:Read time out
問(wèn)題定位:執(zhí)行 slowlog 查看慢查詢?nèi)罩?,發(fā)現(xiàn)大量的 keys 命令操作,keys 命令在大量并發(fā)情況下性能非常差,生產(chǎn)環(huán)境,盡量避免使用 keys,接下來(lái)找出使用 keys 的代碼做優(yōu)化,直到 time out 問(wèn)題解決。
192.168.17.46:6386> slowlog get
1) 1) (integer) 22
2) (integer) 1563344158
3) (integer) 10193
4) 1) "SET"
2) "getBatchChapterFiles"
3) "\x0b\xfa\529:\t489761532B\x02-1J\t48976181... (1293 more bytes)"
2) 1) (integer) 21
2) (integer) 1545403066
3) (integer) 10915
4) 1) "GET"
2) "getVolumeChapters#data"【2】案例二現(xiàn)象:
生產(chǎn)環(huán)境長(zhǎng)時(shí)間的運(yùn)行后,經(jīng)常會(huì)有接口返回?cái)?shù)據(jù)失敗的情況,或者是從監(jiān)控上發(fā)現(xiàn)數(shù)據(jù)庫(kù)壓力某一時(shí)間暴增。查看客戶端日志發(fā)現(xiàn)如下錯(cuò)誤:
redis.clients.jedis.exceptions.JedisConnectionException:Cloud not get a resource from the pool
在redis日志里面發(fā)現(xiàn)報(bào)錯(cuò):
[2489] 02 Jun 10:43:42 # Error allocating resoures for the client
問(wèn)題定位:執(zhí)行 client list 命令,發(fā)現(xiàn)大量的 client 的 idle 時(shí)間特別長(zhǎng)。檢查配置發(fā)現(xiàn) timeout 和 tcp-keepalive(心跳檢測(cè)) 均為啟用(均為0),Redis 服務(wù)端沒(méi)有有效的機(jī)制來(lái)確保服務(wù)端連接是否已經(jīng)失效。當(dāng)服務(wù)器與客戶端網(wǎng)絡(luò)發(fā)生閃斷,導(dǎo)致tcp中斷,這種情況下的 client 將會(huì)一直被 redis 服務(wù)端所持有,就會(huì)出現(xiàn) idle(空閑)時(shí)間特長(zhǎng)的 client 連接。
解決辦法:設(shè)置 timeout 和 tcp-keepalive 來(lái)清理失效的連接。
redis/bin>redis-cli -h 192.168.17.46 -p 6386 info Clients
# Clients
connected_clients:5000 ---------------偏大
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
192.168.17.46:6386> CONFIG GET timeout
1) "timeout"
2) "0"
192.168.17.46:6386> CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "0"192.168.17.46:6386> client list
id=612260747 addr=192.168.17.92:53069 fd=806 name= age=114 idle=21 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=ping
id=612260593 addr=192.168.41.44:38248 fd=381 name= age=131 idle=61 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get字段定義
addr : 客戶端的地址和端口
fd : 套接字所使用的文件描述符
age : 以秒計(jì)算的已連接時(shí)長(zhǎng)
idle : 以秒計(jì)算的空閑時(shí)長(zhǎng)
flags : 客戶端 flag
db : 該客戶端正在使用的數(shù)據(jù)庫(kù) ID
sub : 已訂閱頻道的數(shù)量
psub : 已訂閱模式的數(shù)量
multi : 在事務(wù)中被執(zhí)行的命令數(shù)量
qbuf : 查詢緩沖區(qū)的長(zhǎng)度(字節(jié)為單位, 0 表示沒(méi)有分配查詢緩沖區(qū))
qbuf-free : 查詢緩沖區(qū)剩余空間的長(zhǎng)度(字節(jié)為單位, 0 表示沒(méi)有剩余空間)
obl : 輸出緩沖區(qū)的長(zhǎng)度(字節(jié)為單位, 0 表示沒(méi)有分配輸出緩沖區(qū))
oll : 輸出列表包含的對(duì)象數(shù)量(當(dāng)輸出緩沖區(qū)沒(méi)有剩余空間時(shí),命令回復(fù)會(huì)以字符串對(duì)象的形式被入隊(duì)到這個(gè)隊(duì)列里)
omem : 輸出緩沖區(qū)和輸出列表占用的內(nèi)存總量
events : 文件描述符事件
cmd : 最近一次執(zhí)行的命令
【3】案例三現(xiàn)象:
Redis 突然間不能訪問(wèn),返回如下錯(cuò)誤:
redis.client.jedis.exception.JedisDataException:MISCONF Redis is configured to save RDB snapshots,
but is currently not able to persist on disk.Commands that may modify the data set are disabled.
Please check Redis logs for details about the error
問(wèn)題定位:查看 redis 日志,發(fā)現(xiàn)如下錯(cuò)誤:Cant save in background:fork:Cannot allocate memory Redis在保存內(nèi)存的數(shù)據(jù)到磁盤時(shí),為了防止主線程假死,會(huì)Fork 一個(gè)子進(jìn)程來(lái)完成這個(gè)保存操作,這個(gè)Fork 的子進(jìn)程需要分配與主進(jìn)程相同的內(nèi)存,這時(shí)候就相當(dāng)于需要的內(nèi)存翻倍了。如果這時(shí)候可用內(nèi)存不足以分配需要的內(nèi)存,將會(huì)導(dǎo)致Fork 子進(jìn)程失敗而無(wú)法將數(shù)據(jù)持久化到磁盤。修改Linux內(nèi)核參數(shù) vm.overcommit_memeory=1(表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當(dāng)前的內(nèi)存狀態(tài)如何) 問(wèn)題便可解決。
192.168.17.46:6386> CONFIG GET logfile
1) "logfile"
2) "/home/redis02/redis/log/6386.log"