在互联网高并发、大数据量的场景下,传统关系型数据库的性能瓶颈日益凸显,非关系型数据库(NoSQL)应运而生。Redis 作为 NoSQL 家族中的佼佼者,以其高性能、丰富的数据类型和灵活的应用场景,成为后端开发中不可或缺的技术栈。本文将从 NoSQL 概述入手,全面讲解 Redis 的核心知识点,包括安装部署、数据类型、常用命令及应用场景,帮助读者快速掌握 Redis 的使用精髓。
一、NoSQL 概述
1. 关系型数据库的局限
关系型数据库(如 MySQL、Oracle)基于二维表格模型,具备格式统一、SQL 通用、数据持久化安全等优势,但在海量数据场景下存在明显短板:
- 读写性能差,无法满足高并发的高效读写需求;
- 存储空间利用率低,空字段仍需分配空间;
- 表结构固定,灵活度低,难以适配快速变化的业务需求。
2. NoSQL 的核心优势
NoSQL(Not Only SQL)即非关系型数据库,数据存储无固定格式,支持横向扩展,核心优势如下:
- 存储格式灵活:支持 key-value、文档、图片等多种格式;
- 性能卓越:可基于内存存储,读写速度远超传统数据库;
- 扩展性强:分布式架构适配海量数据,扩展简单、高并发、高稳定;
- 成本低廉:部署和维护成本远低于关系型数据库集群。
3. NoSQL 与关系型数据库的互补
两者并非对立,而是互补关系:
- 关系型数据库:负责核心业务数据的持久化存储,保证数据完整性;
- NoSQL:负责热点数据缓存、高并发场景的快速读写,弥补关系型数据库的性能短板。
典型实践:京东商品分类信息先从 MySQL 查询,再缓存到 Redis,后续访问直接从 Redis 读取,大幅提升响应效率。
4. 主流 NoSQL 产品分类
| 类型 | 代表产品 | 典型应用 | 核心优势 |
|---|---|---|---|
| 键值存储 | Redis、Tokyo Cabinet | 内容缓存、高访问负载 | 查询速度极快 |
| 列存储 | HBase、Cassandra | 分布式文件系统 | 可扩展性强、查找快 |
| 文档型 | MongoDB、CouchDB | Web 应用(结构化 Value) | 数据结构要求宽松 |
| 图形数据库 | Neo4J、InfoGrid | 社交网络 | 适配图结构算法 |
二、Redis 入门
1. Redis 是什么?
Redis(Remote Dictionary Server)是一款开源的、基于内存的键值对存储数据库,采用 C 语言编写,支持网络访问、可选持久化,具备极高的性能:
- 官方测试性能:50 个并发下,读速度 110000 次 / 秒,写速度 81000 次 / 秒;
- 支持多种数据类型:String、Hash、List、Set、Sorted Set,Redis6 新增 BitMaps、HyperLogLog、Geospatial。
2. Redis 核心应用场景
- 缓存:存储热点数据(用户信息、文章列表),提升访问效率;
- 实时排行榜:基于有序集合实现点赞、评论数排序;
- 消息队列:利用 List 结构实现简单的消息生产消费;
- 计数器:单线程模型避免并发问题,适用于点击数、访问量统计;
- 分布式 Session:集群架构下统一存储用户会话信息;
- 位操作:基于 BitMaps 实现签到、在线状态统计;
- 数据过期处理:支持毫秒级过期时间,适用于限时业务(秒杀、验证码)。
3. Redis 核心特性
- 持久化:支持将内存数据写入磁盘,重启后可恢复;
- 多数据类型:除基础 key-value 外,支持复杂数据结构;
- 高可用:支持主从复制、哨兵模式、集群模式;
- 原子性:所有操作要么全执行,要么全不执行;
- 丰富扩展:支持发布订阅、key 过期、Lua 脚本等。
4. Redis 安装部署
(1)Windows 安装(仅测试用)
- 下载压缩包:https://github.com/MicrosoftArchive/redis/releases;
- 解压至非中文目录,双击
redis-server.exe启动服务端; - 双击
redis-cli.exe启动客户端,执行ping测试连接,set name zhangsan/get name验证读写。
(2)Linux 安装(生产环境推荐)
# 1. 下载并解压安装包
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar xzf redis-5.0.8.tar.gz
cd redis-5.0.8
# 2. 安装依赖并编译
yum install gcc-c++
make && make install
# 3. 配置后台启动和远程访问
mkdir /usr/local/bin/redconf
cp redis.conf /usr/local/bin/redconf/
# 修改配置文件:daemonize yes(后台启动)、注释bind 127.0.0.1、protected-mode no、设置requirepass 密码
# 4. 启动服务
redis-server /usr/local/bin/redconf/redis.conf
# 5. 客户端连接
redis-cli -h 127.0.0.1 -p 6379 -a 密码
(3)Docker 安装(快速部署)
# 拉取镜像
docker pull redis
# 创建并启动容器
docker run -itd --name redis01 -p 6379:6379 redis
# 进入容器连接Redis
docker exec -it redis01 /bin/bash
redis-cli
5. Redis 基础配置与核心概念
(1)数据库默认配置
- Redis 默认提供 16 个数据库(DB0~DB15),可通过
select 8切换数据库; - 不同数据库数据隔离,
dbsize查看当前数据库 key 数量; - 常用命令:
keys *(查看所有 key)、flushdb(清空当前库)、flushall(清空所有库)。
(2)核心配置(redis.conf)
bind 0.0.0.0 # 允许所有IP访问
port 6379 # 默认端口
daemonize yes # 后台运行
protected-mode no # 关闭保护模式
requirepass 123456 # 设置连接密码
databases 16 # 数据库数量
logfile "/usr/local/log/redis.log" # 日志路径
(3)性能测试
Redis 自带redis-benchmark工具,支持并发和请求数测试:
# 100个并发连接,100000次请求测试
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
三、Redis 八大核心数据类型
1. Redis-key(通用操作)
所有数据类型均基于 key 操作,核心命令:
| 命令 | 作用 |
|---|---|
exists key |
判断 key 是否存在(1 存在 / 0 不存在) |
del key |
删除 key-value(返回删除数量) |
move key db |
将 key 移动到指定数据库 |
expire key second |
设置 key 过期时间(单位:秒) |
ttl key |
查看 key 剩余过期时间(-1 永久 /-2 已过期) |
type key |
查看 value 的数据类型 |
示例:
bash
运行
127.0.0.1:6379> set name qinjiang
OK
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> expire name 15
(integer) 1
127.0.0.1:6379> ttl name
(integer) 12
127.0.0.1:6379> type name
string
2. String(字符串)
Redis 最基础的类型,key 对应单个 value,二进制安全,最大存储 512MB,支持字符串、数字等格式。
核心命令
| 命令 | 作用 |
|---|---|
append key value |
向 value 尾部追加字符串 |
strlen key |
获取 value 字符串长度 |
incr/decr key |
数字值 + 1/-1(仅适用于数字) |
incrby/decrby key n |
数字值 ±n(n 为整数) |
getrange key s e |
获取字符串区间值(闭区间) |
setrange key o v |
从偏移量 o 开始替换 value |
setnx key value |
仅 key 不存在时设置(分布式锁核心) |
mset/mget |
批量设置 / 获取 key-value |
示例:
127.0.0.1:6379> set msg hello
OK
127.0.0.1:6379> append msg " world"
(integer) 11
127.0.0.1:6379> get msg
"hello world"
127.0.0.1:6379> incr age # age=20
(integer) 21
127.0.0.1:6379> mset k1 v1 k2 v2
OK
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"
应用场景
- 计数器(文章阅读量、商品销量);
- 缓存 JSON 字符串(用户信息、配置信息);
- 分布式锁(setnx 实现);
- 限时存储(setex 设置过期时间)。
3. List(列表)
基于双向链表实现的字符串列表,支持从头部 / 尾部插入 / 删除元素,可作为队列、栈使用。
核心命令
| 命令 | 作用 |
|---|---|
lpush/rpush key v1 v2 |
从左 / 右插入元素 |
lrange key s e |
获取区间元素(0 -1 表示全部) |
lpop/rpop key |
从左 / 右弹出元素 |
rpoplpush src dest |
从 src 尾部弹出,插入 dest 头部 |
lrem key count v |
删除 count 个值为 v 的元素(count>0 从左) |
blpop/brpop key timeout |
阻塞式弹出(无元素时等待超时) |
示例:
bash
运行
127.0.0.1:6379> lpush mylist k1 k2
(integer) 2
127.0.0.1:6379> rpush mylist k3
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "k2"
2) "k1"
3) "k3"
127.0.0.1:6379> lpop mylist
"k2"
应用场景
- 消息队列(lpush + rpop);
- 栈(lpush + lpop);
- 最新列表(如朋友圈动态、新闻列表)。
4. Set(集合)
无序、唯一的字符串集合,基于哈希表实现,增删查复杂度 O (1)。
核心命令
| 命令 | 作用 |
|---|---|
sadd key m1 m2 |
添加集合成员 |
smembers key |
查看所有成员 |
sismember key m |
判断成员是否存在(1 是 / 0 否) |
scard key |
获取成员数量 |
srandmember key n |
随机返回 n 个成员(不删除) |
spop key n |
随机弹出 n 个成员 |
sdiff/sinter/sunion |
差集 / 交集 / 并集 |
示例:
127.0.0.1:6379> sadd myset m1 m2 m3
(integer) 3
127.0.0.1:6379> smembers myset
1) "m3"
2) "m2"
3) "m1"
127.0.0.1:6379> sismember myset m2
(integer) 1
127.0.0.1:6379> scard myset
(integer) 3
应用场景
- 去重(如用户点赞、签到记录);
- 交集计算(如共同好友、共同关注);
- 随机抽奖(spop 随机弹出)。
5. Hash(哈希)
键值对的集合,适合存储对象(如用户信息:id、name、age),可单独操作对象的某个字段,节省内存。
核心命令
| 命令 | 作用 |
|---|---|
hset key f v |
设置哈希字段值 |
hget key f |
获取哈希字段值 |
hmset/hmget |
批量设置 / 获取字段 |
hgetall key |
获取所有字段和值 |
hdel key f |
删除指定字段 |
hlen key |
获取字段数量 |
hexists key f |
判断字段是否存在 |
示例:
127.0.0.1:6379> hset user id 1 name zhangsan age 20
(integer) 3
127.0.0.1:6379> hget user name
"zhangsan"
127.0.0.1:6379> hgetall user
1) "id"
2) "1"
3) "name"
4) "zhangsan"
5) "age"
6) "20"
应用场景
- 存储对象(用户、商品信息);
- 购物车(用户 ID 为 key,商品 ID 为字段,数量为值)。
6. Sorted Set(有序集合)
有序、唯一的字符串集合,每个成员关联一个分数(score),按分数排序,支持分数范围查询。
核心命令
| 命令 | 作用 |
|---|---|
zadd key s1 m1 s2 m2 |
添加成员(score+member) |
zrange key s e |
按分数升序获取区间成员 |
zrevrange key s e |
按分数降序获取区间成员 |
zscore key m |
获取成员的分数 |
zrank key m |
获取成员的升序排名 |
zrem key m |
删除指定成员 |
zcount key min max |
统计分数区间内的成员数 |
示例:
127.0.0.1:6379> zadd rank 90 zhangsan 85 lisi 95 wangwu
(integer) 3
127.0.0.1:6379> zrange rank 0 -1 withscores
1) "lisi"
2) "85"
3) "zhangsan"
4) "90"
5) "wangwu"
6) "95"
127.0.0.1:6379> zrevrange rank 0 1
1) "wangwu"
2) "zhangsan"
应用场景
- 实时排行榜(点赞数、销量、积分排序);
- 延时任务(score 为时间戳,按时间排序执行);
- 范围查询(如成绩区间、销量区间)。
7. BitMaps(位图)
基于 String 类型的位操作,每个位对应 0/1,适用于海量二进制状态存储(如签到、在线状态)。
核心命令
| 命令 | 作用 |
|---|---|
setbit key offset v |
设置指定偏移量的位值(0/1) |
getbit key offset |
获取指定偏移量的位值 |
bitcount key |
统计 1 的位数 |
示例:
127.0.0.1:6379> setbit sign 0 1 # 第0天签到
(integer) 0
127.0.0.1:6379> setbit sign 1 1 # 第1天签到
(integer) 0
127.0.0.1:6379> bitcount sign # 签到天数
(integer) 2
8. HyperLogLog(基数统计)
用于统计海量数据的基数(不重复元素数),占用内存极小(仅 12KB),适用于 UV、独立访客统计。
核心命令
| 命令 | 作用 |
|---|---|
pfadd key m1 m2 |
添加元素到 HyperLogLog |
pfcount key |
统计基数 |
pfmerge dest k1 k2 |
合并多个 HyperLogLog |
示例:
127.0.0.1:6379> pfadd uv user1 user2 user3
(integer) 1
127.0.0.1:6379> pfadd uv user2 user4
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 4
9. Geospatial(地理空间)
用于存储地理位置信息,支持经纬度添加、距离计算、范围查询。
核心命令
| 命令 | 作用 |
|---|---|
geoadd key lon lat m |
添加地理位置(经度、纬度、成员) |
geopos key m |
获取成员的经纬度 |
geodist key m1 m2 unit |
计算两个成员的距离(unit:m/km/mi) |
georadius key lon lat r unit |
按经纬度范围查询成员 |
示例:
127.0.0.1:6379> geoadd city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geodist city beijing shanghai km
"1067.3788"
四、总结
Redis 作为高性能的内存数据库,不仅是缓存工具,更是支撑高并发、海量数据场景的核心组件。掌握其核心数据类型和应用场景,结合关系型数据库的持久化优势,能极大提升系统的性能和稳定性。本文从基础概念到实战命令,覆盖了 Redis 的核心知识点,后续可深入学习 Redis 持久化(RDB/AOF)、主从复制、哨兵模式、集群等高级特性,进一步夯实 Redis 技术栈。