Redis 是高性能鍵值存儲,支援 String、List、Set、Sorted Set、Hash 等豐富數據結構,且提供原子操作、持久化(RDB/AOF)、主從複製、哨兵/集群高可用。PHP 通過 phpredis 擴展(C 實現,效能極高)與其交互。本文系統整理核心 API 並給出生產級用法建議。
$redis = new Redis();
// 短連接
$redis->connect('127.0.0.1', 6379, 2.5); // host, port, timeout(秒)
// 長連接(FPM/CLI 長運行進程推薦)
$redis->pconnect('127.0.0.1', 6379, 2.5, 'persistent_id');
// 認證
$redis->auth('password');
// 選庫
$redis->select(0);
// 連接池建議:配合 php-fpm 進程模型,每進程持有一個 pconnect 連接
| 命令 | 說明 | 示例 |
|---|---|---|
| set | 設置鍵值 | $redis->set('key', 'val'); $redis->setex('key', 3600, 'val'); // 帶 TTL |
| get | 獲取值 | $val = $redis->get('key'); |
| setnx | 僅不存在時設置(分佈式鎖基礎) | $lock = $redis->setnx('lock:key', 1); |
| incr/decr | 原子自增/減 | $redis->incr('counter'); $redis->incrBy('counter', 10); |
| mset/mget | 批量設置/獲取 | $redis->mset(['k1'=>'v1','k2'=>'v2']); $vals = $redis->mget(['k1','k2']); |
| getSet | 原子獲取舊值並設置新值 | $old = $redis->getSet('key', 'newVal'); |
lPush/rPush、lPop/rPop、blPop/brPop(阻塞版,適合隊列消費者)。lRange('key', 0, -1) 獲取全部,lIndex 獲取單元素。lTrim('key', 0, 99) 保留前 100 元素,實現固定長度隊列。lInsert、lRem、lSet。| 類型 | 核心命令 | 典型場景 |
|---|---|---|
| Set | sAdd/sRem/sIsMember/sMembers/sInter/sUnion/sDiff/sPop/sRandMember | 標籤系統、共同好友、抽獎去重 |
| Sorted Set | zAdd/zRange/zRevRange/zScore/zIncrBy/zRem/zCount/zRank | 排行榜、延遲隊列(score=timestamp)、速率限制 |
適合存儲對象結構(如用戶信息),比序列化 String 更靈活、節省內存:
$redis->hSet('user:1001', ['name'=>'Tom','age'=>25,'city'=>'BJ']);
$redis->hGet('user:1001', 'name'); // Tom
$redis->hGetAll('user:1001'); // 全字段
$redis->hIncrBy('user:1001', 'login_count', 1); // 原子增長
exists('key')、del('key1','key2')、expire('key', 3600)、ttl('key')、persist('key')(移除過期時間)。keys('pattern') **生產禁用**(阻塞單線程),改用 scan 迭代器:for ($it=NULL; $arr=$redis->scan($it, 'prefix:*', 100);) { ... }。// 事務(樂觀鎖 WATCH)
$redis->watch('key');
$val = $redis->get('key');
$redis->multi();
$redis->set('key', $val + 1);
$redis->exec(); // 若 key 被外部修改,exec 返回 false,需重試
// Lua 腳本(原子性更強,推薦替代事務)
$lua = "local v = redis.call('GET', KEYS[1]) if v then return redis.call('SET', KEYS[1], v+ARGV[1]) else return redis.call('SET', KEYS[1], ARGV[1]) end";
$redis->eval($lua, 1, 'counter', 1);
pconnect,Swoole/Workerman 用連接池;避免頻繁 connect/close。business:module:id:field,如 order:info:10001:status,設定統一前綴便於維護。json_encode),避免 PHP serialize(跨語言不兼容、安全風險)。used_memory、connected_clients、keyspace_hits/misses、slowlog、replication lag。熟練掌握 Redis 數據結構與 PHP 操作 API,能讓你的應用在高併發、實時計數、分佈式鎖、緩存穿透防護等場景游刃有餘。