Defective Code Logo

Total Downloads Latest Stable Version Latest Stable Version

English | العربية | বাংলা | Bosanski | Deutsch | Español | Français | हिन्दी | Italiano | 日本語 | 한국어 | मराठी | Português | Русский | Kiswahili | தமிழ் | తెలుగు | Türkçe | اردو | Tiếng Việt | 中文

소개

Recall은 Laravel을 위한 고성능 Redis 클라이언트 측 캐싱 패키지입니다. Redis 6의 클라이언트 측 캐싱 기능을 자동 무효화와 함께 활용하여 Redis 왕복 시간과 지연을 극적으로 줄입니다. Laravel Octane 환경에 맞춰 특별히 구축되었으며, APCu 또는 Swoole Table을 로컬 캐시 레이어로 사용하여 무효화 메시지를 통해 Redis와 동기화 상태를 유지합니다.

Redis에서 값을 가져오면 Recall은 이를 로컬에 저장합니다. 그 값이 Redis에서 변경되면(모든 클라이언트에서) Redis는 Recall에 로컬 복사를 무효화하도록 자동으로 알립니다. 이렇게 하면 메모리 캐싱의 속도와 Redis의 일관성 보장을 함께 누릴 수 있습니다.

주요 기능

예시

// Recall을 캐시 드라이버로 구성
// config/cache.php
'stores' => [
'recall' => [
'driver' => 'recall',
],
],
 
// Laravel 캐시처럼 사용
use Illuminate\Support\Facades\Cache;
 
// 첫 번째 호출: Redis에서 가져오고 로컬에 저장
$user = Cache::store('recall')->get('user:1');
 
// 이후 호출: 로컬 APCu/Swoole Table에서 제공 (마이크로초)
$user = Cache::store('recall')->get('user:1');
 
// user:1이 어디에서 업데이트되면, Redis는 Recall에 무효화하도록 알림
Cache::store('recall')->put('user:1', $newUserData, 3600);
// 모든 워커에서 로컬 캐시가 자동으로 무효화됩니다.

설치

Composer를 통해 패키지를 설치하세요:

composer require defectivecode/laravel-recall

요구 사항

사용법

기본 설정

  1. Recall 캐시 저장소를 config/cache.php에 추가합니다:
'stores' => [
// ... 다른 저장소
 
'recall' => [
'driver' => 'recall',
],
],
  1. 애플리케이션에서 캐시 저장소를 사용합니다:
use Illuminate\Support\Facades\Cache;
 
// 값을 저장합니다 (Redis에 기록)
Cache::store('recall')->put('key', 'value', 3600);
 
// 값을 검색합니다 (첫 번째 호출은 Redis에 액세스하며, 이후 호출은 로컬 캐시 사용)
$value = Cache::store('recall')->get('key');
 
// 값을 삭제합니다
Cache::store('recall')->forget('key');

작동 방식

  1. 첫 번째 읽기: Redis에서 값을 가져와 로컬 APCu/Swoole Table 캐시에 저장됩니다.
  2. 이후 읽기: 값이 로컬 메모리에서 직접 제공됩니다 (서브 밀리초).
  3. 어디서든 쓰기: 클라이언트가 Redis에서 키를 수정하면, Redis는 무효화 메시지를 보냅니다.
  4. 자동 무효화: Recall은 메시지를 수신하고 로컬 캐시에서 키를 제거합니다.
  5. 다음 읽기: 새로운 값이 Redis에서 가져와서 다시 로컬에 캐시됩니다.

이 패턴은 요청 간에 워커가 지속되는 Laravel Octane 환경에서 특히 강력하여 로컬 캐시가 쌓이고 많은 요청을 메모리에서 제공할 수 있습니다.

Octane 통합

Recall은 사용 가능할 때 Laravel Octane와 자동으로 통합됩니다:

추가 구성은 필요하지 않습니다. Octane이 설치되면 자동으로 통합됩니다.

구성

구성 파일을 발행합니다:

php artisan vendor:publish --tag=recall-config

이렇게 하면 다음 옵션을 가진 config/recall.php가 생성됩니다:

활성화/비활성화

'enabled' => env('RECALL_ENABLED', true),

비활성화된 경우, Recall은 로컬 캐시 레이어를 사용하지 않고 Redis에 직접 전달합니다. 디버깅이나 점진적 롤아웃에 유용합니다.

Redis 저장소

'redis_store' => env('RECALL_REDIS_STORE', 'redis'),

Redis 작업을 위해 사용할 Laravel 캐시 저장소입니다. 이는 config/cache.php에서 구성된 Redis 저장소를 참조해야 합니다.

캐시 접두사

'cache_prefixes' => [],

이 접두사와 일치하는 키만 로컬에 캐시합니다. 비워두면 모든 키가 캐시됩니다.

// 사용자 및 설정 키만 로컬에 캐시
'cache_prefixes' => ['users:', 'settings:', 'config:'],

자주 변경되는 고부하 키가 있을 때 로컬 캐시를 하지 않아야 할 때 유용합니다.

로컬 캐시 구성

'local_cache' => [
// 드라이버: "apcu" 또는 "swoole"
'driver' => env('RECALL_LOCAL_DRIVER', 'apcu'),
 
// 로컬 캐시 키를 위한 접두사
'key_prefix' => env('RECALL_LOCAL_PREFIX', 'recall:'),
 
// 기본 TTL(무효화가 누락된 경우의 안전망)
'default_ttl' => (int) env('RECALL_LOCAL_TTL', 3600),
 
// Swoole Table 크기 (2의 거듭제곱, swoole 드라이버 전용)
'table_size' => (int) env('RECALL_SWOOLE_TABLE_SIZE', 65536),
 
// Swoole Table의 최대 바이트 (swoole 드라이버 전용)
'value_size' => (int) env('RECALL_SWOOLE_VALUE_SIZE', 8192),
],

APCu 드라이버 (기본)

APCu 드라이버는 모든 PHP 환경 및 Octane 서버(Swoole, RoadRunner, FrankenPHP)에서 작동합니다. 캐시된 값은 모든 PHP 프로세스에서 접근 가능한 공유 메모리에 저장됩니다.

요구 사항:

Swoole Table 드라이버

Swoole Table 드라이버는 Swoole의 공유 메모리 테이블을 사용하여 동일한 워커 내 여러 코루틴에서 일관된 액세스를 제공합니다. Swoole/OpenSwoole 환경에 가장 적합합니다.

구성 팁:

Octane 리스너

'listeners' => [
// 워커 시작 시 연결 예열 (첫 요청 지연 감소)
'warm' => env('RECALL_LISTEN_WARM', true),
 
// 틱 이벤트에서 무효화 처리 (반응성이 더 뛰어나지만 약간의 오버헤드)
'tick' => env('RECALL_LISTEN_TICK', false),
],

연결 예열

사용하도록 설정되면 Recall은 Octane 워커가 시작될 때 Redis 무효화 구독을 설정합니다. 이는 첫 요청의 연결 지연을 없애줍니다.

틱 처리

사용하도록 설정되면 Recall은 요청 이벤트 외에도 Octane 틱 이벤트에서 무효화 메시지를 처리합니다. 이는 추가적인 약간의 오버헤드 비용을 들이더라도 더 반응성이 좋은 캐시 무효화를 제공합니다.

고급 사용법

수동 무효화 처리

오래 실행되는 프로세스에서 무효화를 수동으로 처리해야 하는 경우:

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
$manager->processInvalidations();

로컬 캐시 비우기

Redis에 영향을 주지 않고 로컬 캐시만 비우려면:

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
$manager->flushLocalCache();

연결 관리

use DefectiveCode\Recall\RecallManager;
 
$manager = app(RecallManager::class);
 
// 무효화 구독이 연결되었는지 확인
if ($manager->isConnected()) {
// ...
}
 
// 수동으로 연결 해제
$manager->disconnect();

최적화

워커 요청 제한

Laravel Octane은 메모리 누수를 방지하기 위해 구성 가능한 요청 수 후에 워커를 순환합니다. 워커가 순환될 때 로컬 캐시는 지워집니다. 이 제한을 늘리면 Recall의 로컬 캐시가 더 오래 지속되어 캐시 적중률이 향상됩니다.

config/octane.php에서:

// 기본값은 순환 전 500 요청입니다.
'max_requests' => 10000,

높은 값은 더 나은 캐시 활용을 의미하지만 애플리케이션이 메모리 누수를 일으키지 않는지에 대한 확신이 필요합니다. 이 값을 조정할 때 워커 메모리 사용량을 모니터링하세요.

접두사를 이용한 선택적 캐싱

로컬에 어떤 키가 캐시될지를 제어하기 위해 cache_prefixes를 사용하세요. 이는 다음과 같은 경우에 유용합니다:

// config/recall.php
'cache_prefixes' => [
'users:', // 사용자 데이터를 로컬에 캐시
'settings:', // 애플리케이션 설정을 캐시
'products:', // 제품 카탈로그를 캐시
],

이 접두사와 일치하지 않는 키는 여전히 작동하지만 로컬 캐싱을 우회하고 Redis로 직접 전송됩니다.

메모리 고려 사항

APCu 메모리

APCu는 모든 PHP 프로세스에 걸쳐 메모리를 공유합니다. php.ini에서 메모리 한계를 설정하세요:

; 기본값은 32MB로, 더 큰 캐시가 필요하면 증가시킵니다.
apc.shm_size = 128M

apcu_cache_info()로 APCu 사용량을 모니터링하세요:

$info = apcu_cache_info();
$memory = $info['mem_size']; // 현재 메모리 사용량(바이트)

Swoole Table 크기 조정

Swoole Table은 생성 시 고정 용량을 가집니다. 예상 캐시 크기에 따라 계획하세요:

'local_cache' => [
// 최대 항목 수 (2의 거듭제곱이어야 합니다.)
'table_size' => 65536, // 64K 항목
 
// 직렬화 값의 최대 바이트 수
'value_size' => 8192, // 값당 8KB
],

메모리 사용량: table_size × (value_size + 오버헤드). 65536 항목 및 8KB 값의 테이블은 약 512MB를 사용합니다.

일반적인 패턴

애플리케이션 구성

// 캐시 기능 플래그 및 설정
$features = Cache::store('recall')->remember('config:features', 3600, function () {
return Feature::all()->pluck('enabled', 'name')->toArray();
});
 
// 설정이 변경되면 모든 워커가 자동으로 업데이트를 수신합니다.

자주 액세스하는 참조 데이터

// 제품 카테고리 캐시
$categories = Cache::store('recall')->remember('categories:all', 3600, function () {
return Category::with('children')->whereNull('parent_id')->get();
});
 
// 통화 환율 캐시
$rates = Cache::store('recall')->remember('rates:exchange', 300, function () {
return ExchangeRate::all()->pluck('rate', 'currency')->toArray();
});

캐시 태그 대안

Recall은 캐시 태그를 지원하지 않지만 접두사를 사용하여 유사한 기능을 구현할 수 있습니다:

// 태그 대신 일관된 접두사를 사용합니다.
Cache::store('recall')->put("blog:posts:{$id}", $post, 3600);
Cache::store('recall')->put("blog:comments:{$postId}", $comments, 3600);
 
// 접두사로 모든 블로그 관련 캐시를 비우기 (수동 구현 필요)
// 또는 데이터가 변경될 때 자동 무효화에 의존

제한 사항

Redis 클러스터 모드

Recall은 Redis 클러스터 모드를 지원하지 않습니다. CLIENT TRACKING 명령의 REDIRECT 옵션은 데이터 연결과 무효화 구독 연결이 동일한 Redis 노드에 있어야 합니다. 클러스터에서는 키가 해시 슬롯에 따라 여러 노드에 분산되므로 다른 노드에 저장된 키에 대한 무효화를 수신할 수 없습니다.

클러스터 Redis 배포를 위해 고려하세요:

지원 지침

우리의 오픈 소스 패키지를 선택해 주셔서 감사합니다! 이 지원 지침을 확인하는데 잠시 시간을 할애해 주세요. 이 지침은 우리 프로젝트를 최대한 활용하는 데 도움이 될 것입니다.

커뮤니티 주도 지원

우리의 오픈 소스 프로젝트는 훌륭한 커뮤니티에 의해 구동됩니다. 질문이 있거나 도움이 필요하다면 StackOverflow와 다른 온라인 리소스가 최선의 선택입니다.

버그 및 기능 우선순위

오픈 소스 프로젝트를 관리하는 현실은 모든 보고된 버그나 기능 요청을 즉시 처리할 수 없다는 것입니다. 우리는 문제를 다음과 같은 순서로 우선 처리합니다:

1. 유료 제품에 영향을 주는 버그

우리의 유료 제품에 영향을 미치는 버그는 항상 최우선 순위입니다. 경우에 따라 우리에게 직접적인 영향을 미치는 버그만 처리할 수도 있습니다.

2. 커뮤니티 풀 리퀘스트

버그를 발견하고 해결책이 있다면, 풀 리퀘스트를 제출해 주세요. 우리 제품에 영향을 미치는 문제 다음으로, 이러한 커뮤니티 주도 수정을 우선적으로 처리합니다. 리뷰하고 승인된 후, 귀하의 해결책을 병합하고 기여를 인정할 것입니다.

3. 재정적 지원

언급된 범주 외의 문제에 대해서는 해결을 위한 자금을 기부할 수 있습니다. 각 열려 있는 문제는 재정적으로 기여할 수 있는 주문 양식에 연결되어 있습니다. 제공된 자금 금액에 따라 이러한 문제를 우선 처리합니다.

커뮤니티 기여

오픈 소스는 커뮤니티가 활발할 때 성장합니다. 버그를 수정하지 않더라도 코드 개선, 문서 업데이트, 튜토리얼, 또는 커뮤니티 채널에서 다른 사람들을 도와주는 방식으로 기여하는 것을 고려해 보세요. 우리는 모두가 커뮤니티로서 오픈 소스 작업을 지원하는 것을 강력히 권장합니다.

다시 말해, DefectiveCode는 유료 제품에 영향을 미치는 정도, 커뮤니티 풀 리퀘스트 및 문제에 대한 재정적 지원을 기반으로 버그를 우선 처리할 것입니다.

라이선스 - MIT 라이선스

Copyright © Defective Code, LLC. 모든 권리 보유.

본 소프트웨어 및 관련 문서 파일(이하 "소프트웨어")의 사본을 얻은 모든 개인에게 무료로 사용 권한이 부여되며, 소프트웨어를 제한 없이 사용할 수 있습니다. 여기에는 소프트웨어를 사용, 복사, 수정, 병합, 게시, 배포, 서브 라이센스 및/또는 판매하는 권리가 포함되며, 소프트웨어가 제공된 사람에게 그러한 권한을 허용하는 것이 포함됩니다. 단, 다음 조건을 준수해야 합니다:

위의 저작권 고지 및 이 사용 허가 고지는 소프트웨어의 모든 복사본 또는 상당 부분에 포함되어야 합니다.

소프트웨어는 "있는 그대로" 제공되며, 명시적이거나 암시적인 어떤 종류의 보증도 없이 제공됩니다. 여기에는 상업성, 특정 목적에 대한 적합성 및 비침해성에 대한 보증이 포함되지만 이에 국한되지 않습니다. 어떤 경우에도 저자나 저작권자는 계약, 불법행위 또는 기타 방식으로 소프트웨어 또는 소프트웨어의 사용이나 기타 거래와 관련하여 발생하는 어떤 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다.