環(huán)境配置避坑指南)
1. 裝之前先把這幾件事想明白標(biāo)題叫“Linux安裝redis”但真正做過(guò)生產(chǎn)環(huán)境部署的人都知道安裝本身五分鐘能搞定真正拉開(kāi)差距的是裝之前的思路。Redis這種內(nèi)存型鍵值數(shù)據(jù)庫(kù)安裝方式、配置參數(shù)、啟動(dòng)方式、安全策略每一步都直接決定它在你機(jī)器上能不能穩(wěn)定跑、能不能扛住業(yè)務(wù)流量。這篇內(nèi)容適合誰(shuí)剛接觸Linux服務(wù)器、準(zhǔn)備給項(xiàng)目配緩存的開(kāi)發(fā)者或者已經(jīng)裝過(guò)Redis但想搞清楚配置細(xì)節(jié)、避免踩坑的運(yùn)維新手。我會(huì)把完整的安裝流程、關(guān)鍵參數(shù)、常見(jiàn)坑和排查思路都過(guò)一遍盡量讓你看完就能照著操作。先說(shuō)句實(shí)在話不同Linux發(fā)行版、不同Redis版本、不同業(yè)務(wù)場(chǎng)景安裝細(xì)節(jié)會(huì)有差異。我這里以最常用的CentOS 7/8系和Ubuntu 20.04/22.04系為例版本選擇Redis 6.x/7.x穩(wěn)定版。你機(jī)器上如果環(huán)境不同原理是通用的操作上靈活調(diào)整就行。2. 安裝方式怎么選這是個(gè)判斷題Redis在Linux上的安裝方式主流就三種包管理器安裝、源碼編譯安裝、Docker容器安裝。沒(méi)有絕對(duì)的好壞全看你的場(chǎng)景。2.1 包管理器安裝快但版本由不得你CentOS用yum、Ubuntu用apt直接一條命令就能裝好。優(yōu)點(diǎn)是快、省事、自帶systemd服務(wù)管理。缺點(diǎn)也很明顯——版本往往偏舊而且有時(shí)候莫名裝出來(lái)的是閹割版。比如CentOS默認(rèn)源里的redis版本可能停留在3.x連多線程IO都沒(méi)有性能瓶頸明顯很多新特性也用不上。如果你只是本地開(kāi)發(fā)、測(cè)試功能包管理器裝一下完全夠用。在生產(chǎn)環(huán)境尤其是對(duì)版本有要求或者需要特定編譯參數(shù)的時(shí)候我一般不建議走這條路。還有一個(gè)坑某些源里裝出來(lái)的Redis缺少systemd集成你想用systemctl管理還得自己寫service文件反而更麻煩。2.2 源碼編譯安裝最穩(wěn)也最可控這是我最常用的方式。從官網(wǎng)下載源碼包自己編譯、自己安裝、自己配置。好處在于版本完全可控Redis 7.x新特性想用就用。編譯參數(shù)可定制比如指定安裝路徑、開(kāi)啟特定優(yōu)化。二進(jìn)制文件在自己手里出了問(wèn)題好排查。缺點(diǎn)也很直接需要gcc等編譯工具編譯要花一兩分鐘對(duì)新手來(lái)說(shuō)過(guò)程顯得“重”。但說(shuō)實(shí)話多敲幾行命令換來(lái)完全掌控權(quán)這筆賬是劃算的。下面我會(huì)詳細(xì)介紹這種方式。2.3 Docker安裝隔離干凈但不是萬(wàn)能Docker跑Redis最大的優(yōu)勢(shì)是環(huán)境隔離、部署快速、版本切換方便。測(cè)試環(huán)境臨時(shí)起一個(gè)實(shí)例docker run后面加幾個(gè)參數(shù)就完事。但生產(chǎn)環(huán)境用Docker跑Redis有幾個(gè)問(wèn)題你得想清楚數(shù)據(jù)持久化要掛載目錄配置不好數(shù)據(jù)說(shuō)沒(méi)就沒(méi)。網(wǎng)絡(luò)模式要選對(duì)不然性能有損耗。容器重啟策略要設(shè)置好不然宕機(jī)后不會(huì)自動(dòng)拉起。內(nèi)存監(jiān)控、日志收集都比裸機(jī)部署麻煩一些。所以我的建議是開(kāi)發(fā)測(cè)試用Docker確實(shí)香生產(chǎn)環(huán)境能裸機(jī)部署就裸機(jī)部署。當(dāng)然如果你公司基礎(chǔ)設(shè)施已經(jīng)全面容器化運(yùn)維體系成熟那另當(dāng)別論。3. 源碼編譯安裝的完整實(shí)操記錄這里我走一遍完整過(guò)程用的環(huán)境是CentOS 7.9Redis版本選擇當(dāng)前穩(wěn)定版7.0.x。整個(gè)過(guò)程我會(huì)把命令、參數(shù)、為什么這么做的原因都寫清楚。3.1 第一步裝編譯環(huán)境Redis是用C語(yǔ)言寫的源碼編譯必須要有g(shù)cc編譯器。另外make的時(shí)候需要用到一些基礎(chǔ)工具一并裝上。yum install -y gcc gcc-c make tclUbuntu/Debian系對(duì)應(yīng)的是apt update apt install -y build-essential tcl這里有個(gè)細(xì)節(jié)需要注意某些云廠商的CentOS鏡像里gcc版本特別老編譯Redis 7.x可能會(huì)報(bào)錯(cuò)提示你的gcc版本過(guò)低。遇到這種情況需要先升級(jí)gcc或者用scl源裝新版gcc具體后面排查章節(jié)會(huì)說(shuō)。3.2 第二步下載并解壓源碼包源碼包去Redis官網(wǎng)下載就行。我習(xí)慣先下載到/usr/local/src目錄統(tǒng)一管理源碼包位置。cd /usr/local/src wget https://download.redis.io/releases/redis-7.0.14.tar.gz tar xzf redis-7.0.14.tar.gz cd redis-7.0.14下載鏈接里的版本號(hào)建議先去官網(wǎng)查一下當(dāng)前推薦的最新穩(wěn)定版。別像我之前有一次想當(dāng)然用了7.0.0結(jié)果編譯到一半發(fā)現(xiàn)有個(gè)已知bug在后續(xù)patch版本才修復(fù)又得重新下時(shí)間都浪費(fèi)了。3.3 第三步編譯并安裝make -j$(nproc) make install PREFIX/usr/local/redis第二行命令的PREFIX參數(shù)指定了Redis安裝目錄。如果不指定默認(rèn)會(huì)裝到/usr/local/bin下面bin文件散落在系統(tǒng)路徑里后續(xù)管理比較混亂。指定到獨(dú)立目錄比如/usr/local/redis所有相關(guān)文件都在這一畝三分地里卸載也簡(jiǎn)單整個(gè)目錄刪掉就行。make -j$(nproc)中的-j參數(shù)表示并行編譯$(nproc)自動(dòng)取CPU核數(shù)編譯速度快很多。在一臺(tái)8核機(jī)器上Redis編譯基本一分鐘出頭就完事。編譯過(guò)程偶爾會(huì)報(bào)錯(cuò)最常見(jiàn)的是jemalloc相關(guān)的問(wèn)題。這是Redis的內(nèi)存分配器如果不兼容當(dāng)前系統(tǒng)環(huán)境需要在make時(shí)指定用libc mallocmake MALLOClibc -j$(nproc)什么時(shí)候會(huì)碰到這種情況常見(jiàn)于某些老版本gcc搭配新系統(tǒng)或者在某些ARM架構(gòu)的機(jī)器上。具體原因后面排查部分展開(kāi)。3.4 第四步驗(yàn)證安裝結(jié)果/usr/local/redis/bin/redis-server --version能輸出版本號(hào)安裝就算成功了。此時(shí)Redis二進(jìn)制文件在/usr/local/redis/bin/目錄下但配置文件還沒(méi)準(zhǔn)備好Redis現(xiàn)在跑起來(lái)用的全是默認(rèn)配置監(jiān)聽(tīng)127.0.0.1、無(wú)密碼、不持久化——這顯然不是生產(chǎn)環(huán)境想要的狀態(tài)下一步就是配置。4. 配置文件的四個(gè)關(guān)鍵維度Redis安裝完只是起點(diǎn)配置才是重頭戲。我把配置文件里最關(guān)鍵的幾個(gè)方面拆開(kāi)講每一項(xiàng)都解釋為什么這樣配。4.1 網(wǎng)絡(luò)與訪問(wèn)控制bind、port、protected-modeRedis默認(rèn)只監(jiān)聽(tīng)本機(jī)回環(huán)地址127.0.0.1也就是只有本機(jī)能連。如果你需要讓其他服務(wù)器訪問(wèn)——比如應(yīng)用服務(wù)器和Redis不在同一臺(tái)機(jī)器上——必須修改bind配置bind 0.0.0.0意思是監(jiān)聽(tīng)所有網(wǎng)卡接口。這里必須潑一盆冷水bind 0.0.0.0和protected-mode no組合起來(lái)等于把Redis裸奔在公網(wǎng)上。如果有人掃描到你的6379端口而Redis沒(méi)有密碼惡意者可以直接讀寫你的緩存數(shù)據(jù)甚至通過(guò)Redis寫文件功能拿下服務(wù)器。這不是危言聳聽(tīng)網(wǎng)上被刷的案例一抓一大把。安全的做法是bind指定內(nèi)網(wǎng)IP不要用0.0.0.0。requirepass設(shè)置強(qiáng)密碼長(zhǎng)度不少于16位字母數(shù)字特殊字符混搭。云服務(wù)器安全組、防火墻層面只對(duì)需要的IP放行6379端口。有條件就用Redis自帶ACL功能給不同業(yè)務(wù)分配不同權(quán)限賬號(hào)。protected-mode這個(gè)參數(shù)要重點(diǎn)說(shuō)。默認(rèn)值是yes含義是如果Redis沒(méi)有設(shè)置密碼并且沒(méi)有顯式bind到具體非回環(huán)地址那么只有本機(jī)能訪問(wèn)。一旦你配置了bind為0.0.0.0或某個(gè)具體IPprotected-mode就會(huì)失去保護(hù)作用。所以保護(hù)模式的本質(zhì)是個(gè)“保險(xiǎn)絲”而不是安全屏障真正扛事的是密碼和防火墻。# 配置示例 bind 10.0.0.5 port 6379 protected-mode yes requirepass YourStrongPassword123!4.2 持久化機(jī)制RDB和AOF怎么選Redis數(shù)據(jù)在內(nèi)存里一旦進(jìn)程退出或者機(jī)器宕機(jī)內(nèi)存數(shù)據(jù)就沒(méi)了。要恢復(fù)必須靠持久化。Redis提供了兩種持久化方式標(biāo)配是RDB和AOF同時(shí)啟用雙保險(xiǎn)。先看RDB全稱Redis DataBase本質(zhì)是定期把內(nèi)存數(shù)據(jù)全量快照到磁盤的dump.rdb文件。默認(rèn)配置長(zhǎng)這樣save 900 1 save 300 10 save 60 10000意思是900秒內(nèi)有1次寫入就觸發(fā)快照300秒內(nèi)有10次寫入就觸發(fā)60秒內(nèi)有10000次寫入就觸發(fā)。這種寫法的妙處在于按頻率動(dòng)態(tài)調(diào)整快照節(jié)奏避免頻繁全量寫盤。RDB的優(yōu)點(diǎn)是最多丟幾十秒的數(shù)據(jù)、恢復(fù)速度快缺點(diǎn)是快照生成瞬間會(huì)fork子進(jìn)程內(nèi)存占用短暫翻倍而且兩次快照之間的數(shù)據(jù)說(shuō)丟就丟。再看AOF全稱Append Only File記錄每一次寫操作以日志形式追加到aof文件里。默認(rèn)配置appendonly yes appendfsync everysecappendfsync有三個(gè)取值always每次寫操作都刷盤不丟數(shù)據(jù)但性能最差。everysec每秒刷一次盤最多丟一秒數(shù)據(jù)性能和可靠性平衡。no交給操作系統(tǒng)刷盤性能最好但可能丟更多數(shù)據(jù)。生產(chǎn)環(huán)境建議everysec兼顧性能和數(shù)據(jù)安全。AOF文件會(huì)越來(lái)越大所以需要重寫策略auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb意思是AOF文件比上次重寫時(shí)增長(zhǎng)超過(guò)100%且文件至少64MB時(shí)自動(dòng)觸發(fā)重寫壓縮日志體積。我用一個(gè)表格把兩種持久化方式對(duì)比清楚方便你根據(jù)業(yè)務(wù)取舍對(duì)比維度RDBAOF數(shù)據(jù)恢復(fù)速度快慢數(shù)據(jù)丟失風(fēng)險(xiǎn)較高取決于快照頻率低取決于fsync策略文件大小小大對(duì)性能影響快照f(shuō)ork時(shí)較明顯寫日志有IO開(kāi)銷適用場(chǎng)景緩存、可接受少量丟數(shù)據(jù)對(duì)數(shù)據(jù)一致性要求高的業(yè)務(wù)我的建議是默認(rèn)兩者都開(kāi)。Redis重啟時(shí)優(yōu)先加載AOF因?yàn)锳OF數(shù)據(jù)更完整。如果對(duì)丟數(shù)據(jù)容忍度高、追求極致性能可以只開(kāi)RDB如果對(duì)數(shù)據(jù)安全要求極高可以只開(kāi)AOF甚至用always刷盤但要做好性能下降的評(píng)估。4.3 內(nèi)存與淘汰策略maxmemory和maxmemory-policyRedis內(nèi)存不是無(wú)限大的必須設(shè)置上限否則內(nèi)存泄漏或者數(shù)據(jù)膨脹能把整臺(tái)機(jī)器撐爆。這里有個(gè)常見(jiàn)的錯(cuò)誤認(rèn)知以為不設(shè)置maxmemoryRedis就用不完內(nèi)存。實(shí)際上操作系統(tǒng)有OOM Killer機(jī)制進(jìn)程內(nèi)存超過(guò)物理內(nèi)存時(shí)可能被直接殺掉。所以設(shè)置內(nèi)存上限是保命動(dòng)作。maxmemory 2gb maxmemory-policy allkeys-lrumaxmemory指定最大內(nèi)存可以寫成 512mb、2gb 等。maxmemory-policy指定內(nèi)存達(dá)到上限后的淘汰策略常見(jiàn)的有volatile-lru從設(shè)置了過(guò)期時(shí)間的數(shù)據(jù)中淘汰最近最少使用的。allkeys-lru從所有數(shù)據(jù)中淘汰最近最少使用的。volatile-ttl從設(shè)置了過(guò)期時(shí)間的數(shù)據(jù)中淘汰剩余存活時(shí)間最短的。volatile-random從設(shè)置了過(guò)期時(shí)間的數(shù)據(jù)中隨機(jī)淘汰。allkeys-random從所有數(shù)據(jù)中隨機(jī)淘汰。noeviction不淘汰內(nèi)存滿了直接拒絕寫入返回錯(cuò)誤。生產(chǎn)環(huán)境最常用的是allkeys-lru適合緩存場(chǎng)景——不重要的數(shù)據(jù)優(yōu)先被淘汰。如果是會(huì)話存儲(chǔ)、分布式鎖這種不能丟關(guān)鍵數(shù)據(jù)的場(chǎng)景用noeviction更安全寧可寫入失敗也不丟數(shù)據(jù)。這里還有一個(gè)重要認(rèn)知Redis在64位系統(tǒng)上maxmemory不設(shè)置時(shí)理論上可用內(nèi)存接近無(wú)窮大但這不是好事。比如你的緩存key沒(méi)有設(shè)置過(guò)期時(shí)間寫入量一直增長(zhǎng)Redis內(nèi)存就會(huì)一路飆升直到系統(tǒng)swap、性能雪崩、進(jìn)程被殺。我的習(xí)慣是每臺(tái)Redis實(shí)例的maxmemory設(shè)置為物理內(nèi)存的60%-70%留出余量給系統(tǒng)和其他進(jìn)程。4.4 日志與安全加固logfile、slowlog、ACL默認(rèn)Redis日志是輸出到stdout的也就是說(shuō)前臺(tái)啟動(dòng)時(shí)打印在終端用systemd或后臺(tái)啟動(dòng)時(shí)輸出到j(luò)ournald。要把它寫到文件里logfile /usr/local/redis/logs/redis.log注意日志目錄要先創(chuàng)建Redis不會(huì)自動(dòng)建目錄。有幾個(gè)版本竟然DIRECTORY不存在直接啟動(dòng)失敗或者啟動(dòng)成功但日志丟失排查起來(lái)特別鬧心。后來(lái)我養(yǎng)成了習(xí)慣裝完Redis第一件事就是把logs目錄建好。慢查詢?nèi)罩疽彩桥挪閱?wèn)題的一把利器slowlog-log-lower-than 10000 slowlog-max-len 128意思是超過(guò)10毫秒的命令都會(huì)被記錄下來(lái)最多保留128條。線上事故排查時(shí)SLOWLOG GET一下慢命令無(wú)所遁形。Redis 6.0之后引入的ACL功能顛覆了以前“一個(gè)密碼走天下”的模式。可以為不同業(yè)務(wù)創(chuàng)建不同權(quán)限賬號(hào)user default on nopass ~* all user biz_app_user on AppUserPassword123! ~cache:* get set del expire第一行保持默認(rèn)用戶超管權(quán)限本地運(yùn)維用第二行創(chuàng)建一個(gè)只能操作cache:前綴key的受限賬號(hào)。權(quán)限最小化原則在任何系統(tǒng)都適用Redis也不例外。5. 啟動(dòng)、守護(hù)與開(kāi)機(jī)自啟安裝配置完就該讓Redis跑起來(lái)了。啟動(dòng)方式有很多種我建議使用systemd來(lái)管理好處是開(kāi)機(jī)自啟、進(jìn)程守護(hù)、崩潰自動(dòng)拉起、日志統(tǒng)一管理。5.1 編寫systemd服務(wù)文件手動(dòng)創(chuàng)建一個(gè)/etc/systemd/system/redis.service文件內(nèi)容如下[Unit] DescriptionRedis Server Afternetwork.target [Service] ExecStart/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf ExecReload/bin/kill -USR2 $MAINPID ExecStop/bin/kill -SIGTERM $MAINPID Restarton-failure RestartSec3s Userredis Groupredis LimitNOFILE65535 [Install] WantedBymulti-user.target幾個(gè)參數(shù)解釋一下。Userredis用專用的redis用戶運(yùn)行避免用root跑服務(wù)。這是安全習(xí)慣。Restarton-failure進(jìn)程異常退出時(shí)自動(dòng)重啟生產(chǎn)環(huán)境很關(guān)鍵。LimitNOFILE65535提高文件描述符上限。高并發(fā)場(chǎng)景下Redis需要大量文件描述符默認(rèn)1024完全不夠用。創(chuàng)建完服務(wù)文件后用systemd命令操作systemctl daemon-reload systemctl start redis systemctl enable redis systemctl status redis不出意外Redis就以守護(hù)進(jìn)程方式跑起來(lái)了配置文件生效、開(kāi)機(jī)自啟、異常自動(dòng)拉起。5.2 驗(yàn)證服務(wù)是否正常redis-cli -a YourPassword ping返回PONG說(shuō)明服務(wù)正常。這里有個(gè)小坑命令行里用-a傳密碼會(huì)有 warning 提示密碼被明文記錄在shell history里。能接受但更好的方式是設(shè)置環(huán)境變量或用交互式連接。生產(chǎn)環(huán)境注意別把密碼留在腳本里明文內(nèi)嵌用配置文件或者Redis ACL更合適。另外別忘了驗(yàn)證持久化文件和慢日志功能/usr/local/redis/bin/redis-cli -a YourPassword info persistence /usr/local/redis/bin/redis-cli -a YourPassword slowlog get 10這兩條命令輸出的信息基本能確認(rèn)Redis的持久化、日志記錄工作正常。6. 性能壓測(cè)與基本調(diào)優(yōu)裝好不代表能打。Redis處理能力怎么樣壓一下才有數(shù)。自帶的redis-benchmark工具就能干這活。6.1 跑一輪基準(zhǔn)測(cè)試/usr/local/redis/bin/redis-benchmark -h 127.0.0.1 -p 6379 -a YourPassword -c 100 -n 100000 -t set,get,incr,lpush參數(shù)含義-c 100100個(gè)并發(fā)連接。-n 100000總共10萬(wàn)次請(qǐng)求。-t set,get,incr,lpush分別測(cè)試這幾種命令。一臺(tái)普通云服務(wù)器2核4G上跑完set/get的QPS通常能到5萬(wàn)-15萬(wàn)之間。如果結(jié)果遠(yuǎn)低于這個(gè)范圍依次排查網(wǎng)絡(luò)是不是有瓶頸、CPU是不是被打滿、Redis是否在swap、系統(tǒng)參數(shù)是不是沒(méi)調(diào)。6.2 幾個(gè)關(guān)鍵的調(diào)優(yōu)參數(shù)實(shí)際壓測(cè)和線上運(yùn)行中以下參數(shù)經(jīng)常需要調(diào)整tcp-backlog 511 timeout 300 tcp-keepalive 60 maxclients 10000tcp-backlogTCP連接隊(duì)列大小并發(fā)高時(shí)可以提高避免連接被丟棄。timeout空閑客戶端超時(shí)關(guān)閉時(shí)間0表示不關(guān)閉。如果客戶端連接池連接長(zhǎng)期空閑建議設(shè)300秒。tcp-keepaliveTCP keepalive探測(cè)周期及時(shí)發(fā)現(xiàn)死連接。maxclients最大客戶端連接數(shù)默認(rèn)10000但受系統(tǒng)文件描述符限制。如果報(bào)max number of clients reached除了調(diào)大這個(gè)參數(shù)還要同步調(diào)整系統(tǒng)級(jí)的ulimit -n。操作系統(tǒng)的幾個(gè)隱藏參數(shù)也需要順手調(diào)了sysctl -w net.core.somaxconn1024 sysctl -w vm.overcommit_memory1 sysctl -w net.ipv4.tcp_max_syn_backlog1024vm.overcommit_memory1這個(gè)很多人不理解。Redis持久化時(shí)fork子進(jìn)程需要預(yù)先申請(qǐng)等于當(dāng)前內(nèi)存大小的虛擬內(nèi)存。如果系統(tǒng)overcommit策略過(guò)保守fork會(huì)直接失敗導(dǎo)致持久化失敗。設(shè)置成1就是讓內(nèi)核允許超額分配內(nèi)存保證fork成功。需要把這些sysctl參數(shù)寫進(jìn)/etc/sysctl.conf才能永久生效net.core.somaxconn1024 vm.overcommit_memory1 net.ipv4.tcp_max_syn_backlog1024然后執(zhí)行sysctl -p使配置立刻生效。6.3 大key和熱key的治理意識(shí)壓測(cè)做的再好線上如果存在大key和熱key性能一樣崩。大key指的是單個(gè)key的value特別大比如幾MB甚至幾十MB的字符串或者千萬(wàn)級(jí)別的list、hash。操作這種key時(shí)網(wǎng)絡(luò)傳輸耗時(shí)高、內(nèi)存占用大還會(huì)阻塞Redis單線程執(zhí)行。排查用redis-cli --bigkeys能按類型找出大key清單。熱key指的是某個(gè)key被超高頻率訪問(wèn)單臺(tái)Redis節(jié)點(diǎn)扛不住。排查用redis-cli --hotkeys需要開(kāi)啟LFU策略或者通過(guò)monitor命令臨時(shí)觀察。處理方案不外乎幾種大key拆分成多個(gè)小key熱key做本地緩存或多副本。這塊內(nèi)容展開(kāi)能寫一萬(wàn)字今天先把排查方法放進(jìn)意識(shí)里遇到問(wèn)題知道從哪個(gè)方向查。7. 日常排查問(wèn)題實(shí)錄匯總這部分是根據(jù)我實(shí)際踩過(guò)的坑整理出來(lái)的不敢說(shuō)權(quán)威但真實(shí)有效。7.1 問(wèn)題1編譯報(bào)錯(cuò)MALLOC: Jemalloc Unsupported可能原因當(dāng)前系統(tǒng)尤其某些ARM架構(gòu)、特定版本的gcc環(huán)境與Redis捆綁的jemalloc版本不兼容或者gcc版本過(guò)舊導(dǎo)致編譯階段宏判斷錯(cuò)誤。解決辦法使用make MALLOClibc指定使用系統(tǒng)的libc malloc輔以正常參數(shù)編譯安裝。二次建議如果一直報(bào)錯(cuò)先升級(jí)gcc。CentOS 7老版本自帶gcc 4.8.5阿里云源可以裝devtoolset或者用scl源裝gcc 8以上版本。提示編譯Redis 7.x完整要求gcc版本不低于4.8.5但實(shí)際推薦gcc 8尤其是Arm架構(gòu)上。升級(jí)gcc后再編譯絕大部分問(wèn)題能解決。7.2 問(wèn)題2Redis啟動(dòng)后外部訪問(wèn)不通現(xiàn)象本機(jī)redis-cli連得上其他服務(wù)器連不上。排查步驟確認(rèn)Redis進(jìn)程在監(jiān)聽(tīng)ss -tlnp | grep 6379確認(rèn)監(jiān)聽(tīng)地址不是只有127.0.0.1redis-cli -a pass info server里看tcp_port。確認(rèn)防火墻狀態(tài)firewall-cmd --list-all或iptables -L -n把6379放行。確認(rèn)云服務(wù)器安全組策略這個(gè)經(jīng)常被忽略安全組沒(méi)放行端口你本地防火墻配得再好也沒(méi)用。最后檢查redis.conf里bind和protected-mode配置。一次線上事故的排查順序我印象很深當(dāng)時(shí)業(yè)務(wù)方說(shuō)連不上Redis我先檢查systemd狀態(tài)——正常檢查端口監(jiān)聽(tīng)——也正常檢查防火墻——放行了最后才發(fā)現(xiàn)云控制臺(tái)的安全組忘了加6379端口。這類問(wèn)題一般就藏在最后一步。7.3 問(wèn)題3Redis無(wú)緣無(wú)故被持久化數(shù)據(jù)拖慢現(xiàn)象某些時(shí)刻出現(xiàn)應(yīng)用卡頓redis-cli執(zhí)行命令延遲很高。排查過(guò)程redis-cli --latency觀察平均和最大延遲。查看CPU使用率如果達(dá)到100%大概率是RDB快照f(shuō)ork子進(jìn)程引起。查看RDB/AOF文件所在磁盤IO情況磁盤IOPS被打滿說(shuō)明快照或AOF重寫太頻繁。解決辦法拉大RDB快照觸發(fā)條件或者調(diào)整save間隔。AOF重寫放到業(yè)務(wù)低峰期設(shè)置auto-aof-rewrite-min-size更大。持久化文件放獨(dú)立磁盤與系統(tǒng)盤分離避免互相影響。7.4 問(wèn)題4Redis突然大量超時(shí)但CPU和內(nèi)存都不高這個(gè)隱蔽性很強(qiáng)。當(dāng)時(shí)排查了半天發(fā)現(xiàn)是swap問(wèn)題——機(jī)器內(nèi)存不足Redis內(nèi)存頁(yè)被換到了磁盤上導(dǎo)致所有訪問(wèn)Redis的操作都帶上磁盤IO延遲。排查方法看/proc/redis_pid/status里的VmSwap字段不為0就有問(wèn)題。解決方向把Redis內(nèi)存上限調(diào)低給系統(tǒng)留足余量或者給機(jī)器加內(nèi)存最徹底。7.5 問(wèn)題5AOF文件損壞導(dǎo)致啟動(dòng)失敗現(xiàn)象服務(wù)器異常斷電后重啟Redis直接起不來(lái)報(bào)AOF文件校驗(yàn)失敗。解決辦法redis-check-aof --fix /usr/local/redis/data/appendonly.aof這個(gè)工具會(huì)修復(fù)損壞的AOF文件把錯(cuò)誤的尾部截掉。修完再啟動(dòng)。注意修復(fù)過(guò)程可能丟失最后幾條寫入記錄但這是斷電場(chǎng)景下最好的結(jié)果。8. 我的一些經(jīng)驗(yàn)總結(jié)裝Redis這件事看起來(lái)是執(zhí)行幾條命令實(shí)際上是三個(gè)層面的方法論第一版本和安裝方式需要綜合評(píng)估。生產(chǎn)環(huán)境建議源碼編譯安裝部署路徑統(tǒng)一管理測(cè)試環(huán)境Docker快速拉起完全沒(méi)問(wèn)題包管理器安裝更適合完全不追求版本和定制化的場(chǎng)景。選型時(shí)多花五分鐘想清楚后面運(yùn)維能省五小時(shí)。第二配置的重點(diǎn)不在于“能用”而在于“扛得住”。bind、密碼、maxmemory、持久化策略、文件描述符、swap這六個(gè)維度每一項(xiàng)都決定了Redis在故障場(chǎng)景下會(huì)怎么表現(xiàn)。尤其是maxmemory和持久化快照的配合線上壓測(cè)時(shí)看不出問(wèn)題流量高峰期突然就出幺蛾子。合理設(shè)置內(nèi)存上限和淘汰策略不是隨便填個(gè)數(shù)字而是根據(jù)業(yè)務(wù)數(shù)據(jù)量和請(qǐng)求量估算出來(lái)的。第三排查問(wèn)題的耐心和系統(tǒng)性。Redis出問(wèn)題先看進(jìn)程在不在、端口通不通、狀態(tài)正常不正常然后看日志、看監(jiān)控、看參數(shù)最后才考慮網(wǎng)絡(luò)、硬件、系統(tǒng)層面。我曾經(jīng)遇到一次詭異的高延遲問(wèn)題排查了兩天才確認(rèn)跟所在的物理宿主機(jī)有關(guān)是虛擬化層網(wǎng)絡(luò)調(diào)度造成的周期抖動(dòng)并不是Redis本身的問(wèn)題。所以說(shuō)定位問(wèn)題的過(guò)程比自己亂猜重要得多。最后分享一個(gè)小技巧每次改完Redis配置務(wù)必用redis-server --test-memory或者直接重啟測(cè)試確認(rèn)配置語(yǔ)法沒(méi)寫錯(cuò)防止線上改完配置結(jié)果起不來(lái)。多一份驗(yàn)證少一次半夜救火。Redis是個(gè)好工具但工具越好用越要對(duì)它的脾氣秉性摸清楚。這篇內(nèi)容把安裝、配置、啟動(dòng)、調(diào)優(yōu)、排查全流程過(guò)了一遍希望你能少踩幾個(gè)我踩過(guò)的坑。