Skip to main content

Command Palette

Search for a command to run...

Laravel 7 Redis 叢集設定

Updated
2 min read
Laravel 7 Redis 叢集設定

工作上因為需求,必須使用 AWS Redis Key-Value Store,原本是透過 stunnel 連接 redis,因此必須修改設定。

重點:

  1. 支援叢集

  2. 使用 tls 連線

踩到的雷

laravel 若沒有額外設定,使用的是 redis client 是 phpredis,參考 laravel 7 redis 的說明文件

phpredis 是 php 的擴充,而 laravel 7 另外支援的 predis 是用 php 開發的套件,兩者相比主要是效能上的差異,一般情況下會優先使用 phpredis,但也要注意 phpredis 也會有版本與 php 版本之間的差別。

laravel 官方文件上寫的很陽春,所以設定上只是一再的嚐試,我們可以先透過 redis-cli 來連接 redis 服務試試看是否運作正常。

redis-cli -c -h <redis_host> -p <redis_port> --tls
# 連接成功後
AUTH <redis_password>
# 驗證成功之後
SET my_key 'Hello,Redis Cluster!'
# 寫入成功之後
GET my_key
# return Hello,Redis Cluster!

若是透過 redis-cli 運作都沒有問題,服務端就是運作正常,下一步再來設定。

撞 phpredis 的牆

依 laravel 官方說明文件使用 redis 叢集的設定

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'clusters' => [
        'default' => [
            [
                'host' => env('REDIS_HOST', 'localhost'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
            ],
        ],
    ],

],

只要包在 clusters 的 connection 就視為 redis 叢集服務,在連線上處理就會比一般不同。

  1. 叢集的 redis 連線必需指定「叢集」模式

  2. 叢集不能額外指定 db index 統一帶 `0`

另外還要看連線的協定為何,預設為「tcp」,依情況設定為「tls」。

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
        'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
    ],

    'clusters' => [
        'default' => [
            [
                'scheme' => env('REDIS_PROTOCOL', 'tcp'),
                'host' => env('REDIS_HOST', 'localhost'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
            ],
        ],
    ],

],

透過設定「scheme」即可,同樣,一般的連線設定也可以透過如此設定。

但是透過如此設定仍然無法正常使用,出現 MOVE 或是連線 timeout 的異常,直接檢查「vendor/laravel/framework/src/Illuminate/Redis/Connectors/PhpRedisConnector.php」中「connectToCluster」方法帶入的設定等,還是無法解決連線上的問題。

另闢溪踁

與其一直撞南牆,換的個方式使用 larave 底層也支援的套件「Predis」。

'redis' => [

    'client' => env('REDIS_CLIENT', 'predis'),

    'clusters' => [
        'production' => [
            [
                'scheme' => env('REDIS_PROTOCOL', 'tcp'),
                'host' => env('REDIS_HOST', '127.0.0.1'),
                'password' => env('REDIS_PASSWORD'),
                'port' => env('REDIS_PORT', '6379'),
                'database' => 0,
            ],
        ],

        'options' => [
            'cluster' => env('REDIS_CLUSTER', 'redis'),
            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
            'parameters' => [
                'read_write_timeout' => 60,
                'scheme' => env('REDIS_PROTOCOL', 'tcp'),
                'password' => env('REDIS_PASSWORD', null),
            ],
            'ssl' => [
                'verify_peer' => false,
            ],
        ],
    ],
],

使用 Predis 後就正常使用啦!!

Phpredis 與 Predis 最大的區別還是在效能上,Phpredis 還是較優於 Predis 的,但畢竟在專案上主要也只需用於 session,主要的服務又是後台服務,api 請求也有快取,基本上也還可以,後續再來撞 Phpredis 這個南牆。

參考資料:

Laravel cache 使用 AWS ElastiCache for Redis cluster

https://laravel.com/docs/7.x/redis#main-content

More from this blog

關於 Hash index

什麼是 Hash Index? Hash Index 是資料庫系統中的一種索引結構,它使用雜湊函數(Hash Function)將索引鍵(Key)映射到資料表中的記錄位置。相較於傳統的 B-Tree 索引,Hash Index 在某些特定查詢場景下能提供更高效的性能。 基本原理 Hash Index 的核心原理是: 使用雜湊函數將索引鍵轉換為雜湊值(Hash Value) 雜湊值決定資料記錄在雜湊表(Hash Table)中的儲存位置 查詢時,系統對索引鍵應用相同的雜湊函數,直接定位到對應...

Jul 26, 20251 min read
關於 Hash index

Event Storming 演練 - 停車場系統 - 下

邊界情境 實際做法: 當大家走到「車輛靠近入口 → 辨識 → 進場」的事件時,突然有人問: 「那如果有人卡在入口不走呢?」 此時 facilitator(主持人)會立刻拿一張粉紅貼紙寫: 複製編輯🚧 車輛卡在入口太久 然後貼在「車輛靠近入口」的旁邊,不急著解決,先繼續主流程。 快速記錄格式(現場慣用) 元素怎麼寫 事件粉紅貼紙,寫「異常行為:XXX」 策略建議藍貼紙,可直接寫「應提示駕駛讓道」 命令建議黃貼紙,可寫「發送通知、記錄異常」 👉 不強求完...

Jul 10, 20252 min read

Event Storming 演練 - 停車場系統 - 上

領域專家口述業務流程 停車場入口會顯示目前停車場剩餘車位,當車輛駛入停車場入口,會先判斷是否有停車位,若是有停車位,車號辨視系統成功取得車號將會放入車輛進入,當感應車輛真的進入後,記錄車輛的車牌與其進入的時間,會將剩餘車位減一。 車輛進入之後,會給於一段緩衝時間,若是車輛在緩衝時間內出場,系統判斷可以正常出場不必繳納停車費用,若超過緩衝時間,即必須這行繳費程序之後再放行。 繳費流程要求在出場之前完成,不會與出場流程一起,繳費時會判斷是否在緩衝時間內,若是,將不必繳費請駕駛人儘快離場,並提醒剩於緩...

Jul 10, 20253 min read

TypeScript - Type 那點事

隨便記 將類型定義放在 .types.ts 或 .d.ts 檔案中,此兩者副檔名有何差異? 在 TypeScript 開發中,.types.ts 和 .d.ts 檔案都用於定義類型,但它們的用途和特性有所不同: .types.ts 用途: 通常用於在 TypeScript 專案內部,定義專案中使用的類型。 這些檔案包含 TypeScript 程式碼,可以包含類型別名、介面、列舉等。 .types.ts 檔案會被 TypeScript 編譯器編譯成 JavaScript 檔案(.js...

Jun 28, 20251 min read

碼農筆記 - 設計思維

Mark it Work, Mark it Right, Mark it Fast 可測試性 可閱讀性 可觀察性 可維護性 可擴展性 健壯性 安全性 效能與資源效率 可部署性 可配置性 🧠 最佳實踐心法 別一開始就追求 Make it Fast,先求穩定,再求優雅,最後才是效能。 重構是常態不是例外,Make it Right 應視為開發常規而非技術債還債。 性能瓶頸來自實測,而不是預測。 Make it Right 意指 程式碼結構清晰 命名具語意 關...

Jun 10, 20251 min read

我的工作筆記

8 posts

雖是全端碼農,主力還是後端功能,php + mysql + redis 使用 Laravel 框架,node + mysql + redis 使用 Adonisjs v5。