ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Redis安装配置实战指南:从选型到主从复制与避坑手册

Redis安装配置实战指南:从选型到主从复制与避坑手册 1. 安装Redis之前建议先想清楚这4个问题很多人一上来就搜“redis安装教程”然后照着网上的步骤走一遍装是装上了但过两天就发现不对劲连不上、数据丢了、密码没设、被扫了、内存爆了……回过头来才发现问题不在“安装”这一步而在安装之前有几个决定没做对。做为一个用了七年Redis、在线上被它坑过也靠它救过场的人我真心建议你在动手之前先花几分钟把下面这四个问题过一遍。它们决定了你后面的安装方式、配置文件怎么写、以及将来出问题时你能少熬多少夜。1.1 这台Redis是给自己练手还是给团队/线上用这个问题的答案直接决定你采用哪种安装方式自己本机练手、写Demo怎么方便怎么来。Windows用户直接下载官方Windows移植版或WSL跑Linux版就行不用折腾Docker。公司项目、多人共用、要跑测试环境强烈建议用Docker部署版本可控、环境隔离、迁移方便出了问题删容器重建即可不用在宿主机上留一堆残留依赖。生产环境请老老实实在Linux服务器上以源码编译或官方二进制包方式安装再用systemd托管。Docker跑生产不是不行但需要额外搞定持久化、日志、网络模式、安全加固一大堆东西不适合一篇入门教程展开。1.2 装哪个版本Redis的版本迭代非常快而且大版本之间有一些行为差异比如Redis 6.0引入ACL和IO多线程Redis 7.x开始正式支持Redis Functions。对于新手我建议场景建议版本理由日常学习/练手最新稳定版当前7.x系可以用上新特性社区资料也多生产环境当前大版本的最新unstable往前的稳定patch版修复了已知Crash和Bug更稳老项目维护项目原先锁定的版本不要贸然升主版本行为变更可能踩坑注意千万别装alpha、RC这类预发版本练手有些命令行为和正式版不一样你照着文档写可能就踩坑。1.3 端口、密码、持久化这些基础设置是安装完再改还是安装时就规划好我的答案是安装时就想好装完立刻配好。Redis默认是127.0.0.1:6379无密码如果你安装时一路Next不管将来把它暴露到服务器公网IP上几小时内就会被扫描攻击写入挖矿程序——这不是段子是真实发生的事。后面我会专门列一段讲怎么最低成本地加固一台Redis。1.4 会不会用到集群、主从复制如果你规划里已经有“高可用”“主从”这些词安装阶段就要注意一件事配置文件里的一些参数在主从复制场景下默认值会给你带来困惑比如replica-read-only、replicaof指令的位置、masterauth密码同步等。我建议至少先把单机版玩通再考虑主从不要一步到位。后面我会示范Docker方式怎么快速搭一套主从让大家有个直观感受。2. 两种主流安装路径二进制安装与Docker容器化这一节我会把最常用的两条路都走一遍。你可以根据自己的场景选一条但建议两条都读一遍因为很多问题的排查思路是相通的。2.1 Linux服务器上的二进制安装CentOS / Ubuntu通用思路这里我先说最稳健的方式用Linux发行版自带的包管理器或者直接拉官方源码编译。方式Aapt / yum 安装包管理器版本# Ubuntu / Debian sudo apt update sudo apt install redis-server # CentOS / RHEL系 sudo yum install redis这个方式最快但有个问题包管理器里的版本往往不是最新的而且个别发行版会把Redis的配置拆得比较碎。我个人对它的评价是“胜在省事、跟系统集成好、systemd托管都是自动完成”。如果你对版本要求不高完全够用。方式B官方源码编译安装更可控# 安装编译依赖 # Ubuntu环境下 sudo apt update sudo apt install build-essential tcl pkg-config # 下载源码以稳定版7.2.5为例建议去redis.io/download 自己确认最新版 wget https://download.redis.io/releases/redis-7.2.5.tar.gz tar xzf redis-7.2.5.tar.gz cd redis-7.2.5 # 编译 make -j$(nproc) # 安装到 /usr/local/bin sudo make install编译这一步很多教程都只是带过但我必须多说一句如果编译时报jemalloc相关错误多半是系统缺少必要的库或编译器太旧。此时可以改用make MALLOClibc重新编译这是官方文档里都写明的一个后手。不过在生产环境我建议还是把依赖装齐全再编译因为jemalloc对内存碎片率的优化确实有用。装完后Redis的可执行文件会被放到/usr/local/bin下核心的四个命令是redis-server启动服务端redis-cli客户端连接命令行工具redis-benchmark压测工具redis-check-aof/redis-check-rdb持久化文件修复工具2.2 Windows用户怎么装这里要先澄清一个历史问题Redis官方其实一直不以Windows为主支持平台但架不住大家用得多所以社区维护了一个移植版本通常叫tporadowski/redis或微软archive版本。踩过不少坑之后我现在的建议排序是这样的首选WSL2适用于Linux的Windows子系统在WSL里按Linux方式装行为最接近生产环境命令也通用。次选Docker Desktop跑Linux容器Windows下用Docker跑Redis也是常规操作。不推荐直接跑Windows exe版除非你只是临时要在本机看一眼毕竟这个移植版很久没新特性了而且文件路径、服务注册、开机自启这些细节都跟Linux版有差异。如果你只是想在Windows桌面上快速试一把还有一种更偷懒的方式去Redis官网或GitHub的release页面下载Windows版zip解压后直接redis-server.exe默认就前台跑起来了。想带配置文件启动也可以redis-server.exe redis.windows.conf但说真的从长期学习和进阶比如后面要学主从、集群、Lua脚本、Redis模块的角度WSL2或者云服务器Linux环境会舒坦得多。2.3 Docker方式安装最省心也最容易忽视配置持久化Docker安装Redis是我目前最常用的方式特别是做联调环境和快速demo的时候。命令非常简单# 拉取官方镜像 docker pull redis:7.2-alpine # 简单启动一个测试容器 docker run --name my-redis -d -p 6379:6379 redis:7.2-alpine这条命令跑起来后你本机的6379端口就通了用redis-cli -h 127.0.0.1就能连上。看起来是不是很爽但这里我要重点提个醒如果你不加持久化挂载容器一删数据全没了。对我当年就是这么在测试环境里把缓存数据全删光的。正确做法是给容器挂载数据目录和配置文件# 先准备一份自定义配置文件假设放在 /opt/redis/conf/redis.conf mkdir -p /opt/redis/data docker run --name redis-prod \ -d \ -p 6379:6379 \ -v /opt/redis/conf/redis.conf:/etc/redis/redis.conf \ -v /opt/redis/data:/data \ redis:7.2-alpine \ redis-server /etc/redis/redis.conf注意最后的redis-server /etc/redis/redis.conf是覆盖官方镜像的默认启动命令告诉它加载我们挂载进去的配置文件。如果漏了这一步配置文件挂进去也不会生效这是很多新手最容易犯的错。另外如果Redis容器和应用容器要互通别用localhost连接那在容器网络里指向的是容器自己。建议用--network让两个容器在同一个自定义网络里然后通过容器名互相访问或者干脆在宿主机上用-p把端口映射出来再连宿主IP。3. 启动、连接和基础验证装完先别急着写代码无论你用哪种方式装好Redis安装完成之后都建议先做一套“标准动作”确认它真的健康可用再进入业务开发。3.1 启动服务Linux二进制安装方式未配置systemd之前可以前台启动观察日志redis-server /path/to/redis.conf看到Ready to accept connections这行日志说明服务起来了。如果不想占用终端也可以daemonize yes把它放后台但配置了systemd时别这么设否则systemd会认为服务启动失败。用Docker方式时启动后看日志docker logs -f redis-prod确认没有报错。容器启动失败最常见的原因就是挂载的配置文件有语法错误。3.2 使用redis-cli做连通性验证Redis自带的命令行客户端redis-cli是我们最趁手的工具先跑几个最基础的命令redis-cli -h 127.0.0.1 -p 6379 ping # 返回 PONG 说明服务在线 redis-cli # 进入交互式命令行后执行 127.0.0.1:6379 set hello world OK 127.0.0.1:6379 get hello world 127.0.0.1:6379 dbsize (integer) 1dbsize返回的当前库key数量能直观确认写入生效。如果带着密码连接用-a参数或者进入交互模式后先auth 密码。3.3 看一眼基础状态信息执行info能看到一大段运行状态我最常关注的几项connected_clients当前连接数排查连接泄漏时必看。used_memory_human当前内存占用判断内存规划合不合理。total_commands_processed累计命令数压测或监控时用来算QPS。uptime_in_seconds运行时长确认服务有没有偷偷重启过。role当前节点角色是master还是slave主从模式排查时先看这个。redis-cli info | grep -E connected_clients|used_memory_human|total_commands_processed|role|uptime_in_seconds这几项串起来看一个Redis实例的“体检报告”就出来了。比如连接数高但内存增长不大可能是连接池配小了频繁建连内存涨得快但业务缓存又不大就得考虑是不是大Key或者内存碎片的问题。3.4 Windows上没装redis-cli怎么办如果你是Windows解压版目录里通常自带redis-cli.exe用法一模一样。如果你是WSL或Docker在宿主机没有redis-cli也不要紧Docker里可以这样进入容器执行docker exec -it my-redis redis-cli4. redis.conf配置解读这几行的作用比你想的大得多Redis安装完真正让它“好用”的不是版本而是配置。我按实际踩坑的优先级把redis.conf里最重要的配置项分成三层。4.1 安全相关绑定地址、密码、保护模式默认情况下Redis只允许本机访问。但很多人为了让别的机器能连直接把bind 127.0.0.1注释掉这就等于把Redis裸奔到了公网非常危险。# 在最外层注释掉默认绑定然后写成实际对外的网卡IP多个IP用空格分隔 bind 127.0.0.1 192.168.1.100 # 设置密码访问时通过 AUTH 认证 requirepass YourStrongPassWord # 关闭保护模式否则非本机访问会被拦截 protected-mode no需要说明一下protected-mode把它设为no之前要确保密码足够复杂——一旦Redis部署在云服务器扫描器几乎立刻就会盯上。我都习惯再叠加一层防火墙白名单只允许特定业务机器IP访问6379端口而不是把端口敞开给所有内网。加一层防火墙永远比不加要稳。4.2 持久化相关RDB快照与AOF日志Redis默认启用RDB快照持久化配置格式是save 3600 1 save 300 100 save 60 10000含义分别是“3600秒内至少有1次写操作、300秒内至少有100次写操作、60秒内至少有10000次写操作”就触发快照。这个机制可以理解为“懒人自动备份”平时不用管它。但如果你做的是订单、支付这类要求数据不丢的业务建议把AOF也打开appendonly yes appendfilename appendonly.aof appendfsync everysecappendfsync有三个取值always每个写命令都刷盘最安全但性能最差everysec每秒刷一次盘兼顾性能与安全生产环境默认推荐no交给操作系统决定刷盘时机性能最好但断电可能丢较多数据我的体会是别迷信“AOF必须always”这种极端说法实际业务里everysec最多丢一秒数据绝大多数场景都能接受。如果你连这一秒都不能丢应该去考虑真正的分布式事务方案而不是纠结Redis的刷盘策略。4.3 资源相关最大内存与淘汰策略Redis最核心的价值是缓存那就必然要面对“内存满了怎么办”的问题。默认配置下写满会直接报OOM command not allowed这显然不是我们想要的。一般都会设置最大内存和淘汰策略maxmemory 512mb maxmemory-policy allkeys-lrumaxmemory-policy常见选择就几种我帮大家理清楚noeviction写满后不淘汰写操作直接报错默认。allkeys-lru从所有key里按LRU淘汰最少使用的最常用。volatile-lru只从设置了expire过期时间的key里按LRU淘汰。allkeys-lfu按访问频次淘汰适合“有些key虽然最近没访问但访问频次很高”的场景。很多新手把缓存全设成永久key然后内存直线飙升这就是没理解淘汰策略。我一般在设计阶段就会把“哪些缓存需要设TTL、哪些绝不能淘汰”先列出来再决定用volatile-lru还是allkeys-lru。如果业务上有绝对不能丢的“关键数据”就单独放到另一个实例或者不设过期时间避免被LRU一把梭。5. Redis的五大核心数据类型与高频命令装好、配好、连上之后接下来就是实打实的使用环节。Redis之所以这么好用很大程度上是因为它不只是个“key-value数据库”它内部有丰富的数据结构。下面我挑最常用的几个说说使用场景和要注意的点。5.1 String字符串最基础也最容易被低估String是Redis里最通用的数据类型不仅存普通文本还能存数字和二进制数据。核心命令几乎是约定俗成SET key value # 设置 GET key # 获取 SETEX key 60 value # 设置并带60秒过期 SETNX key value # key不存在才设置分布式锁的基础 INCR key # 自增1计数器场景实际踩坑很多人把对象整个序列化成JSON塞进String里这没问题但要注意单个value过大。一个key对应的value动不动就几MB甚至几十MBRedis的处理性能会明显下降因为大key的读写和内存拷贝成本都高。我通常建议单个String的value控制在1MB以内如果真有大数据对象建议拆分字段用Hash存。5.2 Hash哈希对象数据的最佳拍档Hash特别适合存“对象”型数据比如用户信息、商品详情它可以单独修改某个字段而不需要整体反序列化HSET user:1001 name 小明 age 18 HGET user:1001 name HGETALL user:1001 HINCRBY user:1001 age 1对比String存JSONHash的优势是按需读写字段不会因为改一个字段就传整个大对象。劣势是嵌套复杂对象时表达力不足如果value本身还有列表就还得序列化。我的经验是电商购物车、用户资料这种结构较扁平的用Hash跨系统传输的复杂协议体用String存JSON反而更方便。5.3 List列表消息队列与时间线场景List本质上是一个双向链表头尾操作是O(1)LPUSH task:queue job1 RPUSH task:queue job2 LPOP task:queue BLPOP task:queue 0 # 阻塞式弹出常用于简化版消息队列 LRANGE task:queue 0 -1不过这里必须说一句Redis List做消息队列功能其实很简陋没有消息确认、没有回溯消费、没有消费组。如果你只是“临时塞个任务、丢个通知”还能凑合真要搞可靠消息队列请转向专业消息中间件。很多事故就是因为把Redis List当成万能队列消息丢了都不知道。5.4 Set与ZSet去重、排行、标签体系Set是无序且自动去重的集合SADD tag:user 1001 1002 1003 SMEMBERS tag:user SISMEMBER tag:user 1001 SINTER tag:user tag:vip # 集合交集ZSet有序集合则是在Set基础上增加了一个score字段按score排序最适合排行榜场景ZADD leaderboard 100 playerA ZADD leaderboard 90 playerB ZINCRBY leaderboard 5 playerA ZREVRANGE leaderboard 0 9 WITHSCORES # 取Top10这里提醒新手ZSet的score只能是“数值”如果你业务里的权重是“字符串形式的数字”要先转成数字再写入否则返回排序结果会不符合预期。还有ZSet底层是跳表加哈希表内存占用比普通Set高别动不动啥数据都往里塞。5.5 过期时间人人都知道但很多人用错给key设置过期时间是缓存开发的基本素养SET key value EX 60 EXPIRE key 60 TTL key # 查看剩余存活时间我见过最经典的错误是用SET带上过期时间但每次业务更新时又用不带过期时间的SET覆盖导致过期时间丢失key成了永久key。正确做法是更新时也要带上过期时间或者封装一层统一的缓存写入方法保证每次SET都传入TTL。6. 可视化客户端装是装上了怎么连才舒服命令行固然强大但日常工作里用可视化客户端看数据、排查问题要方便得多。这里就避不开搜索热词里反复出现的“redis desktop manager”和“another redis desktop manager”。6.1 Redis Desktop ManagerRDM老牌可视化客户端界面直观支持键值浏览、常用命令执行、TTL查看、执行日志等。现在新版部分功能开始收费但基础功能免费。连接配置里需要注意地址不要填localhost除非Redis就在你本机填实际IP。端口默认6379。密码如果配置文件里设置了requirepass这里必须填否则连接会提示NOAUTH。数据库编号默认选0号库即可除非你业务里明确用了多个database。6.2 Another Redis Desktop ManagerAnother RDM这个是开源的替代品目前更新也还算勤快亲测连大key时性能比老RDM顺滑一些。功能上支持树状key浏览、批量删除、命令监控面板做本地排查够用了。如果说RDM更像“全功能IDE”Another RDM则更轻快两台都装上也不冲突。6.3 最推荐的连接排查姿势命令空间视角无论用什么客户端我建议你培养一个习惯用Keys搜索时别直接全量模糊搜索。生产环境key数量往往几十万上百万直接遍历所有key会阻塞Redis主线程准确说是开启KEYS命令时有可能长时间阻塞。正确做法是在客户端里用SCAN命令替代KEYS或者按前缀精确匹配去浏览。可视化客户端内部一般已经封装了SCAN但你自己在命令行里执行时一定要有这个意识。7. 用Docker快速搭一套主从复制从单机到高可用的第一步搜索热词里出现了“docker安装redis主从”这确实是一个非常典型的进阶需求。主从复制解决的是“单点故障导致数据不可用”的问题核心思路就是准备一台主库和至少一台从库从库自动复制主库的数据主库挂了以后可以把读流量切到从库甚至把从库提升为主库。7.1 搭一套最简主从假设我们用两个容器主库端口6379从库端口6380# 主库容器 docker run --name redis-master -d -p 6379:6379 redis:7.2-alpine # 从库容器关键是通过 --replicaof 声明主库地址 docker run --name redis-replica -d -p 6380:6379 \ redis:7.2-alpine \ redis-server --replicaof 127.0.0.1 6379这里有一个非常隐蔽的坑如果你在Windows / Mac本机上用Docker Desktop容器里的127.0.0.1指向的是容器自己而不是宿主机的6379端口。所以上面从库里的--replicaof 127.0.0.1 6379大概率是连不上的。正确写法是在同一Docker网络下使用容器名互联docker network create redis-net docker run --name redis-master -d --network redis-net -p 6379:6379 redis:7.2-alpine docker run --name redis-replica -d --network redis-net -p 6380:6379 \ redis:7.2-alpine \ redis-server --replicaof redis-master 63797.2 验证主从是否生效# 进入从库容器查看角色 docker exec -it redis-replica redis-cli info replication输出里看到role:slave并且master_link_status:up说明复制链路是通的。这时候在主库写一个key再到从库查询docker exec -it redis-master redis-cli set foo bar docker exec -it redis-replica redis-cli get foo # 返回 bar说明数据已同步7.3 主从复制里最需要注意的三个问题从库默认是只读的。你在从库上执行写命令会报错提示READONLY这是正常现象别慌。主库崩溃后从库不会自动提升。主从复制只负责数据同步不负责故障转移要自动选举主库还需要引入Redis Sentinel那是另一个话题了。主从节点都别用--appendonly no。虽然纯缓存场景可以不开持久化但主从复制过程中如果主库突然宕机内存里没来得及同步的数据一样会丢。生产环境我倾向主从实例都打开AOF一方面保证节点重启后数据可恢复另一方面减少全量重新同步的概率。8. 常见安装与使用问题排查思路最后一部分我按自己踩过坑的频率把安装和使用阶段最容易遇到的问题列出来。这套排查路径基本能覆盖前面所有安装方式。8.1 报错Could not connect to Redis at 127.0.0.1:6379: Connection refused按顺序排查这几步服务是否真的启动了ps -ef | grep redis或docker ps确认。启动时到底绑定了哪个IP别猜直接看配置文件里的bind或者用ss -lntp | grep 6379看监听地址。如果是远程连接防火墙是否放行了6379云服务器安全组、本地iptables/firewalld都要查一遍。确认Redis是否处于protected-mode拒绝连接状态——日志里通常会有Denied ... from字样的提示。提醒不要一上来就把bind 127.0.0.1注释掉来解决连接问题先搞清楚“客户端到底应该从哪个IP来访问”。8.2 报错NOAUTH Authentication required这个最直白配置文件里设置了requirepass而你连接时没有带密码。redis-cli连接后先执行AUTH yourpassword连接串也可以直接带redis-cli -a yourpassword但-a方式会在命令行历史里暴露密码生产环境慎用。更推荐用REDISCLI_AUTH环境变量或者干脆进入交互后手动AUTH。8.3 启动报错Cant open the log file: Permission denied运行Redis的用户对日志目录没有写权限。这类问题在源码编译安装后特别常见因为你是用普通用户编译但启动时用了root或相反。解决办法把日志和配置目录的owner改成运行Redis的用户或者让systemd服务脚本里指定正确的User或者干脆把日志路径指到/var/log/redis这类权限规范的位置。8.4 Docker容器频繁重启docker logs redis-prod看有没有Fatal error。除了配置文件语法错误外最常见的还有容器启动时指定的redis-server参数引用了不存在的配置文件导致进程直接退出。还有一种是端口被宿主机的其他进程占用了把宿主机端口换一个即可。8.5 数据篇为什么重启后什么都没了一句话回答你没有开启持久化或持久化文件没有被正确加载。先确认配置里的save和appendonly。如果开了持久化但重启后数据还是丢了去dir配置的目录下看是否有dump.rdb或appendonly.aof没有的话说明写入过程没有触发持久化。还有一种情况是Redis是正常退出时才会生成RDB文件如果被你用kill -9强杀数据就可能丢。排查时还可以看启动日志里有没有DB loaded from disk: 0.005 seconds有这行说明它确实从持久化文件加载了没这行说明加载逻辑压根没跑。8.6 线上Redis突然变慢这个不会直接在安装阶段暴露但用久了大概率遇到。先看SLOWLOGSLOWLOG GET 10返回的慢查询里最常见的三个原因运行了KEYS *这样的全量扫描命令我建议一律改用SCAN。有大key存在比如一个Hash里有几十万个field操作它时主线程就会卡顿。AOF重写或RDB快照fork时由于内存大加上系统负载高会短暂阻塞。9. 从安装到上手的几点心得这篇教程陪你走完了Redis从下载安装、配置启动、命令使用、可视化连接、主从复制到问题排查的完整路径。最后分享几条我自己的体会算是这些年折腾Redis攒下来的私货。如果你是纯新手第一次装Redis我建议别想着“一步到位”。先在本机用最简单的方式跑起来执行一下SET/GET、LPUSH/LPOP、HGETALL把数据类型的感觉找着了再去折腾Docker、主从、哨兵这些进阶内容。学习曲线太陡反而容易劝退。配置文件这块我强烈建议养成“版本化管理”的习惯把redis.conf存到Git仓库里改动时留下记录。你永远不知道哪一次改完配置后线上出了诡异问题能git回滚真的是救命。还有我一直强调的安全习惯给Redis设密码永远不要裸奔。就算只是内网测试环境也建议设一个简单密码因为内网不等于安全。我之前在云服务器上亲眼见过一台没设密码的Redis被写入挖矿配置的记录两三分钟内连接数就暴涨到几千。不要以为“这种情况不会发生在我身上”。至于持久化策略我的原则是能开AOF就开everysec足够绝大多数场景RDB快照也留着两者互补比二选一更省心。如果你照着这篇教程走到这里其实已经超过了大多数“装了Redis但说不清它怎么干活”的开发同学。剩下的路就是把它真正用进你的项目里在缓存穿透、缓存击穿、缓存雪崩这些实战问题中一点点加深理解。Redis这东西你越用越会觉得它设计得巧妙也越能体会到“越简单的工具越值得认真对待”。
返回列表