ARTICLE DETAIL

资讯详情

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

Redis 入门(一):Redis 是什么,为什么后端都离不开它

Redis 入门(一):Redis 是什么,为什么后端都离不开它 个人主页 我不会起名字322 欢迎各位大佬莅临其他栏目 技术栈学习笔记 其他栏目 力扣Hot100题目解析 其他栏目 Go项目学习笔记 文章目录Redis 入门一Redis 是什么为什么后端都离不开它一、Redis 到底是什么1.1 一句话定位1.2 它不是 MySQL 的替代品1.3 Redis 为什么快1.4 四个最典型的使用场景二、把 Redis 装上2.1 Linux 源码编译安装2.2 用包管理器安装2.3 Docker 一条命令起一个三、启动、关闭与配置3.1 两种启动方式3.2 三种关闭方式3.3 redis.conf 里新手最该先看的五个参数四、第一次用 redis-cli 连上并验证4.1 连接4.2 依次验证这几条4.3 不进入交互模式直接用五、常见启动报错与排查小结Redis 入门一Redis 是什么为什么后端都离不开它这篇只干一件事把 Redis 的定位讲清楚再带你从零把它装起来、启动、连上、跑通几条命令。适合刚开始学后端、还没有真正用过缓存的同学也适合环境荒废很久、想重新把 Redis 跑起来的开发者。看完之后你应该能独立完成一次安装与验证并且知道配置文件里哪几个参数先别乱改。一、Redis 到底是什么1.1 一句话定位Redis 的全称是 Remote Dictionary Server直译过来就是远程字典服务。它的核心特征只有两条数据放在内存里组织方式是 key-value然后通过网络把读写能力开放给别的进程。这句话里远程两个字很关键。如果只是单个程序自己用那用语言内置的 Map 就够了没必要再引入一个中间件。真正的价值出现在多台机器、多个服务需要共享同一份状态的时候——这时候某个进程的内存变量没法给别的进程看而 Redis 可以。所以更准确的说法是Redis 是一个基于网络的内存数据存储服务它同时具备缓存和数据库两种角色。1.2 它不是 MySQL 的替代品两者的差异从存储介质就开始了维度MySQLRedis数据落在哪磁盘为主内存为主组织方式表 / 行 / 列key-value定位全量、可靠地保存数据快速读取热点数据容量大可以分库分表受内存限制单机通常几十 GBMySQL 面对的问题不是不可靠而是每次查询都要碰磁盘慢。互联网业务里读操作往往远多于写操作如果每次都打到 MySQL数据库很快就会成为瓶颈。业界的经典做法是二八原则把访问最频繁的那 20% 数据放进 Redis让它承接 80% 的读请求剩下的全量数据仍然老老实实存在 MySQL 里。这里有个新手最容易忽略的点一旦引入 Redis 缓存就凭空多出了两边数据可能不一致的问题。所以缓存的定位是加速不是权威数据源。Redis 挂了、数据被清了业务应该还能从 MySQL 重新加载回来而不是直接崩掉。1.3 Redis 为什么快面试常问但答案不该只背因为它在内存里。主要有四点内存操作。读写内存和读写磁盘差着好几个数量级这是最根本的原因。数据结构简单高效。Redis 底层自己实现了动态字符串、跳表、压缩列表等结构大部分命令的复杂度是 O(1) 或 O(log N)不存在 SQL 解析、执行计划、多表关联这一整套开销。网络模型用了 IO 多路复用。单个线程配合 epoll 之类的机制就能同时盯住成千上万个连接避免了为每条连接开一个线程。核心命令走单线程。不需要加锁也就没有线程切换和锁竞争的开销。顺便澄清一个常见误解Redis 6.0 之后确实引入了多线程但多线程只用在了网络收发这类 IO 处理上命令的执行依旧是单线程。所以Redis 是单线程这个说法在今天依然基本成立。1.4 四个最典型的使用场景缓存最常见的用法。热点商品详情、首页配置、用户基础信息先查 Redis没有再回查 MySQL 并写回缓存。分布式锁多台机器要争抢同一个资源比如定时任务只允许一个节点执行靠 Redis 的 SET NX 加上过期时间来做互斥。计数器文章阅读量、接口调用次数、点赞数。Redis 的原子自增命令天然适合而且不用担心并发覆盖。排行榜游戏积分榜、热搜榜。Redis 自带按分数排序的数据结构插入和取 Top N 都很轻松。会话共享把 session 从单机挪到 Redis、简单的消息队列也在使用范围之内但业内有更专业的选择不必强求。二、把 Redis 装上下面三条路任选其一即可。生产环境的正确选择是 LinuxWindows 上用官方移植版或者干脆上 Docker / WSL。2.1 Linux 源码编译安装想用最新版本、或者需要自己调编译参数时选它# 1. 装编译依赖以 CentOS 为例Ubuntu 换成 build-essentialyuminstall-ygccmakewget# 2. 下载并解压源码包cd/usr/local/srcwgethttps://download.redis.io/releases/redis-7.2.4.tar.gztar-zxvfredis-7.2.4.tar.gz# 3. 编译并把可执行文件装到 /usr/local/bincdredis-7.2.4makemakeinstall# 4. 准备配置文件和目录mkdir-p/etc/redis /var/lib/rediscpredis.conf /etc/redis/redis.confmake这一步如果报错说找不到jemalloc可以改用make MALLOClibc。编译完成后redis-server、redis-cli都在/usr/local/bin下任何目录都能直接调用。2.2 用包管理器安装图省事就用系统仓库的版本缺点是版本通常偏旧# Ubuntu / Debiansudoaptupdatesudoaptinstall-yredis-server# CentOS / RHEL需要先装 EPEL 源sudoyuminstall-yepel-releasesudoyuminstall-yredis用包管理器装完会自动注册 systemd 服务配置文件在/etc/redis/redis.confCentOS 是/etc/redis.conf。2.3 Docker 一条命令起一个本地开发、临时验证场景这是最省心的方式dockerrun-d\--nameredis-dev\-p6379:6379\-vredis-data:/data\redis:7.2\redis-server--appendonlyyes--requirepass123456几个参数值得说明-p把容器端口映射到宿主机-v挂一个数据卷否则容器删了数据也一起没了命令末尾的--appendonly yes打开 AOF 持久化--requirepass直接设密码。注意这里的密码写在启动命令里只适合开发环境生产上应该走配置文件或密钥管理。三、启动、关闭与配置3.1 两种启动方式前台启动调试用关掉终端进程就结束redis-server /etc/redis/redis.conf成功后会看到一段 ASCII 图案、版本号、监听端口 6379以及Ready to accept connections。systemd 托管推荐的长期运行方式sudosystemctl start redis-serversudosystemctlenableredis-server# 开机自启sudosystemctl status redis-server3.2 三种关闭方式# 方式一客户端命令会触发一次保存最优雅redis-clishutdown# 方式二systemdsudosystemctl stop redis-server# 方式三暴力杀进程不推荐可能丢数据kill-9PID3.3 redis.conf 里新手最该先看的五个参数# 只监听本机回环地址最安全的默认值 bind 127.0.0.1 -::1 # 监听端口也是 redis-cli 默认连接的端口 port 6379 # 是否以后台守护进程方式运行 daemonize no # 访问密码注释掉表示不需要密码 requirepass yourStrongPassword # 保护模式没有密码且对外暴露时的一道兜底防线 protected-mode yes逐个说清楚bind默认只绑本机。要让别的机器连过来必须改成bind 0.0.0.0但这等于把服务暴露到网络上务必同时设置requirepass。更稳妥的做法是绑内网网卡 IP。port改成非 6379 可以减少被扫描的概率改完客户端要加-p。daemonize自己手动跑redis-server时设成yes可以让它转入后台。但用 systemd 托管时应该保持no因为 systemd 本身就在管后台进程daemonize yes会让它 fork 出去systemd 追踪不到主进程出现服务显示启动成功但实际已退出的诡异现象。requirepass设了之后所有客户端都必须先认证。配置里如果还写了masterauth主从之间也要一致。protected-mode这是 Redis 3.2 引入的兜底机制。当既没有设密码、又监听了非回环地址时它会拒绝外部连接并返回一段 DENIED 提示。它是防呆而不是防护正确做法是配好密码和 bind而不是简单地把protected-mode no一关了事。四、第一次用 redis-cli 连上并验证redis-cli有两个使用形态交互式进去之后一直敲命令和一次性执行把命令当参数传进去结果打印到标准输出。下面主要用交互式。4.1 连接# 本机默认端口直接进redis-cli# 指定主机端口密码并直接进 0 号库redis-cli-h127.0.0.1-p6379-a123456进入后会看到提示符127.0.0.1:6379代表已连上并且默认处于 0 号库。注意-a会把密码暴露在 shell 历史和ps输出里Redis 也会打印一行告警生产环境建议改用REDISCLI_AUTH环境变量。4.2 依次验证这几条127.0.0.1:6379pingPONG用途最简单的存活探测。返回PONG说明连接通了。如果启用了密码而没认证这里会返回(error) NOAUTH Authentication required.先执行auth 123456即可。写健康检查脚本时可以用ping的返回值判断。127.0.0.1:6379setuser:1:nametomOK127.0.0.1:6379get user:1:nametom127.0.0.1:6379get user:2:name(nil)用途写入和读取一个 key。返回OK表示写成功取到不存在 key 时返回(nil)而不是报错写代码时不要把 nil 当成异常。注意 key 名是区分大小写的User:1和user:1是两个不同的 key命令名本身则不区分大小写。127.0.0.1:6379keys user:*1)user:1:name用途按通配符查看当前库里有哪些 key排查数据有没有写进去时很方便。但这条命令要慎用它是全量扫描key 数量一多就会阻塞整个实例生产环境严禁执行keys *。需要遍历时改用scan游标分批取。127.0.0.1:6379dbsize(integer)1用途返回当前库里 key 的总数。返回类型带(integer)前缀说明 Redis 的回复是分类型的字符串、整数、数组、错误、nil。如果希望输出更适合喂给脚本可以加--rawredis-cli--rawdbsize1127.0.0.1:6379select1OK127.0.0.1:6379[1]dbsize(integer)0127.0.0.1:6379[1]select0OK127.0.0.1:6379用途切换数据库。Redis 默认有 16 个库编号 0~15切换成功后提示符会多出[1]这样的标记一眼就能看出当前在哪个库。这里的库只是命名空间隔离不是分片多个库共用同一个单线程别把它当成隔离故障的手段。另外select只影响当前这个连接。127.0.0.1:6379info server# Serverredis_version:7.2.4 redis_mode:standalone os:Linux5.15.0-91-generic x86_64 tcp_port:6379 uptime_in_seconds:132用途查看运行状态。不带参数会输出全部信息信息量很大建议按段查看比如info server看版本和运行模式、info memory看内存占用、info clients看当前连接数、info stats看命中率。排查内存怎么涨这么快时used_memory_human和mem_fragmentation_ratio是最先该看的两项。127.0.0.1:6379shutdownnot connected用途关停服务端。执行后当前连接会被服务端断开提示符变成not connected这属于正常现象不是报错。shutdown默认会在退出前保存一次 RDB 快照如果只是想断开客户端而让服务端继续跑应该按CtrlC或者输入quit。4.3 不进入交互模式直接用排查问题时经常只需要跑一条命令这时不必进交互模式redis-clipingredis-cli-a123456setweather sunny redis-cli-a123456get weather redis-cli-r5incr page:view# 连跑 5 次redis-cli--stat# 每秒刷新一次运行指标-r指定执行次数配合-i还能指定间隔秒数比如-r -1 -i 1 info memory可以一直循环输出内存信息。--stat会持续打印 keys、内存、连接数、请求数等增量指标比反复敲info直观得多。五、常见启动报错与排查1DENIED Redis is running in protected mode...连接被拒且提示里带protected-mode。原因是没设密码又对外监听。正确解法是二选一设置requirepass并把bind收窄到内网地址或者老老实实从本机连。不要为了图快直接关掉保护模式。2(error) NOAUTH Authentication required.服务端要求密码而客户端没认证。临时办法是在交互模式里执行auth 你的密码长期办法是连接时带-a或者设置环境变量REDISCLI_AUTH。顺带一提requirepass改完之后必须重启或执行config rewrite才对外生效改完忘了重启是最常见的密码明明设了却没生效。3Could not connect to Redis at 127.0.0.1:6379: Connection refused服务端根本没在跑或者不在这个地址端口上。排查顺序ps -ef | grep redis看进程在不在 →ss -lntp | grep 6379看端口有没有监听 → 检查bind和port配置是否和你连的一致。4Could not create server TCP listening socket *:6379: bind: Address already in use端口被占用通常是上一次的 Redis 没退干净。先找出占用者ss-lntp|grep6379# 或 netstat -tlnp | grep 6379确认是旧实例后正常关掉它或者改配置文件里的port换一个端口。别上来就kill -9容易丢数据。5启动成功但连接超时进程活着、端口也在监听但客户端连不上一般是防火墙或安全组没放行。云服务器上要同时检查系统防火墙和安全组规则。如果bind只写了127.0.0.1那外部无论如何都连不进来这点要先确认。6daemonize和 systemd 打架现象是systemctl start显示成功但systemctl status立刻变成 inactive。因为daemonize yes会让 Redis fork 到后台systemd 认为主进程已经退出。用 systemd 托管时把daemonize设为no让 systemd 自己管前后台。7改完配置没生效Redis 读的是你启动时指定的那份配置文件路径写错就会用内置默认值。启动时用redis-server /etc/redis/redis.conf显式指定路径启动日志的第二行会打印实际加载的配置文件名对不上就说明路径错了。小结这一篇我们把 Redis 的定位讲清了它是靠内存和网络提供 key-value 读写能力的服务擅长缓存、分布式锁、计数器和排行榜和 MySQL 的分工是热点加速与全量可靠接着走完了源码、包管理器、Docker 三条安装路线理清了bind、port、daemonize、requirepass、protected-mode这五个先要弄明白的配置最后用ping、set/get、keys、dbsize、select、info、shutdown完成了一轮真实验证并覆盖了几类典型报错。现在你手里有了一个能连上的 Redis但往里存东西还只会用set和get。key 到底能设计成什么样、除了字符串还能存哪些结构、什么场景该用哪种结构这些是下一步真正要解决的问题——下一篇我们看 Redis 的五大数据类型以及每个类型最常用、最容易踩坑的那几条命令。
返回列表