[AWS] RDS 엘라스틱 캐쉬 - 레디스(Redis)
AWS Elasticache는 Amazon Web Services(AWS)에서 제공하는 완전 관리형 인메모리 데이터 스토어 및 캐시 서비스입니다. 이 서비스는 레디스와 Memcached를 지원하며, 이를 통해 고성능, 스케일링 가능한 및 비용 효율적인 인메모리 캐시 솔루션을 제공합니다.
Redis는 RDB가 아닙니다.
RDB에서 IO를 줄이거나 슬로우쿼리가 약간 있거나 많은 게시물이 있을때 키 밸류의 인메모리 디비를 사용하면 잇점이 있기 때문에 사용하는 데이터 베이스 입니다.
AWS 엘라스틱캐쉬 REDIS
레디스(Redis)에 대해 설명하자면, Redis는 고성능의 분산 저장 시스템으로서 키-값 구조의 데이터를 메모리에 저장하여 빠른 읽기/쓰기 작업을 가능하게 합니다. Redis는 문자열, 리스트, 세트(set), 정렬된 세트(sorted set), 해시 등 다양한 데이터 타입을 지원합니다.
AWS Elasticache for Redis는 이러한 Redis의 기능들을 AWS 환경에서 사용할 수 있게 해주며, 아래와 같은 주요 기능들이 있습니다
- 고성능: AWS Elasticache for Redis는 메모리 내 데이터 처리로 매우 빠른 성능을 제공합니다.
- 확장성: 클러스터 크기 조정이나 여러 클러스터 간에 자동 분할(sharding) 등의 기능으로 확장성이 용이합니다.
- 내구성과 가용성: 자동 복제(replication), 자동 장애 조치(failover), 백업 및 복원 기능 등으로 데이터 안정성과 서비스 가용성을 보장합니다.
- 보안: VPC 네트워크 내에서 동작하며 SSL/TLS 프로토콜로 암호화된 연결을 지원하여 보안을 유지합니다.
require 'vendor/autoload.php';
class DatabaseWithCache {
private $db;
private $cache;
public function __construct($dbHost, $dbName, $dbUser, $dbPassword, $cacheEndpoint) {
// Initialize MySQL connection
$this->db = new PDO("mysql:host=$dbHost;dbname=$dbName", $dbUser, $dbPassword);
// Initialize Redis connection
$this->cache = new Predis\Client([
'scheme' => 'tcp',
'host' => '<elasticache-endpoint>',
'port' => 6379,
]);
}
public function fetch($query, array $params = [], bool $useCache = true) {
// Generate cache key from query and parameters
ksort($params);
$cacheKey = md5($query . serialize($params));
if ($useCache && ($result = @$this->cache->get($cacheKey))) {
return unserialize($result);
} else {
// Execute the query and fetch result from database
try{
if (!empty($params)) {
foreach ($params as &$param){
if(is_int(strpos(strtolower($param), ':'))){
throw new Exception("Parameters should not contain colon (:)");
}
}
}
$_sql = str_replace(array_keys( array_map(function($_key){ return ':'.$_key; },$params)),array_values( array_map(function($_value){ return "'".$_value."'"; },$params)),$query);
$_stmt = @$this->pdoObject->prepare($_sql);
$_stmt -> execute();
while ($_row=$_stmt -> fetch(PDO::FETCH_ASSOC)){
$_result[]=$_row;
}
// Cache the result in Redis (if enabled)
if ($useCache && isset($_result)) {
@$this->cache->setex($cacheKey, 3600 /* expire after 1 hour */, serialize($_result));
}
return $_result;
}catch(Exception $__e){
echo $__e -> getMessage();
}
}
}
public function updateOrDelete(string $__query,array $__param){
try{
foreach($__param as &$__p){
if(is_int(strpos(strtolower($__p), ':'))){
throw new Exception("Parameters should not contain colon (:)");
}
}
$__sql=str_replace(array_keys(array_map(function($__k){return ':'.$__k;},$__param)),array_values(array_map(function($__v){return "'".$__v."'";},$__param)),$__query);
$__stmt=@$this->pdoObject->prepare($__sql);
$__stmt -> execute();
// Generate cache key from query and parameters
ksort($__param);
$cacheKey = md5($__query . serialize($__param));
// Invalidate the cache
@$this->cache->del($cacheKey);
}catch(Exception $__e){
echo $__e -> getMessage();
}
}
}
$db = new DatabaseWithCache('dbHost', 'dbName', 'dbUser', 'dbPassword', '<elasticache-endpoint>');
// Fetch data with caching
$result = $db->fetch("SELECT * FROM users WHERE id = :id", ['id' => 1]);
// Update data and invalidate cache
$db->updateOrDelete("UPDATE users SET email = :email WHERE id = :id", ['email' => 'newemail@example.com', 'id' => 1]);
// Delete data and invalidate cache
$db->updateOrDelete("DELETE FROM users WHERE id = :id", ['id' => 1]);
- update, delete 할때는 redis에서 삭제 합니다.
- select 할때는 redis에서 있는지 확인 후 사용하고, 없으면 DB 조회 후 redis에 입력 합니다.