
Linux下裝Redis這件事看起來就是下載、解壓、make三步走但真正落到服務(wù)器上坑一個(gè)接一個(gè)系統(tǒng)源自帶的版本老得掉渣、源碼編譯時(shí)gcc版本不對(duì)報(bào)錯(cuò)、配了systemd之后服務(wù)一直卡在activating、遠(yuǎn)程連接死活不通。我在不同發(fā)行版上把這些問題輪番踩了一遍今天重新整理一份可以直接照著抄的完整筆記目標(biāo)是按標(biāo)準(zhǔn)流程把Redis 7編譯安裝好用systemd統(tǒng)一托管再把7.x版本新增的核心能力驗(yàn)證一遍最后把容易踩的坑一次性列清楚。這篇東西適合第一次在Linux云服務(wù)器上部署Redis的后端同學(xué)也適合運(yùn)維想把手動(dòng)安裝流程規(guī)范化的場景。1. 安裝前想清楚版本、環(huán)境與下載源1.1 為什么建議源碼編譯而非系統(tǒng)源直接安裝很多發(fā)行版自帶的軟件源里其實(shí)有Redis比如CentOS 7自帶的是3.2.xCentOS 8自帶的是5.0.xUbuntu 20.04默認(rèn)源里是5.0.7。這幾個(gè)版本有一個(gè)共同問題太老了。5.0版本到現(xiàn)在雖然還能用但沒有ACL權(quán)限體系、沒有多線程I/O、也缺少RESP3協(xié)議更別說Redis 7才有的Functions、Sharded Pub/Sub這些能力。生產(chǎn)環(huán)境里如果還在用老版本一方面是功能跟不上另一方面是一些老版本在特定場景下存在已知的穩(wěn)定性問題升級(jí)越拖越痛苦。有人會(huì)問能不能加第三方源直接裝Redis 7部分發(fā)行版確實(shí)可以通過EPEL、Remi或一些社區(qū)源裝到但第三方源的維護(hù)質(zhì)量參差不齊有時(shí)候版本跟進(jìn)不及時(shí)有時(shí)候又存在依賴沖突。我自己更傾向于一個(gè)確定性的方案從Redis官網(wǎng)下載源碼包在目標(biāo)機(jī)器上編譯安裝。這樣版本完全可控、安裝路徑完全可控以后升級(jí)也好管理。編譯安裝的代價(jià)只是需要gcc、make這些基礎(chǔ)工具鏈對(duì)Linux服務(wù)器來說基本是標(biāo)配。1.2 環(huán)境檢查與依賴準(zhǔn)備編譯Redis 7需要的基礎(chǔ)工具不多gcc、make、pkg-config。想在編譯后跑官方測(cè)試套件的話還需要tcl。不同系統(tǒng)的安裝命令不一樣CentOS/RHEL系列yum install -y gcc make tcl # 或者更省事直接安裝開發(fā)工具組 yum groupinstall -y Development ToolsUbuntu/Debian系列apt update apt install -y build-essential tcl這里有一個(gè)非常容易被忽略的細(xì)節(jié)gcc版本。CentOS 7自帶的gcc是4.8.5這個(gè)版本編譯Redis 7.0或者7.2時(shí)可能會(huì)遇到問題。我在CentOS 7.9上試過編譯7.0.x時(shí)能過但警告很多編譯7.2.x時(shí)嚴(yán)格模式下會(huì)報(bào)錯(cuò)。如果你的生產(chǎn)環(huán)境是CentOS 7這種老系統(tǒng)建議先升級(jí)gccyum install -y centos-release-scl yum install -y devtoolset-9 scl enable devtoolset-9 bash新一點(diǎn)的系統(tǒng)比如Rocky Linux 9、Ubuntu 22.04/24.04自帶的gcc版本足夠新不需要這一步。裝依賴之前可以先看一下系統(tǒng)信息cat /etc/os-release uname -a gcc --version順便說一句make命令和內(nèi)核版本也有關(guān)系如果編譯時(shí)指定高并行度比如make -j8內(nèi)存小的機(jī)器可能會(huì)出現(xiàn)內(nèi)存不足導(dǎo)致編譯失敗這種情況把并行度降到make -j2或者直接make就好。1.3 下載Redis 7安裝包的選擇Redis官網(wǎng)的下載頁面會(huì)列出當(dāng)前穩(wěn)定版本。以Redis 7為例常見的有7.0.x和7.2.x兩個(gè)系列。7.0是2022年發(fā)布的穩(wěn)定大版本7.2是后續(xù)的穩(wěn)定分支。如果項(xiàng)目不是特別追求新特性建議選7.2.x系列的最新小版本如果團(tuán)隊(duì)更保守7.0.x也完全夠用。這里我以7.2.4為例cd /usr/local/src wget https://download.redis.io/releases/redis-7.2.4.tar.gz國內(nèi)服務(wù)器如果直接連官網(wǎng)下載慢可以用阿里云或華為云的開源鏡像站搜索“redis”就能找到源碼包的鏡像地址下載速度會(huì)快很多。下載完成后建議核對(duì)一下文件的校驗(yàn)值官網(wǎng)會(huì)給出對(duì)應(yīng)版本的SHA256防止下載過程損壞sha256sum redis-7.2.4.tar.gz2. 編譯安裝完整流程從下載到可運(yùn)行2.1 解壓與編譯常用參數(shù)說明解壓源碼包并進(jìn)入目錄tar -zxvf redis-7.2.4.tar.gz cd redis-7.2.4接下來是編譯。Redis的Makefile比較簡單直接執(zhí)行make就好建議帶上-j參數(shù)并行編譯加快速度make -j$(nproc)這里如果報(bào)錯(cuò)最常見的錯(cuò)誤是找不到j(luò)emalloc頭文件。Redis默認(rèn)的內(nèi)存分配器是jemalloc但系統(tǒng)中如果沒有安裝對(duì)應(yīng)的開發(fā)包make的時(shí)候會(huì)提示“jemalloc.h: No such file or directory”。處理方法有兩個(gè)# 方案一使用系統(tǒng)默認(rèn)的libc分配器 make MALLOClibc # 方案二安裝jemalloc開發(fā)包后再編譯推薦 yum install -y jemalloc-devel # Debian/Ubuntu: apt install -y libjemalloc-dev make clean make -j$(nproc)為什么要推薦jemallocRedis是重度內(nèi)存操作的程序大量小對(duì)象頻繁申請(qǐng)和釋放jemalloc在減少內(nèi)存碎片方面比glibc的malloc表現(xiàn)更好。用libc分配器也能跑但長時(shí)間運(yùn)行后內(nèi)存碎片率可能會(huì)偏高。編譯完成之后如果時(shí)間允許可以跑一下官方測(cè)試make testmake test需要系統(tǒng)里有tcl沒裝的話會(huì)提示找不到tclsh。測(cè)試套件會(huì)完整驗(yàn)證Redis各功能模塊耗時(shí)幾分鐘第一次安裝建議跑一遍能提前暴露很多潛在問題。2.2 安裝目錄規(guī)劃與配置文件準(zhǔn)備編譯產(chǎn)物會(huì)生成在src目錄下包括redis-server、redis-cli、redis-benchmark、redis-check-aof、redis-check-rdb等。直接用make install可以安裝到系統(tǒng)路徑但我習(xí)慣指定一個(gè)獨(dú)立目錄方便后續(xù)多版本切換和維護(hù)make install PREFIX/usr/local/redis執(zhí)行完后Redis的可執(zhí)行文件會(huì)安裝到/usr/local/redis/bin目錄。注意make install不會(huì)自動(dòng)復(fù)制配置文件需要手動(dòng)把源碼包根目錄下的redis.conf復(fù)制過去。同時(shí)我建議把數(shù)據(jù)目錄、日志目錄單獨(dú)規(guī)劃出來和生產(chǎn)環(huán)境的標(biāo)準(zhǔn)一致mkdir -p /usr/local/redis/etc /var/lib/redis /var/log/redis cp redis.conf /usr/local/redis/etc/redis.conf這樣規(guī)劃的好處很明顯二進(jìn)制、配置、數(shù)據(jù)、日志四者分離。以后升級(jí)版本時(shí)只需要替換bin目錄配置和數(shù)據(jù)目錄原封不動(dòng)不用做額外遷移。日志和數(shù)據(jù)目錄分離之后清理日志、備份數(shù)據(jù)也都不會(huì)互相干擾。為安全起見生產(chǎn)環(huán)境不要用root運(yùn)行Redis單獨(dú)創(chuàng)建一個(gè)系統(tǒng)用戶useradd -r -s /sbin/nologin redis chown -R redis:redis /var/lib/redis /var/log/redis /usr/local/redis/etc/sbin/nologin這個(gè)shell能確保該用戶無法交互登錄即使進(jìn)程被入侵攻擊者也無法直接通過這個(gè)用戶登進(jìn)系統(tǒng)。2.3 配置環(huán)境變量讓redis-cli直接可用如果不用環(huán)境變量每次執(zhí)行Redis命令都要寫全路徑/usr/local/redis/bin/redis-cli非常麻煩。Linux下配置環(huán)境變量的標(biāo)準(zhǔn)做法是在/etc/profile.d/下新建一個(gè)腳本echo export PATH$PATH:/usr/local/redis/bin /etc/profile.d/redis.sh chmod 644 /etc/profile.d/redis.sh source /etc/profile.d/redis.sh之后重新登錄或者source一下redis-cli、redis-server這些命令就能直接用了。驗(yàn)證一下redis-server --version輸出版本號(hào)說明二進(jìn)制文件安裝成功且PATH配置生效。3. 配置文件與服務(wù)托管不會(huì)systemd等于白裝3.1 redis.conf核心參數(shù)逐項(xiàng)解讀Redis的配置文件在源碼包根目錄有一份默認(rèn)版本但默認(rèn)配置只適合本地開發(fā)生產(chǎn)環(huán)境必須逐項(xiàng)過一遍。我挑幾個(gè)改動(dòng)頻率最高的參數(shù)說明配置項(xiàng)默認(rèn)值建議值說明bind127.0.0.1 -::1127.0.0.1 或內(nèi)網(wǎng)IP控制監(jiān)聽地址默認(rèn)只允許本機(jī)訪問port63796379默認(rèn)端口除非有沖突否則不用改protected-modeyesyes保護(hù)模式配合bind和密碼使用daemonizenono用systemd托管時(shí)必須保持nosupervisednosystemd配合systemd的Typenotify機(jī)制logfile空/var/log/redis/redis.log日志文件路徑dir.//var/lib/redisRDB/AOF持久化文件目錄requirepass空強(qiáng)密碼訪問密碼生產(chǎn)環(huán)境必設(shè)maxmemory0根據(jù)機(jī)器內(nèi)存最大內(nèi)存限制0表示不限制maxmemory-policynoevictionallkeys-lru等內(nèi)存達(dá)到上限后的淘汰策略appendonlynoyes是否開啟AOF持久化逐項(xiàng)解釋一下關(guān)鍵點(diǎn)。daemonize這個(gè)參數(shù)老教程基本都是“daemonize yes”因?yàn)橐郧傲?xí)慣用nohup把redis-server放到后臺(tái)。但用systemd管理服務(wù)時(shí)必須保持daemonize no否則systemd會(huì)認(rèn)為進(jìn)程沒有正常啟動(dòng)或管理不了進(jìn)程生命周期服務(wù)狀態(tài)會(huì)是異常的。supervised systemd這個(gè)配置容易被忽略。它的作用是讓Redis在啟動(dòng)完成后主動(dòng)通知systemd“我已經(jīng)準(zhǔn)備好了”systemd那邊配合Typenotify來接收消息。這兩個(gè)必須配套使用后面我會(huì)單獨(dú)說明如果配錯(cuò)會(huì)發(fā)生什么。maxmemory和maxmemory-policy是線上必須認(rèn)真考慮的參數(shù)。如果不設(shè)maxmemoryRedis會(huì)一直吃內(nèi)存直到操作系統(tǒng)OOM如果設(shè)了maxmemory但不設(shè)置合理的淘汰策略默認(rèn)的noeviction會(huì)在內(nèi)存滿后直接拒絕寫操作。緩存場景一般用allkeys-lru語義是所有key按照最近最少使用算法淘汰如果業(yè)務(wù)上允許多數(shù)數(shù)據(jù)過期也可以用volatile-lru只淘汰設(shè)了過期時(shí)間的key。appendonly建議生產(chǎn)環(huán)境開啟。Redis默認(rèn)只開RDB快照周期性保存極端情況下會(huì)丟失最后一次快照之后的數(shù)據(jù)。AOF是追加寫日志每秒刷盤一次的配置下最多丟一秒數(shù)據(jù)。兩個(gè)同時(shí)開的話Redis啟動(dòng)時(shí)會(huì)優(yōu)先用AOF恢復(fù)數(shù)據(jù)安全性和恢復(fù)速度都能兼顧。3.2 使用systemd管理Redis寫service文件前先確保配置文件和目錄權(quán)限已經(jīng)就位。然后創(chuàng)建/etc/systemd/system/redis.service[Unit] DescriptionRedis 7.2 server Afternetwork-online.target Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf ExecReload/bin/kill -s HUP $MAINPID ExecStop/bin/kill -s QUIT $MAINPID Restartalways RestartSec3 Userredis Groupredis LimitNOFILE1024000 [Install] WantedBymulti-user.target幾個(gè)關(guān)鍵配置我展開說一下。Typenotify是我踩過大坑的地方。Redis配置里如果沒寫supervised systemd進(jìn)程啟動(dòng)后不會(huì)給systemd發(fā)通知而systemd的Typenotify會(huì)一直等通知直到超時(shí)然后服務(wù)顯示啟動(dòng)失敗。反過來如果配置里寫了supervised systemd但service文件用的是默認(rèn)的Typesimple雖然服務(wù)能起來但systemd無法準(zhǔn)確感知Redis的就緒狀態(tài)管理上會(huì)有偏差。所以這兩個(gè)配置必須配套。LimitNOFILE1024000是文件描述符上限。Redis處理高并發(fā)連接時(shí)會(huì)打開大量文件描述符系統(tǒng)默認(rèn)的1024遠(yuǎn)遠(yuǎn)不夠如果不調(diào)大連接數(shù)一上來就會(huì)出現(xiàn)“Too many open files”錯(cuò)誤。這個(gè)限制在systemd里通過LimitNOFILE設(shè)置作用是覆蓋系統(tǒng)的ulimit限制。Restartalways和RestartSec3表示進(jìn)程異常退出后3秒自動(dòng)重啟。Redis自身比較穩(wěn)定但也會(huì)遇到OOM或者被誤殺的情況這種自動(dòng)化恢復(fù)在線上能省很多事。寫完service文件后執(zhí)行systemctl daemon-reload systemctl enable redis systemctl start redis systemctl status redis如果一切正常status輸出會(huì)是active (running)。查看日志journalctl -u redis -f順便說一句很多人問為什么要用systemd而不是直接在命令行敲redis-server這個(gè)人差別在于systemd接管了進(jìn)程生命周期管理開機(jī)自啟、崩潰重啟、統(tǒng)一日志、統(tǒng)一停止重啟操作運(yùn)維上完全標(biāo)準(zhǔn)。以后這臺(tái)機(jī)器上如果還跑其他服務(wù)管理方式都一致不用再記各種trick。3.3 防火墻、SELinux與遠(yuǎn)程訪問控制服務(wù)起來之后如果是本機(jī)使用默認(rèn)bind 127.0.0.1就夠了。但更多時(shí)候需要讓其他機(jī)器連過來比如應(yīng)用服務(wù)器連Redis。這時(shí)要設(shè)置監(jiān)聽地址和放行端口。redis.conf里改動(dòng)兩處# 如果需要所有網(wǎng)卡都能訪問 bind 0.0.0.0 # 或者只綁定內(nèi)網(wǎng)IP bind 192.168.1.100注意一旦bind不是127.0.0.1就必須設(shè)置requirepass同時(shí)保持protected-mode yes。否則Redis端口暴露到外網(wǎng)掃描工具掃到后很快就會(huì)被入侵、寫入惡意數(shù)據(jù)、甚至被當(dāng)作跳板。這個(gè)不是危言聳聽公網(wǎng)裸奔的Redis在掃描器眼里的價(jià)值極高。防火墻要放行6379端口firewall-cmd --permanent --add-port6379/tcp firewall-cmd --reload firewall-cmd --list-ports如果你用的是云服務(wù)器還要到云控制臺(tái)的安全組規(guī)則里放行6379端口。這兩層網(wǎng)絡(luò)策略是疊加的缺一個(gè)都連不上。CentOS這類默認(rèn)開啟SELinux的系統(tǒng)還有一個(gè)隱藏難點(diǎn)。就算防火墻放行了端口SELinux如果沒有對(duì)應(yīng)的端口策略連接仍然會(huì)被攔截。表現(xiàn)為本機(jī)redis-cli連接正常遠(yuǎn)程telnet端口不通。先看SELinux狀態(tài)getenforce如果輸出Enforcing需要給Redis放行端口yum install -y policycoreutils-python-utils semanage port -a -t redis_port_t -p tcp 6379再強(qiáng)調(diào)一下遇到SELinux攔截時(shí)別一上來就setenforce 0那是關(guān)掉整個(gè)SELinux保護(hù)屬于治標(biāo)不治本。用semanage精準(zhǔn)放行Redis端口才是正規(guī)做法。4. Redis 7新特性實(shí)測(cè)與基本玩法4.1 ACL賬號(hào)權(quán)限從“一把密碼鎖”到細(xì)粒度授權(quán)Redis 6開始引入了ACLAccess Control ListRedis 7繼續(xù)完善了這個(gè)體系。我不止一次見過生產(chǎn)環(huán)境里所有人共用一個(gè)密碼、所有權(quán)限一把梭出問題根本不知道是誰操作的。ACL可以按業(yè)務(wù)創(chuàng)建獨(dú)立賬號(hào)只給最小權(quán)限。默認(rèn)情況下Redis只有一個(gè)default用戶配置里的requirepass等價(jià)于給default用戶設(shè)置了密碼。創(chuàng)建業(yè)務(wù)只讀賬號(hào)redis-cli -a 管理員密碼 EOF ACL SETUSER app_read on app123 ~cache:* get mget exists ACL LIST ACL GETUSER app_read EOF這條ACL命令的意思是創(chuàng)建app_read用戶密碼app123只允許訪問cache:前綴的key只允許執(zhí)行g(shù)et、mget、exists三個(gè)命令。效果立竿見影即使密碼泄露攻擊者也無法刪除數(shù)據(jù)、無法執(zhí)行flushall、無法訪問非cache前綴的key。ACL真正的價(jià)值在于權(quán)限收斂和審計(jì)。生產(chǎn)環(huán)境可以給不同業(yè)務(wù)線建立不同用戶緩存讀寫賬號(hào)、報(bào)表只讀賬號(hào)、運(yùn)維管理賬號(hào)每個(gè)賬號(hào)的命令范圍、key范圍、讀寫權(quán)限都明確。萬一某個(gè)賬號(hào)泄露影響范圍可以控制在最小。4.2 Redis Functions把Lua腳本變成可復(fù)用的函數(shù)Redis 7發(fā)布時(shí)重點(diǎn)推的功能之一就是Redis Functions。之前寫Lua腳本要么用EVAL每次把腳本內(nèi)容傳過去要么把腳本緩存在客戶端管理起來很別扭。Redis Functions相當(dāng)于服務(wù)端的“存儲(chǔ)過程”腳本一次加載之后通過函數(shù)名直接調(diào)用還能跟隨主從復(fù)制和集群同步。一個(gè)很常見的場景需要原子的“INCR EXPIRE”防止key永遠(yuǎn)不過期。新建一個(gè)mylib.lua文件#!lua namemylib local function incr_with_ttl(keys, args) local key keys[1] local ttl tonumber(args[1]) local v redis.call(INCR, key) if v 1 then redis.call(EXPIRE, key, ttl) end return v end redis.register_function(incr_with_ttl, incr_with_ttl)加載到Redisredis-cli -a 管理員密碼 -x FUNCTION LOAD mylib.lua調(diào)用redis-cli -a 管理員密碼 FCALL incr_with_ttl 1 mykey 60連續(xù)執(zhí)行兩次第一次返回1第二次返回2同時(shí)TTL mykey會(huì)顯示60。這套機(jī)制做限流、計(jì)數(shù)器衰減、分布式鎖續(xù)期都非常方便。函數(shù)庫支持FUNCTION DUMP/RESTORE可以整體備份和遷移比手動(dòng)管理一堆EVAL腳本干凈太多。為什么推薦函數(shù)而不是直接EVAL一是代碼復(fù)用同一個(gè)邏輯不需要每個(gè)客戶端各存一份腳本二是升級(jí)管理函數(shù)整體加載版本可通過名字區(qū)分三是主從同步加載的函數(shù)會(huì)自動(dòng)同步到從節(jié)點(diǎn)故障切換后邏輯不丟。在Redis 7環(huán)境里新項(xiàng)目建議優(yōu)先用Functions。4.3 Sharded Pub/Sub分片發(fā)布訂閱簡單實(shí)驗(yàn)Redis 7在集群場景新增了Sharded Pub/Sub分片發(fā)布訂閱相關(guān)的命令是SPUBLISH、SSUBSCRIBE、SUNSUBSCRIBE。傳統(tǒng)的PUBLISH/SUBSCRIBE在集群模式下有個(gè)問題一條消息要廣播到集群所有節(jié)點(diǎn)節(jié)點(diǎn)規(guī)模大了之后很浪費(fèi)帶寬。Sharded Pub/Sub將頻道和某個(gè)slot綁定消息只會(huì)路由到該slot所在節(jié)點(diǎn)的訂閱客戶端大幅減少網(wǎng)絡(luò)開銷。單機(jī)環(huán)境一樣可以體驗(yàn)這個(gè)功能開兩個(gè)終端# 終端1 redis-cli SSUBSCRIBE shard_channel # 終端2 redis-cli SPUBLISH shard_channel hello sharded pubsub終端1會(huì)收到這條消息。如果項(xiàng)目里用到WebSocket推送、實(shí)時(shí)通知這類場景并且部署的是Redis Cluster用Sharded Pub/Sub會(huì)比傳統(tǒng)發(fā)布訂閱更高效。4.4 安裝完成后的基本數(shù)據(jù)操作與驗(yàn)證Redis裝好后至少要熟練操作五大數(shù)據(jù)類型。我每次給團(tuán)隊(duì)做環(huán)境驗(yàn)證都會(huì)用這幾條命令過一遍redis-cli -a 密碼 EOF # String緩存、計(jì)數(shù)器、會(huì)話 SET user:1:name tom GET user:1:name INCR page_view # Hash對(duì)象存儲(chǔ) HSET user:1 age 20 city beijing HGETALL user:1 # List消息隊(duì)列、時(shí)間線 LPUSH task:queue job1 job2 job3 LRANGE task:queue 0 -1 # Set去重、標(biāo)簽、共同關(guān)注 SADD tag:redis linux database SMEMBERS tag:redis # ZSet排行榜、延時(shí)隊(duì)列 ZADD rank:score 100 user_a 95 user_b ZRANGE rank:score 0 -1 WITHSCORES EOF驗(yàn)證版本和運(yùn)行狀態(tài)redis-cli -a 密碼 INFO server redis-cli -a 密碼 INFO memory redis-cli -a 密碼 INFO statsINFO server里能看到redis_versionINFO memory里的used_memory是實(shí)際占用mem_fragmentation_ratio是內(nèi)存碎片率這個(gè)值長期高于1.5說明碎片比較多得找原因INFO stats里的instantaneous_ops_per_sec表示瞬時(shí)QPS壓測(cè)時(shí)可以觀察。5. 常見問題與排查實(shí)錄5.1 編譯安裝階段的問題速查我把實(shí)際運(yùn)維中遇到的高頻問題整理成一張表方便直接對(duì)照現(xiàn)象原因解決辦法make報(bào)錯(cuò)jemalloc.h找不到系統(tǒng)缺少jemalloc開發(fā)包make MALLOClibc或安裝jemalloc-devel后重新makemake test報(bào)錯(cuò)找不到tclsh沒裝tclyum/apt install tcl老系統(tǒng)編譯7.2報(bào)語法錯(cuò)誤gcc版本太低如4.8.5用devtoolset升級(jí)gcc或換新系統(tǒng)make -j高并行度時(shí)編譯失敗內(nèi)存不足降低并行度用make -j2或直接make啟動(dòng)時(shí)報(bào)TCP backlog警告內(nèi)核somaxconn參數(shù)小于Redis的511sysctl -w net.core.somaxconn1024并寫入/etc/sysctl.conf日志提示transparent huge page警告THP未被禁用echo never /sys/kernel/mm/transparent_hugepage/enabled并寫入rc.local編譯階段最花時(shí)間的是gcc版本和jemalloc這兩個(gè)問題建議在準(zhǔn)備環(huán)境時(shí)就處理掉不要等到編譯報(bào)錯(cuò)再折騰。5.2 啟動(dòng)與服務(wù)管理階段的問題速查服務(wù)管理階段最常見的問題就是systemd啟動(dòng)卡住?,F(xiàn)象原因解決辦法systemctl start redis后一直activating (start)Typenotify等待通知但Redis沒發(fā)通知redis.conf里設(shè)置supervised systemd并保持daemonize no服務(wù)一會(huì)兒起來一會(huì)兒掛數(shù)據(jù)目錄權(quán)限不對(duì)redis用戶無法寫dirchown -R redis:redis /var/lib/redis /var/log/redis重啟后Redis沒起來沒執(zhí)行enablesystemctl enable redis想改配置但不知道生效沒有寫錯(cuò)配置項(xiàng)用redis-cli CONFIG GET/REWRITE動(dòng)態(tài)校驗(yàn)我之前在測(cè)試環(huán)境反復(fù)出現(xiàn)service狀態(tài)卡在activating日志里什么都沒有排查到最后就是配置里寫了一個(gè)daemonize yessystemd一直在等一個(gè)永遠(yuǎn)等不到的通知。這個(gè)問題在官方文檔里有說明但平時(shí)誰會(huì)逐字讀文檔還是踩坑記得最牢。5.3 連接與安全相關(guān)的問題速查遠(yuǎn)程連接不上按照下面的順序一層層排查基本都能找到原因現(xiàn)象原因解決辦法本機(jī)能連遠(yuǎn)程不行bind還綁定在127.0.0.1修改bind為內(nèi)網(wǎng)IP或0.0.0.0報(bào)NOAUTH Authentication required設(shè)了密碼但客戶端沒帶redis-cli -a 密碼或連接后執(zhí)行AUTH密碼正確但仍連不上protected-mode 無bind組合限制保持protected-mode yes設(shè)置bind和requirepass遠(yuǎn)程telnet端口不通防火墻或安全組沒放行firewall-cmd添加6379/tcp檢查云安全組防火墻放行后仍不通SELinux攔截semanage放行redis_port_t端口收到MISCONF Errors writing to the AOF file磁盤滿或AOF寫入失敗檢查磁盤空間、掛載權(quán)限安全相關(guān)的建議再重復(fù)一遍密碼不要用弱口令不要圖方便不設(shè)密碼直接暴露公網(wǎng)。連接測(cè)試時(shí)別用redis-cli -a 密碼這種把密碼暴露在命令行歷史里的做法用環(huán)境變量更安全export REDISCLI_AUTH你的密碼 redis-cli ping寫在最后的一點(diǎn)經(jīng)驗(yàn)這套流程走完Redis 7已經(jīng)能穩(wěn)定跑在Linux上了。我個(gè)人實(shí)操后的幾個(gè)習(xí)慣配置目錄用Git管理每次改動(dòng)都有記錄啟動(dòng)后第一件事就是配ACL賬號(hào)和強(qiáng)密碼數(shù)據(jù)目錄掛獨(dú)立磁盤避免和根分區(qū)搶空間每月用redis-check-aof和redis-check-rdb做一次持久化文件體檢。安裝本身只是第一步真正考驗(yàn)功力的是運(yùn)行期的監(jiān)控、備份和權(quán)限治理。希望這篇筆記能讓你少踩幾個(gè)坑尤其是systemd托管和SELinux那兩個(gè)地方知道原理就不會(huì)再被繞進(jìn)去了。