Redis 作為高性能鍵值存儲,廣泛應用於緩存、會話管理、排行榜、分佈式鎖等場景。本文提供 PHP 連接 Redis 的完整示例,涵蓋認證、基本操作、異常處理等實戰要點。
pecl install redis 或編譯 phpredisextension=redis.so<?php
/**
* Redis 連接與基本操作示例
* 支援密碼認證、數據庫選擇、異常捕獲
*/
try {
// 從配置中心或環境變量讀取(此處為示例佔位)
$host = '127.0.0.1';
$port = 6379;
$password = 'your_redis_password'; // 無密碼可留空
$dbIndex = 0; // 數據庫索引 0-15
$redis = new Redis();
// 建立連接(支援超時參數)
$ret = $redis->connect($host, $port, 2.5); // 2.5 秒連接超時
if ($ret === false) {
throw new Exception('Redis 連接失敗: ' . $redis->getLastError());
}
// 認證(Redis 6.0+ 支援 ACL 用戶名,此處為簡單密碼模式)
if (!empty($password)) {
$ret = $redis->auth($password);
if ($ret === false) {
throw new Exception('Redis 認證失敗: ' . $redis->getLastError());
}
}
// 選擇數據庫
$redis->select($dbIndex);
// --- 基本操作演示 ---
// 字符串操作
$redis->set('site:name', 'PHP技術站');
$redis->set('site:url', 'https://example.com');
$redis->expire('site:name', 3600); // 設置過期時間 1 小時
echo "站點名稱: " . $redis->get('site:name') . PHP_EOL;
echo "站點鏈接: " . $redis->get('site:url') . PHP_EOL;
// 哈希表操作(適合存儲對象)
$userKey = 'user:1001';
$redis->hSet($userKey, 'name', '張三');
$redis->hSet($userKey, 'email', 'zhangsan@example.com');
$redis->hSet($userKey, 'age', 28);
$userInfo = $redis->hGetAll($userKey);
echo "用戶信息: " . json_encode($userInfo, JSON_UNESCAPED_UNICODE) . PHP_EOL;
// 列表操作(佇列、棧、消息隊列)
$redis->lPush('task:queue', 'task_1');
$redis->lPush('task:queue', 'task_2');
$redis->rPush('task:queue', 'task_3');
echo "隊列長度: " . $redis->lLen('task:queue') . PHP_EOL;
echo "彈出任務: " . $redis->lPop('task:queue') . PHP_EOL;
// 集合操作(去重、標籤、共同好友)
$redis->sAdd('tags:php', 'backend', 'api', 'laravel');
$redis->sAdd('tags:golang', 'backend', 'microservice', 'grpc');
$common = $redis->sInter('tags:php', 'tags:golang');
echo "共同標籤: " . implode(', ', $common) . PHP_EOL;
// 有序集合(排行榜、延遲隊列)
$redis->zAdd('rank:score', 95, 'user_A');
$redis->zAdd('rank:score', 88, 'user_B');
$redis->zAdd('rank:score', 100, 'user_C');
$top3 = $redis->zRevRange('rank:score', 0, 2, true); // 帶分數降序
echo "前三名: " . json_encode($top3, JSON_UNESCAPED_UNICODE) . PHP_EOL;
// 管道操作(批量寫入優化網絡往返)
$pipe = $redis->pipeline();
for ($i = 0; $i < 100; $i++) {
$pipe->set("batch:key:$i", "value_$i");
}
$pipe->exec();
echo "管道批量寫入完成" . PHP_EOL;
} catch (RedisException $e) {
die("Redis 異常: " . $e->getMessage());
} catch (Exception $e) {
die("通用錯誤: " . $e->getMessage());
}
高併發場景下,頻繁創建連接開銷大。建議使用 pconnect 持久連接,或引入 predis 支援的連接池:
$redis->pconnect('127.0.0.1', 6379); // 持久連接
// 或配合 Swoole/RoadRunner 协程池化管理
如「檢查並設置」分佈式鎖,必須用 Lua 保證原子:
$luaScript = "
if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then
redis.call('expire', KEYS[1], ARGV[2])
return 1
else
return 0
end
";
$scriptSha = $redis->script('load', $luaScript);
// 後續調用 evalsha
$lock = $redis->evalSha($scriptSha, 1, 'lock:order_123', 'request_id', 10);
業務模塊:實體類型:ID:屬性,如 order:info:20240101:detailexpire(key, 3600 + rand(0, 300))| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| 連接超時 | 防火牆、bind 配置、網絡不通 | 檢查 redis.conf bind 0.0.0.0、安全組、ping 測試 |
| 認證失敗 | 密碼錯誤、ACL 權限不足 | 檢查 requirepass、ACL LIST 用戶權限 |
| 內存飆升 | 大鍵、未設置 TTL、內存碎片 | 掃描大鍵、設置合理 TTL、配置 maxmemory-policy |
| 讀寫延遲高 | 慢查詢、大鍵操作、主從同步 | 開啟 slowlog、避免 keys *、使用 pipeline |
PHP 操作 Redis 核心在於:正確管理連接生命週期、善用數據結構特性、通過 Pipeline/Lua 優化性能、建立完善的鍵名與過期規範。掌握這些基礎後,可進一步探索 Redis Cluster、Sentinel 高可用、Redis Streams 消息隊列等進階特性。