Redis 在 PHP 中的使用完全教程

安装配置 连接方式 数据类型操作 函数速查 扩展用法 最佳实践

一、Redis 概述

Redis(Remote Dictionary Server)是一个开源的、基于内存的键值对(Key‑Value)数据库,使用 ANSI C 语言编写。它不仅支持简单的字符串键值对,还提供了丰富的数据结构,包括字符串、哈希、列表、集合、有序集合、位图、HyperLogLog、流(Stream)等。Redis 将数据存储在内存中,因此读写速度极快,单机 QPS 可达十万级别,同时支持持久化(RDB / AOF)将内存数据写入磁盘,防止重启后数据丢失。

Redis 的核心特性包括:

  • 高性能:纯内存操作,读写延迟通常在亚毫秒级,单实例 QPS 可达 10 万以上。
  • 丰富数据结构:支持 String、Hash、List、Set、Sorted Set、Bitmap、HyperLogLog、Stream 等。
  • 持久化:支持 RDB(快照)和 AOF(追加日志)两种持久化方式,可组合使用。
  • 主从复制:支持一主多从架构,从节点自动同步主节点数据,实现读写分离。
  • 哨兵与集群:Sentinel 提供自动故障转移;Cluster 提供数据分片和高可用。
  • 过期机制:支持为键设置 TTL,到期自动删除,天然适合缓存场景。
  • 原子操作:单条命令保证原子性,支持事务(MULTI/EXEC)和 Lua 脚本。
  • 发布订阅:内置 Pub/Sub 消息模型,可用于实时消息推送。

Redis 在 PHP 项目中的典型应用场景:

  • 缓存:缓存数据库查询结果、页面片段、API 响应等,降低数据库压力。
  • 会话存储:将用户会话(Session)存储在 Redis 中,支持多服务器共享。
  • 计数器/限流:利用 INCR 实现访问计数、点赞数、接口限流。
  • 排行榜:利用 Sorted Set 实现实时排行榜功能。
  • 消息队列:利用 List 的 BLPOP/BRPOP 或 Stream 实现轻量级消息队列。
  • 分布式锁:利用 SET NX EX 实现分布式锁,保证并发安全。
  • 排行榜/延时队列:利用 Sorted Set 的 score 实现延时任务调度。

二、PHP Redis 扩展安装

PHP 中操作 Redis 有两种主流方式:

  1. phpredis 扩展(推荐):C 语言编写的 PHP 扩展,性能最高,由 PECL 维护,提供了面向对象的 API,是生产环境的首选。
  2. predis 客户端:纯 PHP 编写的 Redis 客户端库,通过 Composer 安装,无需编译扩展,但性能略低于 phpredis。

2.1 安装 phpredis 扩展

Linux 环境下通过 PECL 安装:

复制代码
pecl install redis

安装后在 php.ini 中添加扩展:

复制代码
extension=redis.so

安装完成后验证:

复制代码
php -m | grep redis
php --ri redis

2.2 安装 predis 客户端(备选方案)

如果无法安装 C 扩展,可使用 Composer 安装 predis:

复制代码
composer require predis/predis

本文所有代码示例均基于 phpredis 扩展(C 扩展版),即 Redis 类。predis 的 API 接口与 phpredis 高度相似但不完全一致,使用时需注意差异。

三、Redis 连接方式

3.1 基本连接(短连接)

使用 connect() 方法创建 Redis 连接,脚本结束时自动关闭:

复制代码
<?php
$redis=new Redis();
$redis->connect('127.0.0.1',6379,2.5);//主机、端口、超时时间(秒)
$redis->auth('your_password');//有密码时需要认证
$redis->select(0);//选择数据库(默认0)
$redis->set('test_key','HelloRedis');
echo $redis->get('test_key');//输出:HelloRedis
$redis->close();//显式关闭连接

connect() 方法参数说明:

参数 功能说明
host Redis 服务器地址,可为 IP 或域名,如 '127.0.0.1'/var/run/redis/redis.sock(Unix 套接字)
port Redis 端口,默认 6379。使用 Unix 套接字时端口设为 0
timeout 连接超时时间(秒),默认 0 表示不限制。浮点数表示毫秒级,如 2.5 秒
retry_interval 重连间隔(毫秒),连接失败时的重试等待时间,默认 0
read_timeout 读取超时时间(秒),默认 0 表示不限制

3.2 持久连接(长连接)

使用 pconnect() 创建持久连接,连接在脚本结束后不会关闭,后续请求可复用该连接,减少 TCP 握手开销:

复制代码
<?php
$redis=new Redis();
$redis->pconnect('127.0.0.1',6379,2.5);
//pconnect也可接受persistent_id参数,用于区分不同的连接池
$redis->pconnect('127.0.0.1',6379,2.5,'pool_1');

生产环境推荐使用 pconnect() 持久连接,配合 PHP‑FPM 进程常驻,可显著降低连接建立开销。注意每个 PHP‑FPM 进程会维持一个独立连接。

3.3 带认证的连接

Redis 6.0+ 推荐使用 ACL 用户认证,旧版本使用 requirepass 密码认证:

复制代码
<?php
$redis=new Redis();
$redis->connect('127.0.0.1',6379);
//方式一:旧版密码认证
$redis->auth('your_password');
//方式二:ACL用户名+密码认证(Redis6.0+)
$redis->auth(['user'=>'myuser','pass'=>'mypass']);
//方式三:连接时直接带认证信息
$redis->connect('127.0.0.1',6379,2.5,NULL,0,0,['auth'=>['user','pass']]);

3.4 连接参数数组方式(推荐)

phpredis 5.3+ 支持用数组参数一次性传入所有连接配置:

复制代码
<?php
$redis=new Redis();
$redis->connect([
    'host'=>'127.0.0.1',
    'port'=>6379,
    'timeout'=>2.5,
    'auth'=>['myuser','mypass'],
    'db'=>0,//选择数据库
    'retry_interval'=>100,//重连间隔(ms)
    'read_timeout'=>3.0,//读取超时
]);

3.5 SSL/TLS 加密连接

连接远程 Redis 时可启用 TLS 加密传输:

复制代码
<?php
$redis=new Redis();
$redis->connect('tls://redis.example.com',6379,2.5,
    NULL,0,0,
    ['stream'=>[
        'verify_peer'=>true,
        'verify_peer_name'=>true,
        'cafile'=>'/etc/ssl/certs/ca‑bundle.crt',
    ]
]);

3.6 predis 连接方式

复制代码
<?php
require 'vendor/autoload.php';
//单节点连接
$redis=new Predis\Client([
    'scheme'=>'tcp',
    'host'=>'127.0.0.1',
    'port'=>6379,
    'password'=>'your_password',
    'database'=>0,
]);
//集群连接
$redis=new Predis\Client([
    ['host'=>'10.0.0.1','port'=>6379],
    ['host'=>'10.0.0.2','port'=>6379],
    ['host'=>'10.0.0.3','port'=>6379],
],['cluster'=>'redis','parameters'=>['password'=>'secret']]);

3.7 连接相关函数汇总

方法 频率 说明
connect(host, port, timeout, ...) 常用 创建 Redis 短连接,脚本结束自动断开
pconnect(host, port, timeout, ...) 常用 创建 Redis 持久连接,跨请求复用
close() 常用 关闭当前连接
auth(password) 常用 Redis 密码认证
select(db) 常用 切换 Redis 数据库(0~15)
ping() 常用 发送 PING 命令测试连接,返回 true 或 '+PONG'
echo(msg) 非常用 发送 ECHO 命令,原样返回消息字符串
getAuth() 非常用 获取当前设置的认证密码
getDBNum() 非常用 获取当前选中的数据库编号
getHost() 非常用 获取当前连接的主机地址
getPort() 非常用 获取当前连接的端口号
isConnected() 非常用 判断当前是否已连接
getPersistentID() 非常用 获取持久连接的唯一标识

四、字符串(String)操作

String 是 Redis 最基本的数据类型,一个键对应一个值,值最大支持 512MB。String 可以存储文本、数字、序列化数据(JSON、PHP serialize)甚至二进制数据。它是 Redis 中使用频率最高的数据类型。

4.1 常用字符串函数

4.1.1 set() --- 设置键值

将字符串值关联到指定键。如果键已存在则覆盖旧值。

复制代码
<?php
$redis->set('name','Redis');
//带选项参数(phpredis5.0+)
$redis->set('user:1','Alice',['ex'=>3600]);//3600秒后过期
$redis->set('lock:1','owner1',['nx']);//仅当键不存在时设置
$redis->set('lock:2','owner2',['xx','ex'=>30]);//仅当键存在时设置,30秒过期
方法 功能说明
set(key, value) 设置键值,存在则覆盖。返回 true
set(key, value, 'ex' =\> seconds) 设置键值并指定过期时间(秒)
set(key, value, 'px' =\> ms) 设置键值并指定过期时间(毫秒)
set(key, value, 'nx') 仅当键不存在时设置(等同于 setnx)
set(key, value, 'xx') 仅当键已存在时设置
set(key, value, 'keepttl') 设置新值但保留原有 TTL
4.1.2 get() --- 获取值
复制代码
<?php
$redis->set('name','Redis');
echo $redis->get('name');//输出:Redis
var_dump($redis->get('not_exist'));//输出:bool(false)
4.1.3 del() --- 删除键
复制代码
<?php
$redis->set('key1','val1');
$redis->set('key2','val2');
$redis->del('key1');//删除单个键,返回删除数量
$redis->del(['key1','key2']);//批量删除
$count=$redis->del('k1','k2','k3');//返回实际删除数量
4.1.4 incr() / decr() --- 自增自减

原子操作,适合计数器场景。值必须为整数,否则报错。

复制代码
<?php
$redis->set('counter',100);
$redis->incr('counter');//101
$redis->decr('counter');//100
$redis->incrBy('counter',10);//110
$redis->decrBy('counter',5);//105
//浮点数自增
$redis->set('price','10.50');
$redis->incrByFloat('price',0.25);//10.75
4.1.5 setex() / psetex() --- 带过期的设置
复制代码
<?php
$redis->setex('token',3600,'abc123');//3600秒后过期
$redis->psetex('token2',5000,'xyz789');//5000毫秒(5秒)后过期
4.1.6 setnx() --- 不存在时设置

常用于分布式锁。键不存在时设置成功返回 true,已存在返回 false。

复制代码
<?php
$ok=$redis->setnx('lock:order:1001','client_1');
if($ok){
    $redis->expire('lock:order:1001',30);//设置过期防止死锁
    //执行业务逻辑...
}else{
    echo '锁已被占用';
}
4.1.7 mset() / mget() --- 批量操作
复制代码
<?php
//批量设置
$redis->mset([
    'user:name'=>'Alice',
    'user:age'=>'28',
    'user:city'=>'Beijing',
]);
//批量获取
$values=$redis->mget(['user:name','user:age','user:city']);
print_r($values);//['Alice','28','Beijing']
4.1.8 append() --- 追加字符串
复制代码
<?php
$redis->set('greeting','Hello');
$redis->append('greeting','World');//'HelloWorld'
echo $redis->strlen('greeting');//11
4.1.9 getSet() --- 设置新值并返回旧值
复制代码
<?php
$redis->set('counter','100');
$old=$redis->getSet('counter','200');//$old='100',当前值为'200'

4.2 非常用字符串函数

4.2.1 getRange() / setRange() --- 范围操作
复制代码
<?php
$redis->set('text','HelloWorld');
echo $redis->getRange('text',0,4);//'Hello'
$redis->setRange('text',6,'Redis');//'HelloRedis'
4.2.2 位操作函数
复制代码
<?php
$redis->set('bitmap','abc');
$redis->setBit('bitmap',10,1);//设置第10位为1
$bit=$redis->getBit('bitmap',10);//获取第10位
$count=$redis->bitCount('bitmap');//统计被设为1的位数

位操作适用于用户签到、在线状态等需要高效存储布尔标记的场景。

4.3 字符串函数速查表

方法 频率 说明
set(key, value, opts) 常用 设置键值,支持过期、NX/XX 等选项
get(key) 常用 获取键的值,不存在返回 false
del(key1, key2, ...) 常用 删除一个或多个键,返回删除数量
exists(key) 常用 判断键是否存在(存在返回1,可传多个键返回总数)
incr(key) 常用 值自增1,返回新值
decr(key) 常用 值自减1,返回新值
incrBy(key, int) 常用 值增加指定整数
decrBy(key, int) 常用 值减少指定整数
incrByFloat(key, float) 非常用 值增加指定浮点数
setex(key, ttl, val) 常用 设置键值并指定过期时间(秒)
psetex(key, ttl, val) 非常用 设置键值并指定过期时间(毫秒)
setnx(key, value) 常用 仅当键不存在时设置值
getSet(key, value) 常用 设置新值并返回旧值
mset(array) 常用 批量设置多个键值
mget(array) 常用 批量获取多个键的值
msetnx(array) 非常用 批量设置,仅当所有键都不存在时成功
append(key, value) 常用 在值末尾追加字符串
strlen(key) 常用 获取值的字符串长度
getRange(key, start, end) 非常用 获取值的子字符串
setRange(key, offset, val) 非常用 从指定偏移量覆写值
getBit(key, offset) 非常用 获取值指定位置的比特位
setBit(key, offset, val) 非常用 设置值指定位置的比特位
bitCount(key) 非常用 统计值中被设为1的比特数
bitOp(op, dest, key1, ...) 非常用 位运算(AND/OR/XOR/NOT)并存入 dest

五、哈希(Hash)操作

Hash 是一个键对应多个字段‑值(field‑value)对的结构,类似于 PHP 中的关联数组。Hash 非常适合存储对象,例如用户信息(姓名、年龄、邮箱等),相比将对象序列化为 String 存储,Hash 可以单独修改某个字段而无需读写整个对象。

5.1 常用哈希函数

5.1.1 hSet() / hGet() --- 设置和获取字段
复制代码
<?php
//设置单个字段
$redis->hSet('user:1','name','Alice');
$redis->hSet('user:1','age','28');
//获取单个字段
echo $redis->hGet('user:1','name');//Alice
var_dump($redis->hGet('user:1','email'));//false(字段不存在)
5.1.2 hMSet() / hMGet() --- 批量操作
复制代码
<?php
//批量设置多个字段
$redis->hMSet('user:1',[
    'name'=>'Alice',
    'age'=>'28',
    'email'=>'alice@example.com',
    'city'=>'Beijing',
]);
//批量获取多个字段
$fields=$redis->hMGet('user:1',['name','age','email']);
print_r($fields);
//['name'=>'Alice','age'=>'28','email'=>'alice@example.com']
5.1.3 hGetAll() --- 获取所有字段和值
复制代码
<?php
$all=$redis->hGetAll('user:1');
print_r($all);
//['name'=>'Alice','age'=>'28','email'=>'alice@example.com','city'=>'Beijing']
5.1.4 hDel() --- 删除字段
复制代码
<?php
$redis->hDel('user:1','email');//删除单个字段
$redis->hDel('user:1','email','city');//删除多个字段
5.1.5 hExists() / hLen() --- 判断和计数
复制代码
<?php
var_dump($redis->hExists('user:1','name'));//true
echo $redis->hLen('user:1');//字段数量,如3
5.1.6 hIncrBy() --- 字段自增
复制代码
<?php
$redis->hSet('user:1','login_count',0);
$redis->hIncrBy('user:1','login_count',1);//1
$redis->hIncrBy('user:1','login_count',5);//6
$redis->hIncrByFloat('user:1','score',1.5);//浮点数自增
5.1.7 hKeys() / hVals() --- 获取所有字段名/值
复制代码
<?php
print_r($redis->hKeys('user:1'));//['name','age','email']
print_r($redis->hVals('user:1'));//['Alice','28','alice@example.com']

5.2 非常用哈希函数

5.2.1 hSetNx() --- 不存在时设置字段
复制代码
<?php
//仅当字段不存在时设置,已存在则不修改
$redis->hSetNx('user:1','created_at',date('Y‑m‑d H:i:s'));
5.2.2 hStrLen() --- 获取字段值长度
复制代码
<?php
echo $redis->hStrLen('user:1','name');//字段值的字节长度
5.2.3 hScan() --- 迭代哈希字段
复制代码
<?php
$iterator=null;
while($keys=$redis->hScan('user:1',$iterator)){
    foreach($keys as $field=>$value){
        echo "$field => $value\n";
    }
}

5.3 哈希函数速查表

方法 频率 说明
hSet(key, field, val) 常用 设置哈希字段的值,字段已存在则覆盖
hGet(key, field) 常用 获取哈希字段的值
hMSet(key, array) 常用 批量设置多个字段
hMGet(key, array) 常用 批量获取多个字段的值
hGetAll(key) 常用 获取所有字段和值(关联数组)
hDel(key, field1, ...) 常用 删除一个或多个字段,返回删除数
hExists(key, field) 常用 判断字段是否存在
hLen(key) 常用 获取字段数量
hIncrBy(key, field, int) 常用 字段值增加指定整数
hIncrByFloat(key, field, fl) 非常用 字段值增加指定浮点数
hKeys(key) 常用 获取所有字段名
hVals(key) 常用 获取所有字段值
hSetNx(key, field, val) 非常用 仅当字段不存在时设置值
hStrLen(key, field) 非常用 获取字段值的字节长度
hScan(key, iter, opts) 非常用 增量迭代哈希字段,支持 MATCH/COUNT

六、列表(List)操作

List 是一个有序的字符串链表,支持从头部(左)和尾部(右)插入/弹出元素。List 常用于消息队列、最新动态列表、操作日志等场景。

6.1 常用列表函数

6.1.1 lPush() / rPush() --- 入队

lPush 从左端(头部)插入,rPush 从右端(尾部)插入。返回列表长度。

复制代码
<?php
$redis->lPush('queue:tasks','task3');//[task3]
$redis->lPush('queue:tasks','task2');//[task2,task3]
$redis->lPush('queue:tasks','task1');//[task1,task2,task3]
$redis->rPush('queue:tasks','task4');//[task1,task2,task3,task4]
6.1.2 lPop() / rPop() --- 出队
复制代码
<?php
echo $redis->lPop('queue:tasks');//'task1',剩余[task2,task3,task4]
echo $redis->rPop('queue:tasks');//'task4',剩余[task2,task3]
6.1.3 lRange() --- 获取范围元素

获取列表指定范围的元素,0 表示第一个,‑1 表示最后一个。

复制代码
<?php
//获取全部元素
$all=$redis->lRange('queue:tasks',0,-1);
//获取前3个
$top3=$redis->lRange('queue:tasks',0,2);
6.1.4 lLen() --- 获取列表长度
复制代码
<?php
echo $redis->lLen('queue:tasks');//列表元素数量
6.1.5 lRem() --- 移除元素
复制代码
<?php
//count>0:从头到尾移除最多count个等于value的元素
//count<0:从尾到头移除
//count=0:移除所有等于value的元素
$redis->lRem('queue:tasks','task2',1);
6.1.6 lTrim() --- 裁剪列表
复制代码
<?php
//只保留索引0~2的元素,其余删除
$redis->lTrim('queue:tasks',0,2);

6.2 非常用列表函数

6.2.1 lIndex() / lSet() --- 按索引操作
复制代码
<?php
echo $redis->lIndex('queue:tasks',0);//获取第一个元素
$redis->lSet('queue:tasks',0,'new_task1');//设置第一个元素的值
6.2.2 lInsert() --- 插入元素
复制代码
<?php
//在pivot元素之前/之后插入新元素
$redis->lInsert('queue:tasks',Redis::BEFORE,'task2','task1.5');
$redis->lInsert('queue:tasks',Redis::AFTER,'task2','task2.5');
6.2.3 阻塞弹出 blPop / brPop

阻塞式弹出,列表为空时等待直到有元素或超时。适合消费者长轮询。

复制代码
<?php
//阻塞等待最多5秒
$result=$redis->blPop(['queue:tasks'],5);
//返回['queue:tasks','task_value']或超时返回空
if($result){
    $queue=$result[0];
    $value=$result[1];
}
6.2.4 rpoplpush() --- 移动元素
复制代码
<?php
//从source尾部弹出并推入destination头部
$redis->rpoplpush('queue:src','queue:dst');

6.3 列表函数速查表

方法 频率 说明
lPush(key, val1, ...) 常用 从列表左端插入一个或多个元素
rPush(key, val1, ...) 常用 从列表右端插入一个或多个元素
lPop(key) 常用 弹出并返回列表左端第一个元素
rPop(key) 常用 弹出并返回列表右端第一个元素
lRange(key, start, end) 常用 获取指定范围的元素列表
lLen(key) 常用 获取列表长度(元素数量)
lRem(key, val, count) 常用 移除指定数量等于 val 的元素
lTrim(key, start, end) 常用 裁剪列表,只保留指定范围
lIndex(key, index) 非常用 获取指定索引的元素
lSet(key, index, val) 非常用 设置指定索引的元素值
lInsert(key, pos, piv, v) 非常用 在 pivot 元素前/后插入值
blPop(keys, timeout) 非常用 阻塞式从左端弹出
brPop(keys, timeout) 非常用 阻塞式从右端弹出
rpoplpush(src, dst) 非常用 从 src 尾部弹出推入 dst 头部
brpoplpush(src, dst, t) 非常用 阻塞式 rpoplpush
lPushx(key, val) 非常用 仅当列表存在时从左端插入
rPushx(key, val) 非常用 仅当列表存在时从右端插入

七、集合(Set)操作

Set 是一个无序的、不重复的字符串集合。支持集合运算(交集、并集、差集),常用于标签管理、共同好友、去重等场景。

7.1 常用集合函数

7.1.1 sAdd() / sRem() --- 添加和移除成员
复制代码
<?php
$redis->sAdd('tags:article:1','php','redis','database');
$redis->sAdd('tags:article:1','redis');//重复添加返回0
$redis->sRem('tags:article:1','database');//移除成员
7.1.2 sMembers() --- 获取所有成员
复制代码
<?php
$members=$redis->sMembers('tags:article:1');
print_r($members);//['php','redis']
7.1.3 sIsMember() --- 判断成员是否存在
复制代码
<?php
var_dump($redis->sIsMember('tags:article:1','php'));//true
var_dump($redis->sIsMember('tags:article:1','java'));//false
7.1.4 sCard() --- 获取成员数量
复制代码
<?php
echo $redis->sCard('tags:article:1');//2
7.1.5 sPop() / sRandMember() --- 随机操作
复制代码
<?php
//随机弹出一个成员
$member=$redis->sPop('tags:article:1');
//随机获取3个成员(不弹出)
$random=$redis->sRandMember('tags:article:1',3);

7.2 集合运算函数

集合运算是 Set 类型的核心能力:

复制代码
<?php
$redis->sAdd('set:A','a','b','c','d');
$redis->sAdd('set:B','c','d','e','f');
//交集:{c,d}
$inter=$redis->sInter('set:A','set:B');
//并集:{a,b,c,d,e,f}
$union=$redis->sUnion('set:A','set:B');
//差集(A有B没有):{a,b}
$diff=$redis->sDiff('set:A','set:B');
//将交集结果存入新集合
$redis->sInterStore('result:inter','set:A','set:B');
$redis->sUnionStore('result:union','set:A','set:B');
$redis->sDiffStore('result:diff','set:A','set:B');

7.3 sMove() --- 移动成员

复制代码
<?php
//将成员从source集合移动到destination集合
$redis->sMove('set:A','set:B','a');

7.4 集合函数速查表

方法 频率 说明
sAdd(key, member1, ...) 常用 向集合添加一个或多个成员
sRem(key, member1, ...) 常用 从集合移除一个或多个成员
sMembers(key) 常用 获取集合所有成员
sIsMember(key, member) 常用 判断成员是否在集合中
sCard(key) 常用 获取集合成员数量
sPop(key) 非常用 随机弹出一个成员
sRandMember(key, count) 非常用 随机获取成员(不弹出)
sInter(key1, key2, ...) 常用 获取多个集合的交集
sUnion(key1, key2, ...) 常用 获取多个集合的并集
sDiff(key1, key2, ...) 常用 获取多个集合的差集
sInterStore(dst, k1, ...) 非常用 交集结果存入指定集合
sUnionStore(dst, k1, ...) 非常用 并集结果存入指定集合
sDiffStore(dst, k1, ...) 非常用 差集结果存入指定集合
sMove(src, dst, member) 非常用 将成员从源集合移到目标集合
sScan(key, iter, opts) 非常用 增量迭代集合成员

八、有序集合(Sorted Set)操作

Sorted Set 是 Redis 最具特色的数据类型之一。每个成员关联一个分数(score),集合按分数自动排序。非常适合排行榜、延时队列、带权重的数据等场景。

8.1 常用有序集合函数

8.1.1 zAdd() --- 添加成员
复制代码
<?php
//添加成员及分数
$redis->zAdd('leaderboard',100,'Alice');
$redis->zAdd('leaderboard',85,'Bob');
$redis->zAdd('leaderboard',92,'Charlie');
//批量添加(phpredis5.0+支持选项参数)
$redis->zAdd('leaderboard',
    ['nx'],//仅当成员不存在时添加
    100,'Alice',
    85,'Bob',
    92,'Charlie'
);
8.1.2 zRange() / zRevRange() --- 范围获取

zRange 按分数升序,zRevRange 按分数降序。

复制代码
<?php
//升序获取全部
$asc=$redis->zRange('leaderboard',0,-1);
//['Bob','Charlie','Alice']
//降序获取前3名(含分数)
$top3=$redis->zRevRange('leaderboard',0,2,true);
//['Alice'=>100,'Charlie'=>92,'Bob'=>85]
8.1.3 zRangeByScore() --- 按分数范围获取
复制代码
<?php
//获取分数在80~95之间的成员
$mid=$redis->zRangeByScore('leaderboard',80,95);
//['Bob','Charlie']
//限制返回数量,带分数
$mid=$redis->zRangeByScore('leaderboard',80,95,
    ['withscores'=>true,'limit'=>[0,10]]);
//降序按分数范围
$desc=$redis->zRevRangeByScore('leaderboard',100,80);
8.1.4 zScore() --- 获取成员分数
复制代码
<?php
echo $redis->zScore('leaderboard','Alice');//100
8.1.5 zIncrBy() --- 增加分数
复制代码
<?php
$redis->zIncrBy('leaderboard',10,'Bob');//Bob分数变为95
8.1.6 zRank() / zRevRank() --- 获取排名

zRank 返回升序排名(0 开始),zRevRank 返回降序排名。

复制代码
<?php
echo $redis->zRank('leaderboard','Alice');//2(升序第3位)
echo $redis->zRevRank('leaderboard','Alice');//0(降序第1位)
8.1.7 zRem() / zCard() / zCount()
复制代码
<?php
//删除成员
$redis->zRem('leaderboard','Bob');
//获取成员总数
echo $redis->zCard('leaderboard');//2
//获取分数范围内的成员数
echo $redis->zCount('leaderboard',90,100);//1(Alice)

8.2 非常用有序集合函数

8.2.1 zRemRangeByRank() / zRemRangeByScore()
复制代码
<?php
//按排名范围删除
$redis->zRemRangeByRank('leaderboard',0,2);
//按分数范围删除
$redis->zRemRangeByScore('leaderboard',0,50);
8.2.2 zUnion() / zInter() --- 集合运算
复制代码
<?php
//并集:将多个有序集合合并
$redis->zUnion('result',['set1','set2']);
//带权重和聚合方式
$redis->zUnion('result',['set1','set2'],
    ['weights'=>[2,1],'aggregate'=>'MAX']);
//交集
$redis->zInter('result',['set1','set2']);

8.3 有序集合函数速查表

方法 频率 说明
zAdd(key, score, member, ...) 常用 添加成员及分数
zRem(key, member1, ...) 常用 移除一个或多个成员
zRange(key, start, end, w) 常用 按分数升序获取成员
zRevRange(key, start, end, w) 常用 按分数降序获取成员
zRangeByScore(key, min, max) 常用 按分数范围升序获取成员
zRevRangeByScore(key, max, min) 常用 按分数范围降序获取成员
zScore(key, member) 常用 获取成员的分数
zIncrBy(key, incr, member) 常用 增加成员的分数
zRank(key, member) 常用 获取成员升序排名
zRevRank(key, member) 常用 获取成员降序排名
zCard(key) 常用 获取成员总数
zCount(key, min, max) 常用 获取分数范围内的成员数
zRemRangeByRank(key, s, e) 非常用 按排名范围删除成员
zRemRangeByScore(key, min, max) 非常用 按分数范围删除成员
zUnion(dst, keys, opts) 非常用 多个有序集合并集存入 dst
zInter(dst, keys, opts) 非常用 多个有序集合交集存入 dst
zRangeByLex(key, min, max) 非常用 按字典序范围获取成员
zScan(key, iter, opts) 非常用 增量迭代有序集合成员

九、键(Key)操作

Key 操作不限于特定数据类型,适用于所有 Redis 数据类型。包括过期设置、类型查询、模式匹配查找等通用操作。

9.1 常用键操作函数

9.1.1 keys() --- 按模式查找键

支持通配符:* 匹配任意字符,? 匹配单个字符,[] 匹配范围。

复制代码
<?php
$keys=$redis->keys('user:*');//匹配所有user:开头的键
$keys=$redis->keys('user:?:??');//匹配user:1ab等模式

keys() 命令在大数据量下会阻塞 Redis,生产环境应使用 scan() 替代。scan() 是增量式遍历,不会阻塞服务器。

9.1.2 scan() --- 增量遍历键(推荐)
复制代码
<?php
$iterator=null;
$result=[];
do{
    $keys=$redis->scan($iterator,'user:*',100);
    if($keys!==false){
        $result=array_merge($result,$keys);
    }
}while($iterator>0);
print_r($result);
9.1.3 expire() / ttl() --- 过期与查询
复制代码
<?php
$redis->set('token','abc123');
$redis->expire('token',3600);//设置3600秒后过期
echo $redis->ttl('token');//剩余秒数,如3598
$redis->persist('token');//移除过期,变为永久键
echo $redis->ttl('token');//‑1(永不过期)
$redis->pExpire('token',5000);//5000毫秒后过期
echo $redis->pttl('token');//剩余毫秒数
9.1.4 exists() / type() / rename()
复制代码
<?php
var_dump($redis->exists('token'));//true/false
echo $redis->type('token');//返回类型常量
echo $redis->type('user:1');//Redis::REDIS_HASH
$redis->rename('old_key','new_key');//重命名键
9.1.5 object() --- 获取键的内部信息
复制代码
<?php
echo $redis->object('encoding','user:1');//编码方式如'hashtable'
echo $redis->object('refcount','user:1');//引用计数
echo $redis->object('idletime','user:1');//空闲时间(秒)

9.2 键操作函数速查表

方法 频率 说明
keys(pattern) 常用 按模式匹配查找所有键(生产慎用)
scan(iter, pat, count) 常用 增量式遍历键(推荐替代 keys)
del(key1, key2, ...) 常用 删除一个或多个键
exists(key) 常用 判断键是否存在
expire(key, seconds) 常用 设置键的过期时间(秒)
pExpire(key, ms) 非常用 设置键的过期时间(毫秒)
expireAt(key, timestamp) 非常用 设置键在指定 Unix 时间戳过期
pExpireAt(key, timestamp) 非常用 设置键在指定毫秒级时间戳过期
ttl(key) 常用 获取键的剩余过期时间(秒),‑1为永不过期
pTtl(key) 非常用 获取键的剩余过期时间(毫秒)
persist(key) 常用 移除键的过期时间,变为永久键
type(key) 常用 获取键的数据类型
rename(key, newkey) 非常用 重命名键,新键已存在则覆盖
renameNx(key, newkey) 非常用 仅当新键不存在时重命名
randomKey() 非常用 随机返回一个键名
object(subcmd, key) 非常用 获取键的内部信息(编码/引用数/空闲时间)
move(key, db) 非常用 将键移动到指定数据库
dump(key) 非常用 序列化键的值(用于迁移)
restore(key, ttl, val) 非常用 反序列化恢复键值
touch(key1, ...) 非常用 修改键的最后访问时间,返回存在键数

十、事务(Transaction)操作

Redis 事务通过 MULTI/EXEC 实现:MULTI 开启事务,后续命令进入队列,EXEC 原子性执行队列中的所有命令。WATCH 可实现乐观锁,当被监视的键在事务执行前被修改,事务自动中止。

10.1 基本事务

复制代码
<?php
$redis->multi();
$redis->set('key1','val1');
$redis->set('key2','val2');
$redis->incr('counter');
$result=$redis->exec();//返回每条命令的执行结果数组
//['val1','val2',新计数]

10.2 链式事务调用

复制代码
<?php
$ret=$redis->multi()
    ->set('a','1')
    ->set('b','2')
    ->incr('counter')
    ->exec();

10.3 WATCH 乐观锁

复制代码
<?php
//监视键,如果事务执行前被修改则中止
$redis->watch('balance');
$balance=$redis->get('balance');
if($balance>=100){
    $redis->multi();
    $redis->decrBy('balance',100);
    $redis->incrBy('paid',100);
    $result=$redis->exec();
    if($result===false){
        echo '事务被中止(数据已被修改)';
    }
}else{
    $redis->unwatch();
    echo '余额不足';
}

10.4 事务函数速查表

方法 频率 说明
multi() 常用 开启事务,后续命令进入队列
exec() 常用 执行事务队列中的所有命令,返回结果数组
discard() 非常用 取消事务,清空命令队列
watch(key1, ...) 常用 监视一个或多个键(乐观锁)
unwatch() 常用 取消所有键的监视

十一、发布订阅(Pub/Sub)

Redis Pub/Sub 是一种消息通信模式:发布者将消息发送到频道,所有订阅了该频道的客户端都能收到消息。适合实时消息推送、聊天室等场景。

11.1 发布消息

复制代码
<?php
//向频道发布消息,返回收到消息的订阅者数量
$count=$redis->publish('news','Breaking:PHP8.4 released!');
echo "收到消息的订阅者数:$count\n";

11.2 订阅频道

subscribe() 会阻塞当前进程,持续监听频道消息:

复制代码
<?php
$redis=new Redis();
$redis->connect('127.0.0.1',6379);
//订阅频道,有消息时触发回调
$redis->subscribe(['news','alerts'],function($redis,$channel,$msg){
    echo "[$channel] $msg\n";
});
//此行以下的代码不会执行,subscribe会阻塞

11.3 模式订阅

复制代码
<?php
//按模式匹配频道名
$redis->psubscribe(['news.*','log.*'],function($redis,$pattern,$channel,$msg){
    echo "[pattern=$pattern][channel=$channel] $msg\n";
});

11.4 发布订阅函数速查表

方法 频率 说明
publish(channel, msg) 非常用 向频道发布消息,返回订阅者数
subscribe(channels, cb) 非常用 订阅频道,阻塞监听消息
psubscribe(patterns , cb) 非常用 按模式订阅频道
unsubscribe(channels) 非常用 取消订阅频道
punsubscribe(patterns) 非常用 取消模式订阅
pubsub(subcmd, args) 非常用 查询 Pub/Sub 状态(频道/订阅者数)

十二、常用函数汇总

以下是 Redis 在 PHP 项目中实际使用频率最高的函数分类汇总,掌握这些函数即可覆盖绝大多数日常开发需求。

12.1 连接类常用函数

方法 功能说明
connect(host, port, timeout) 创建 Redis 连接
pconnect(host, port, timeout) 创建持久连接(PHP‑FPM 推荐)
auth(password) 密码认证
select(db) 选择数据库
close() 关闭连接
ping() 测试连接

12.2 字符串类常用函数

方法 功能说明
set(key, value, opts) 设置键值,可带过期/NX/XX 选项
get(key) 获取键值
del(key1, key2, ...) 删除键
exists(key) 判断键是否存在
incr(key) / decr(key) 自增/自减1
incrBy(key, n) / decrBy(key, n) 自增/自减指定整数
setex(key, ttl, value) 设置带过期的键值
setnx(key, value) 仅当键不存在时设置
mset(array) / mget(array) 批量设置/获取
getSet(key, value) 设置新值返回旧值
append(key, value) 追加字符串
strlen(key) 获取值长度

12.3 哈希类常用函数

方法 功能说明
hSet(key, field, value) 设置字段值
hGet(key, field) 获取字段值
hMSet(key, array) 批量设置字段
hMGet(key, array) 批量获取字段
hGetAll(key) 获取所有字段和值
hDel(key, field1, ...) 删除字段
hExists(key, field) 判断字段是否存在
hLen(key) 获取字段数量
hIncrBy(key, field, n) 字段值自增
hKeys(key) / hVals(key) 获取所有字段名/值

12.4 列表类常用函数

方法 功能说明
lPush(key, val) / rPush(key, val) 从左/右入队
lPop(key) / rPop(key) 从左/右出队
lRange(key, start, end) 获取范围元素
lLen(key) 获取列表长度
lRem(key, val, count) 移除指定元素
lTrim(key, start, end) 裁剪列表

12.5 集合类常用函数

方法 功能说明
sAdd(key, member1, ...) 添加成员
sRem(key, member1, ...) 移除成员
sMembers(key) 获取所有成员
sIsMember(key, member) 判断成员是否存在
sCard(key) 获取成员数量
sInter(k1, k2, ...) 交集
sUnion(k1, k2, ...) 并集
sDiff(k1, k2, ...) 差集

12.6 有序集合类常用函数

方法 功能说明
zAdd(key, score, member) 添加成员及分数
zRem(key, member) 移除成员
zRange(key, s, e, w) 升序获取成员
zRevRange(key, s, e, w) 降序获取成员
zRangeByScore(key, min, max) 按分数范围获取
zScore(key, member) 获取分数
zIncrBy(key, incr, member) 增加分数
zRank(key, member) 获取升序排名
zRevRank(key, member) 获取降序排名
zCard(key) / zCount(key, min, max) 获取成员数/范围内成员数

12.7 键操作常用函数

方法 功能说明
keys(pattern) 按模式查找键(慎用)
scan(iterator, pattern, count) 增量遍历键(推荐)
expire(key, seconds) 设置过期时间
ttl(key) 查询剩余过期时间
persist(key) 移除过期时间
type(key) 获取数据类型

12.8 事务常用函数

multi()、exec()、watch(key1, ...)、unwatch()

十三、非常用函数汇总

以下函数在实际开发中使用频率较低,但在特定场景下非常有用。了解这些函数有助于在遇到特殊需求时选择合适的工具。

13.1 字符串非常用函数

方法 功能说明
incrByFloat(key, float) 浮点数自增
psetex(key, ttl, value) 毫秒级过期设置
msetnx(array) 批量设置(全部不存在时才成功)
getRange(key, start, end) 获取子字符串
setRange(key, offset, value) 按偏移覆写值
getBit(key, offset) 获取比特位
setBit(key, offset, val) 设置比特位
bitCount(key) 统计值为1的比特数
bitOp(op, dest, key1, ...) 位运算(AND/OR/XOR/NOT)

13.2 哈希非常用函数

方法 功能说明
hIncrByFloat(key, field, float) 字段浮点数自增
hSetNx(key, field, value) 字段不存在时设置
hStrLen(key, field) 字段值字节长度
hScan(key, iterator, opts) 增量迭代哈希字段

13.3 列表非常用函数

方法 功能说明
lIndex(key, index) 获取指定索引元素
lSet(key, index, value) 设置指定索引元素
lInsert(key, pos, pivot, val) 在 pivot 前/后插入
blPop(keys, timeout) 阻塞式左弹出
brPop(keys, timeout) 阻塞式右弹出
rpoplpush(src, dst) 尾弹出推入头部
brpoplpush(src, dst, t) 阻塞式 rpoplpush
lPushx(key, val) / rPushx(key, val) 列表存在时插入

13.4 集合非常用函数

方法 功能说明
sPop(key) 随机弹出成员
sRandMember(key, count) 随机获取成员
sInterStore(dst, k1, ...) 交集存入新集合
sUnionStore(dst, k1, ...) 并集存入新集合
sDiffStore(dst, k1, ...) 差集存入新集合
sMove(src, dst, member) 移动成员到另一集合
sScan(key, iterator, opts) 增量迭代集合成员

13.5 有序集合非常用函数

方法 功能说明
zRemRangeByRank(key, s, e) 按排名范围删除
zRemRangeByScore(key , min, max) 按分数范围删除
zUnion(dst, keys, opts) 有序集合并集
zInter(dst, keys, opts) 有序集合交集
zRangeByLex(key, min, max) 按字典序获取
zScan(key, iterator, opts) 增量迭代成员

13.6 键操作非常用函数

方法 功能说明
pExpire(key, ms) 设置毫秒过期
expireAt(key, timestamp) 时间戳秒级过期
pExpireAt(key, timestamp) 毫秒级时间戳过期
pTtl(key) 毫秒级剩余时间
rename(key, newkey) 重命名
renameNx(key, newkey) 不存在时重命名
randomKey() 随机返回一个键
object(subcmd, key) 获取键内部信息
move(key, db) 移动到其他数据库
dump(key) 序列化键值
restore(key, ttl, val) 反序列化恢复
touch(key1, ...) 修改最后访问时间

13.7 服务器管理非常用函数

方法 功能说明
info(section) 获取 Redis 服务器信息
config(cmd, key) 获取/设置配置参数
dbSize() 获取当前数据库键数量
flushDB() 清空当前数据库
flushAll() 清空所有数据库
time() 获取 Redis 服务器时间
bgSave() 后台异步保存(RDB)
save() 同步保存(会阻塞)
lastSave() 获取上次保存时间戳
slaveOf(host, port) 设置主从复制
slowlog(subcmd, arg) 慢查询日志
client(cmd, args) 客户端管理
eval(script, keys, args) 执行 Lua 脚本
rawCommand(...) 发送原始 Redis 命令

十四、Redis 扩展用法

14.1 Pipeline 管道

Pipeline 允许一次性发送多条命令,减少网络往返延迟。适合批量写入或读取场景。管道内的命令不保证原子性。

复制代码
<?php
$redis=new Redis();
$redis->connect('127.0.0.1',6379);
//方式一:数组形式
$redis->pipeline();
for($i=0;$i<1000;$i++){
    $redis->set("key:$i","val:$i");
}
$results=$redis->exec();//返回1000条结果

//方式二:回调形式(推荐)
$results=$redis->pipeline(function($pipe){
    for($i=0;$i<1000;$i++){
        $pipe->set("key:$i","val:$i");
    }
});

Pipeline 与 multi() 的区别:Pipeline 是客户端行为,减少网络往返;multi/exec 是服务端事务,保证原子性。两者可以组合使用。

14.2 分布式锁

利用 SET NX EX 实现分布式锁,确保在分布式环境中同一资源只有一个客户端能操作。

复制代码
<?php
class RedisLock
{
    private Redis $redis;
    private string $lockKey;
    private string $token;//唯一标识,防止误解锁

    public function __construct(Redis $redis,string $key,int $ttl=10)
    {
        $this->redis=$redis;
        $this->lockKey="lock:{$key}";
        $this->token=uniqid('',true);
        //SETNX EX实现原子加锁
        $ok=$redis->set($this->lockKey,$this->token,['nx','ex'=>$ttl]);
        if(!$ok){
            throw new RuntimeException('获取锁失败');
        }
    }

    public function release():bool
    {
        //用Lua脚本保证原子解锁(验证token后删除)
        $script="
if redis.call('get',KEYS[1])==ARGV[1] then
    return redis.call('del',KEYS[1])
else
    return 0
end
";
        return(bool)$this->redis->eval($script,
            [$this->lockKey,$this->token],1);
    }
}

//使用示例
try{
    $lock=new RedisLock($redis,'order:1001',30);
    //执行业务逻辑...
    $lock->release();
}catch(RuntimeException $e){
    echo $e->getMessage();
}

14.3 计数器与限流

利用 INCR 的原子性实现接口限流(固定窗口算法):

复制代码
<?php
function rateLimit(Redis $redis,string $key,int $max,int $period):bool
{
    $count=$redis->incr($key);
    if($count===1){
        $redis->expire($key,$period);//首次访问设置过期窗口
    }
    return $count<=$max;
}

//每分钟最多100次请求
if(!rateLimit($redis,'api:limit:user:1001',100,60)){
    http_response_code(429);
    echo '请求过于频繁,请稍后再试';
    exit;
}

14.4 缓存模式(Cache‑Aside)

复制代码
<?php
function getCachedData(Redis $redis,string $cacheKey,callable $callback,int $ttl=3600)
{
    //1.先从缓存读取
    $data=$redis->get($cacheKey);
    if($data!==false){
        return json_decode($data,true);
    }
    //2.缓存未命中,从数据源获取
    $data=$callback();
    //3.写入缓存
    $redis->setex($cacheKey,$ttl,json_encode($data));
    return $data;
}

//使用示例
$users=getCachedData($redis,'users:active',function(){
    //从数据库查询
    return Db::table('users')->where('status',1)->limit(100)->select();
},300);//缓存5分钟

14.5 Session 存储

将 PHP Session 存储到 Redis,支持多台服务器共享会话:

复制代码
//php.ini配置
session.save_handler=redis
session.save_path="tcp://127.0.0.1:6379?auth=yourpass&database=1"

<?php
//或在代码中动态设置
ini_set('session.save_handler','redis');
ini_set('session.save_path','tcp://127.0.0.1:6379?auth=yourpass&database=1');
session_start();

14.6 延时队列(Sorted Set 实现)

利用 Sorted Set 的 score 存储执行时间戳,实现延时任务:

复制代码
<?php
//投递延时任务
function delayPush(Redis $redis,string $queue,$data,int $delay):void
{
    $execTime=time()+$delay;
    $redis->zAdd($queue,$execTime,json_encode($data));
}

//消费延时任务
function delayPop(Redis $redis,string $queue)
{
    $now=time();
    //获取score<=当前时间的第一个成员
    $items=$redis->zRangeByScore($queue,0,$now,['limit'=>[0,1]]);
    if(empty($items)){
        return null;
    }
    $data=$items[0];
    //原子删除(防止并发重复消费)
    $removed=$redis->zRem($queue,$data);
    if($removed>0){
        return json_decode($data,true);
    }
    return null;
}

14.7 位图实现签到统计

复制代码
<?php
//用户签到:将每月的某天对应位设为1
function checkIn(Redis $redis,int $userId,int $year,int $month,int $day):void
{
    $key="signin:{$userId}:{$year}{$month}";
    $offset=$day‑1;
    $redis->setBit($key,$offset,1);
}

//查询本月签到天数
function getCheckInCount(Redis $redis,int $userId,int $year,int $month):int
{
    $key="signin:{$userId}:{$year}{$month}";
    return $redis->bitCount($key);
}

//判断某天是否签到
function isCheckedIn(Redis $redis,int $userId,int $year,int $month,int $day):bool
{
    $key="signin:{$userId}:{$year}{$month}";
    return(bool)$redis->getBit($key,$day‑1);
}

14.8 Lua 脚本执行

通过 eval() 执行 Lua 脚本,保证多条命令的原子性:

复制代码
<?php
//原子性扣库存脚本
$script="
local stock=tonumber(redis.call('get',KEYS[1]))
if stock==nil or stock<tonumber(ARGV[1])then
    return 0--库存不足
end
redis.call('decrby',KEYS[1],ARGV[1])
return 1--扣减成功
";
$result=$redis->eval($script,['product:1001:stock',1],1);
echo $result?'扣减成功':'库存不足';

14.9 Redis 集群连接

复制代码
<?php
//RedisCluster连接(phpredis3.0+)
$redis=new RedisCluster(null,
    ['10.0.0.1:7000','10.0.0.2:7000','10.0.0.3:7000'],
    2.5,//连接超时
    3.0,//读取超时
    true//启用持久连接
);

//带认证的集群连接
$redis=new RedisCluster(
    'my_persistent_id',
    ['10.0.0.1:7000','10.0.0.2:7000','10.0.0.3:7000'],
    2.5,3.0,true,
    ['auth'=>['myuser','mypass']]
);
$redis->set('key','value');
echo $redis->get('key');

十五、Redis 最佳实践

15.1 键命名规范

使用冒号分隔的层级命名,形成命名空间:

  • user:1001:profile //用户资料
  • user:1001:settings //用户设置
  • cache:article:200 //文章缓存
  • queue:email:pending //邮件队列
  • lock:order:5001 //订单分布式锁

15.2 合理选择数据结构

  • 缓存单个值:使用 String + set/get
  • 存储对象/结构化数据:使用 Hash + hSet/hGet,可单独修改字段
  • 消息队列:使用 List + lPush/rPop 或 BLPOP
  • 排行榜:使用 Sorted Set + zAdd/zRevRange
  • 标签/去重:使用 Set + sAdd/sIsMember
  • 签到/布尔标记:使用 Bitmap + setBit/bitCount
  • 计数器:使用 String + incr/decr
  • 延时队列:使用 Sorted Set + score 存储执行时间

15.3 过期策略

  • 缓存键必须设置 TTL,避免内存无限增长。
  • 热点数据 TTL 可适当延长,冷数据设置较短 TTL。
  • 避免大量键同时过期(缓存雪崩),可在 TTL 上加随机偏移。
  • 使用 setex 一步完成设置值和过期,避免两次命令。

15.4 连接管理

  • PHP‑FPM 环境使用 pconnect() 持久连接,减少 TCP 连接开销。
  • 避免在循环中反复创建 Redis 连接,应在脚本入口创建一次。
  • 连接超时和读取超时应根据业务合理设置,防止阻塞。
  • 生产环境应设置 Redis 密码,不要暴露默认端口到公网。

15.5 批量操作优化

  • 大量写入使用 pipeline() 管道,减少网络往返。
  • 批量获取使用 mget/hmget 替代循环 get/hget。
  • 遍历键使用 scan() 替代 keys(),防止阻塞 Redis。
  • 避免大 key 操作(如 hGetAll 大哈希),考虑分页或 hScan。

15.6 内存优化

  • 使用合适的数据结构编码:小 Hash/Set 会自动使用 ziplist 压缩编码。
  • 控制单个键的体积,避免大 Hash(字段过多)和大 List(元素过多)。
  • 定期清理无用键和过期键,监控 used_memory 指标。
  • 使用 expire 设置 TTL,让 Redis 自动回收内存。
  • 对象存储优先用 Hash 而非序列化为 String,可节省内存。

15.7 安全建议

  • 设置 requirepass 或使用 ACL 限制访问。
  • 绑定 bind 127.0.0.1 或内网 IP,禁止外网直接访问。
  • 禁用危险命令:rename‑command FLUSHALL "" 等方式屏蔽。
  • 使用 SSL/TLS 加密跨网络传输。
  • 定期备份 RDB 文件,开启 AOF 持久化。

15.8 错误处理

复制代码
<?php
try{
    $redis=new Redis();
    $redis->connect('127.0.0.1',6379,2.5);
    $redis->auth('yourpass');
    $redis->set('key','value');
    $val=$redis->get('key');
}catch(RedisException $e){
    //Redis连接或操作异常
    error_log('Redis error:'.$e->getMessage());
    //降级处理:从数据库读取或返回默认值
    $val=null;
}

本教程涵盖了 Redis 在 PHP 中的安装配置、连接方式、五大数据类型的完整操作函数、事务、发布订阅、常用与非常用函数分类、扩展用法及最佳实践。掌握这些内容,即可在实际项目中高效使用 Redis 解决缓存、计数、队列、锁等问题。

相关推荐
张洛闻Eren1 小时前
云原生k8s【第五课】:资源配额与限制
运维·数据库·云原生·kubernetes·k8s·github
天行健,君子而铎1 小时前
2026年中国API安全产品综合排名:选型指南与市场趋势解析
大数据·数据库·安全
瀚高PG实验室1 小时前
PostgreSQL 服务器因整数回绕导致分配空间过小HGVE-2026-E008
运维·服务器·数据库·瀚高数据库
todoitbo1 小时前
向量数据库不该成为新孤岛:KingbaseES 多模融合架构如何减少数据搬运
数据库·架构·国产数据库·kes
mwmbfh1 小时前
【CentOS7环境下Redis 6.2.14 源码编译部署说明】
linux·运维·数据库·redis
175063319451 小时前
Ubuntu24 DNS 问题
网络·数据库
风123456789~1 小时前
【Oracle专栏】跨服务器调用ORA-02064: 不支持分布式操作
数据库·oracle
瀚高PG实验室1 小时前
PostgreSQL libpq lo_* 函数允许服务器超级用户覆盖客户端栈内存HGVE-2026-E011
服务器·数据库·postgresql·瀚高数据库
Feynman’s boom3 小时前
PDF解析复盘
数据库·人工智能·算法·pdf解析