# Memcached 사용 가이드

## 고도몰 멤캐시 소개

#### 라이브러리

* 고도몰 멤캐시 기능은 Symfony Cache v3.4 라이브러리를 바탕으로 구현되었습니다.
* [Symfony Cache v3.4 구현 코드 바로가기](https://github.com/symfony/symfony/tree/3.4/src/Symfony/Component/Cache)

#### Eviction 정책

* 고도몰 멤캐시 Eviction 정책은 LRU (Least Recently Used) 방식입니다.
* [Symfony 공식 구현에서의 Memcached 설정 예시](https://github.com/symfony/symfony/blob/0a9296a8b23360475c282cd98b1fd36e3937d259/src/Symfony/Component/Cache/Adapter/MemcachedAdapter.php#L22-L31)

## 코딩 가이드

### Using namespaces

* 고도몰에서 제공하는 캐시 함수는 SimpleCache 클래스 내부에 구현되어 있습니다.
* 캐시 함수를 사용하는 곳에서 SimpleCache namespaces 를 불러와주세요.

```php
use Framework\SimpleCache\SimpleCache;
```

### 고도몰 캐시 함수

* 고도몰에서 제공하는 캐시 함수의 종류는 총 5개입니다.
  * set()
  * has()
  * get()
  * getSet()
  * delete()

#### set

```php
/**
 * Save cache item
 *
 * @param string $key
 * @param mixed $value
 * @param int $ttl 1 or more, up to 300 (seconds)
 *
 * @return bool stating if caching succeeded or not
 */
```

* 캐시 내부에 데이터를 저장하는 함수입니다.

```php
use Framework\SimpleCache\SimpleCache;

$cacheKey = "(CACHE_KEY)";
$cacheValue = "(CACHE_VALUE)";
$ttl = 300;

$setResult = SimpleCache::init(SimpleCache::MEMCACHED)->set($cacheKey, $cacheValue, $ttl);
```

* 위와 같이 set 함수를 이용할 수 있습니다.
* ttl 값은 300을 초과할 수 없습니다.

#### has

```php
/**
 * Confirms if the cache contains specified cache item.
 *
 * @param string $key
 *
 * @return bool True if item exists in the cache, false otherwise
 */
```

* 캐시 내 조회하고자 하는 key에 대한 데이터가 있는지 확인하는 함수입니다.

```php
use Framework\SimpleCache\SimpleCache;

$cacheKey = "(CACHE_KEY)";
$hasKey = SimpleCache::init(SimpleCache::MEMCACHED)->has($cacheKey);
```

* 위와 같이 has 함수를 이용할 수 있습니다.

#### get

```php
/**
 * Fetches cache item.
 *
 * @param string $key
 *
 * @return mixed The corresponding values found in the cache, returning null if no value is present in the cache.
 */
```

* 캐시 내 저장된 데이터의 value를 반환하는 함수입니다. \
  조회하고자 하는 키값이 존재하지 않을 경우 null을 반환합니다.

```php
use Framework\SimpleCache\SimpleCache;

$cacheKey = "(CACHE_KEY)";
$cacheData = SimpleCache::init(SimpleCache::MEMCACHED)->get($cacheKey);
```

* 위와 같이 get 함수를 이용할 수 있습니다.

#### getSet

```php
/**
 * Finding the corresponding value in the cache, 
 * setting the value if it is not present in the cache, and returning the value stored in the cache.
 *
 * @param string $key
 * @param callable $callback
 * @param int $ttl 1 or more, up to 300 (seconds)
 *
 * @return mixed The corresponding values found in the cache, returning values from the cache. 
 *               If no value is present in the cache, it returns the result of the lambda function provided as the second parameter.
 */
```

* 캐시 내 조회하고자 하는 키값의 데이터가 있을 경우, 캐시 데이터를 반환하고 캐시 내 조회하고자 하는 키값의 데이터가 없을 경우, 2번째 파라미터의 람다 함수 내 로직 실행 결과를 캐시에 set 한 다음 저장된 데이터를 반환합니다.
* `$callback` 이 `null` 일 경우에는 캐시에 저장되는 값이 없으며, `null` 로 return 됩니다.

```php
use Framework\SimpleCache\SimpleCache;

$cacheKey = "(CACHE_KEY)";
$ttl = 300;
$cacheData = SimpleCache::init(SimpleCache::MEMCACHED)->getSet(
    $cacheKey,
    function () {
        $cacheValue = "(CACHE_VALUE)";
        return $cacheValue;
    },
    $ttl
);
```

* 위와 같이 getSet 함수를 이용할 수 있습니다.
* ttl 값은 300을 초과할 수 없습니다.

#### delete

```php
/**
 * Removes cache item.
 *
 * @param string $key
 *
 * @return mixed True if the items were successfully removed, false otherwise
 */
```

* 캐시 내 저장된 데이터를 삭제하는 함수입니다.

```php
use Framework\SimpleCache\SimpleCache;

$cacheKey = "(CACHE_KEY)";
$cacheData = SimpleCache::init(SimpleCache::MEMCACHED)->delete($cacheKey);
```

* 위와 같이 delete 함수를 이용할 수 있습니다.

### 개발 시 유의사항

* 캐싱 처리가 필요한 위치에서 직접 가이드에 제공된 함수를 호출하여 사용해주세요.

  ```php
  /**
   * 캐시 내 goods_benefit_config 키에 할당된 값이 있는지 확인합니다.
   * set()을 하지 않았거나 ttl(만료 시간)이 지나 캐시가 삭제된 경우에는 has() 값이 false 로 반환됩니다.
   */
  $cacheKey = "(CACHE_KEY)";
  if (SimpleCache::init(SimpleCache::MEMCACHED)->has($cacheKey)) {
      /**
       * goods_benefit_config 키에 할당된 값이 있으면
       * 캐시에서 값을 가져와 $goodsBenefitConfig 에 할당합니다.
       */
      $goodsBenefitConfig = SimpleCache::init(SimpleCache::MEMCACHED)->get($cacheKey);

  } else {
      /**
       * goods_benefit_config 키에 할당된 값이 없으면
       * 저장을 원하는 데이터를 가져와 다시 캐시에 set()을 합니다.
       * 
       * set()을 통해 goods_benefit_config 키에는 $goodsBenefitConfig 값이 300초 동안 저장됩니다.
       */
      $goodsBenefit = \App::load('\\Component\\Goods\\GoodsBenefit');
      $goodsBenefitConfig = $goodsBenefit->getConfig();
      $ttl = 300;
      SimpleCache::init(SimpleCache::MEMCACHED)->set($cacheKey, $goodsBenefitConfig, 300);
  }

  /**
   * getSet 함수를 활용한 캐시 개발 가이드입니다.
   * 1번째 파라미터의 $cacheKey에 대한 데이터가 캐시에 있을 경우,
   * 2번째 람다 함수 내 로직이 수행되지 않고 캐시 내 저장된 데이터가 반환됩니다.
   *
   * 1번째 파라미터의 $cacheKey에 대한 데이터가 캐시에 없을 경우,
   * 2번째 람다 함수 내 로직이 수행된 결과가 캐시 내 set 되며, set 된 결과가 반환됩니다.
   */
  $cacheKey = "(CACHE_KEY)";
  $ttl = 300;
  $goodsBenefitConfig = SimpleCache::init(SimpleCache::MEMCACHED)->getSet(
      $cacheKey,
      function () {
          $goodsBenefit = \App::load('\\Component\\Goods\\GoodsBenefit');
          $goodsBenefitConfig = $goodsBenefit->getConfig();
          return $goodsBenefitConfig;
      },
      $ttl
  );
  ```

{% hint style="danger" %} <mark style="color:red;">**캐싱 처리를 위한 클래스를 생성하여 기존 클래스를 상속받는 방법은 성능 저하와 클래스 간의 복잡성을 증가시킬 수 있습니다.**</mark> \ <mark style="color:red;">**가급적 가이드 내에 소개된 방식에 맞춰 활용하시는 것을 권장합니다.**</mark>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devcenter-help.nhn-commerce.com/other-guide/memcached.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
