Redis
灵魂拷问:啥场景?哪儿用?为啥非它不可?
咱们先别急着敲代码,得先搞清楚为什么要请Redis这尊"大佛"。
想象一下,如果你的数据量其实不大(比如就几万个配置项),但是访问量却大得像早晚高峰的地铁(每秒几万次查询),这时候如果让MySQL去抗,那简直就是在虐待硬盘。MySQL走的是硬盘(哪怕是SSD也有IO瓶颈),就像你要去图书馆查资料,得走路、找书架、抽书,这一套流程下来,高并发下数据库直接累吐血。
最典型的例子就是首页广告 或者热点资讯 。这玩意儿谁都要看,但又不常变。如果每次刷新首页都要去MySQL里翻箱倒柜,服务器早就罢工了。而Redis走的是内存,就像把书直接背在脑子里,想啥时候调出来就啥时候调出来,速度是微秒级的。
所以,Redis就是个高性能的Key-Value(键值对)数据库,由C语言编写,读操作能飙到110,000次/秒,写操作也有81,000次/秒。它就是为了在高并发场景下,替MySQL分担压力而生的。
安装与启动:从入门到"入土"(划掉)精通
接下来是动手环节。虽然现在的包管理器很方便,但为了理解原理,我们还是按最原始的源码安装方式来走一遍,这样你才知道它肚子里卖的什么药。
首先,把压缩包扔到Linux服务器的 /usr/upload 目录下,然后解压它。
bash
cd /usr/upload
ll # 看看文件在不在,强迫症必备
tar -zxvf redis-3.0.0.tar.gz # 解压,释放它的灵魂
Redis是C写的,得先给它装个翻译官(编译器),不然它听不懂系统的指令。
bash
yum install gcc-c++
环境好了,就可以开始打造金身了。进入目录,执行编译,然后指定安装路径。
bash
cd /usr/upload/redis-3.0.0
make
make install PREFIX=/usr/local/redis
默认情况下,Redis是个"粘人精",它会占用你的终端窗口,你一关掉终端,它就挂了。我们需要修改配置文件,让它在后台默默守护(守护进程模式)。
bash
# 拷贝配置文件到安装目录
cp /usr/upload/redis-3.0.0/redis.conf /usr/local/redis/bin
# 修改配置
vim /usr/local/redis/bin/redis.conf
在配置文件里,找到 daemonize no,把它改成 daemonize yes。这一步至关重要,改完保存退出。
最后就是启动和测试了。
bash
cd /usr/local/redis/bin
./redis-server redis.conf # 启动服务
./redis-cli # 启动客户端,连接服务器
如果你看到 127.0.0.1:6379> 的提示符,恭喜你,Redis已经跑起来了!想关闭它的时候,别直接杀进程,优雅一点,用 ./redis-cli shutdown,这样能保证数据安全落地。
基本命令:跟Redis对话的艺术
进了 redis-cli 就像进了一个聊天室,你可以对它发号施令。
最常用的就是 keys *,这就像是点名,让Redis把所有存在的键都亮出来。如果你想知道某个键还在不在,用 exists key,返回1就是在,0就是没了。
Redis最强大的功能之一是自动过期,比如做验证码或者会话管理。用 expire key 秒数 给数据定个闹钟,时间一到它自动消失。想知道还有多久消失,就用 ttl key(Time To Live)。
对于计数器场景(比如点赞、浏览量),Redis简直是神器。incr key 让数值加1,decr key 让数值减1,原子操作,线程安全,比自己在代码里写锁要快得多。
bash
# 1. 查看所有key,看看现在库里都有啥
127.0.0.1:6379> keys *
(empty list or set) # 现在是空的
# 2. 存一个字符串,模拟存个用户信息
127.0.0.1:6379> set username "zhangsan"
OK
# 3. 查一下这个key存在吗
127.0.0.1:6379> exists username
(integer) 1 # 返回1表示存在
# 4. 模拟验证码场景,设置10秒后过期
127.0.0.1:6379> expire code 10
(integer) 1 # 设置成功
# 5. 看看还有几秒挂掉
127.0.0.1:6379> ttl code
(integer) 8 # 还有8秒
# 6. 模拟文章阅读量,自增
127.0.0.1:6379> set view_count 10
OK
127.0.0.1:6379> incr view_count
(integer) 11 # 变成了11
127.0.0.1:6379> incr view_count
(integer) 12 # 变成了12
# 7. 模拟点踩,自减
127.0.0.1:6379> decr view_count
(integer) 11 # 变回11
多数据库:Redis的"分身术"
很多人以为Redis只有一个数据库,其实它默认提供了16个数据库,编号从0到15。这就像一栋楼有16层,你可以通过 select 1 这样的命令在不同楼层之间穿梭。
但是要注意,Redis是单线程处理命令的,虽然分库了,但在高并发下切换数据库并不会带来性能提升,反而容易造成数据管理混乱,所以生产环境通常只用0号库。
如果你想清空数据,有两个选择:flushdb 是清空当前这一层楼的数据,flushall 则是毁灭性的,清空整栋楼(所有数据库)的数据,慎用!
bash
# 1. 默认我们在0号库
127.0.0.1:6379> select 0
OK
# 2. 在0号库存个数据
127.0.0.1:6379> set db0_data "我是0号库的数据"
OK
# 3. 切换到1号库
127.0.0.1:6379> select 1
OK
# 4. 在1号库存个数据
127.0.0.1:6379[1]> set db1_data "我是1号库的数据"
OK
# 5. 切回0号库,看看刚才的数据还在不在
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> get db0_data
"我是0号库的数据" # 还在
# 6. 清空当前库(0号库)
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> get db0_data
(nil) # 没了
# 7. 去1号库看看,刚才的数据还在吗
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get db1_data
"我是1号库的数据" # 还在,flushdb只杀当前库
持久化:断电了数据还在吗?
这是面试必问,也是生产环境最核心的问题。内存虽快,但它是易失的,断电就失忆。为了不让数据裸奔,Redis搞了两套方案:RDB和AOF。
RDB (Redis DataBase) 是默认开启的。它的原理是"拍快照"。每隔一段时间,Redis会fork一个子进程,把内存里的数据全部 Dump 到硬盘上,生成一个 dump.rdb 文件。
配置策略通常写在配置文件里,比如 save 900 1 表示900秒内至少有1个key变了,就存一次;save 60 10000 表示60秒内有1万个key变了,就存一次。
RDB的优点是恢复数据极快,而且文件紧凑,适合做冷备份。缺点是可能会丢数据。比如在900秒的间隔内,你刚写完数据,还没来得及拍快照,服务器就断电了,那最后一次快照后的数据就全没了。
AOF (Append Only File) 则是另一种思路:存命令。你每敲一个写命令(如set),它就把它记在小本本(appendonly.aof)上。重启的时候,Redis会把小本本上的命令重新执行一遍,数据就回来了。
AOF默认是关闭的,需要在配置文件里把 appendonly no 改成 appendonly yes。它的同步策略有三种:always(来一个写一个,最安全但最慢)、everysec(每秒同步一次,推荐,平衡了速度和安全)、no(看操作系统心情)。
AOF的优点是数据完整性高,顶多丢1秒数据。缺点是文件体积通常比RDB大,而且恢复数据时要把命令重放一遍,速度比RDB慢。
在生产环境中,通常建议混合使用:用RDB做冷备份(比如每天半夜存一次),用AOF做实时恢复(每秒同步)。这样既保证了恢复速度,又保证了数据安全。
bash
# --- RDB 实验 ---
# 1. 找到你的 dump.rdb 文件位置(通常在 /usr/local/redis/bin 目录下)
# 2. 删掉它,模拟全新开始
rm -f dump.rdb
# 3. 启动 Redis
./redis-server redis.conf
# 4. 存个数据
127.0.0.1:6379> set rdb_test "rdb数据持久化测试"
OK
# 5. 优雅关闭,触发保存
127.0.0.1:6379> shutdown
# 6. 再次启动
./redis-server redis.conf
# 7. 查数据,发现还在!说明RDB生效了
127.0.0.1:6379> get rdb_test
"rdb数据持久化测试"
# --- AOF 实验 ---
# 1. 修改配置文件 redis.conf
# 把 appendonly no 改为 appendonly yes
# 把 appendfsync no 改为 appendfsync everysec
# 或appendfsync always
# 2. 重启 Redis
./redis-server redis.conf
# 3. 存个数据
127.0.0.1:6379> set aof_test "aof数据持久化测试"
OK
# 4. 等待1秒(让AOF刷盘)
# 5. 强制杀掉进程(模拟断电,不优雅关闭)
kill -9 <redis进程ID>
# 6. 再次启动
./redis-server redis.conf
# 7. 查数据,发现还在!说明AOF生效了,数据没丢
127.0.0.1:6379> get aof_test
"aof数据持久化测试"
主从复制:找个"备胎"防身
单机Redis再强,也有挂掉的一天。为了保证高可用,我们需要搞"主从复制"。
这个过程其实很简单:
从节点(Slave)启动后,会向主节点(Master)发送 sync 命令,说"大哥,我想跟你混"。
主节点收到后,会触发一次RDB快照,把数据文件发给从节点。
从节点加载完数据后,主节点之后收到的每一个写命令,都会实时转发给从节点,保证大家的数据是一致的。
配置起来非常简单:
主节点(Master):啥都不用配,躺着就行,自带大佬气质。
从节点(Slave):在配置文件里加一句 slaveof masterIp masterPort,或者在命令行敲 slaveof 192.168.x.x 6379。
测试的时候你会发现,往主节点写数据,从节点立马就能读到。但是,如果主节点挂了,从节点会发现自己没老大了。这时候要注意,默认情况下,从节点只能读,不能写(因为写了也没人同步给它,数据会乱)。
bash
# --- 准备工作 ---
# 假设你有两台Redis,或者在同一台机器开了两个端口
# 主节点(Master): 6379
# 从节点(Slave): 6380
# --- 配置从节点 ---
# 方法一:修改 6380 的 redis.conf 配置文件
# 添加一行:slaveof masterIp masterPort(换成主节点的ip和端口)
# 方法二:直接在 6380 的客户端命令行敲(临时生效)
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
# --- 测试同步 ---
# 1. 在主节点(6379)写数据
127.0.0.1:6379> set master_data "我是主节点的数据"
OK
# 2. 去从节点(6380)读数据
127.0.0.1:6380> get master_data
"我是主节点的数据" # 哇!秒同步!
# --- 测试主节点挂了 ---
# 1. 把主节点(6379)关掉
127.0.0.1:6379> shutdown
# 2. 尝试在从节点(6380)写数据
127.0.0.1:6380> set slave_write "我想写数据"
(error) READONLY You can't write against a read only replica.
# 报错!提示只读!说明从节点虽然活着,但为了保护数据一致性,禁止写入。
这就是Redis的基础架构。它就像是一个极速的缓存层,挡在应用和数据库之间,用内存换时间,用主从换高可用。掌握了这些,你就拿到了高并发系统的入场券。