memcached increment always return false codeigniter.. 낫웤킹


배경 설명

문제상황

페이지 내에서 아주아주 크고 서비스내 여기저기서 빈번히 이용하며, 트랜잭션 걸려 사용하는 테이블을 매번 조회해서 보여주어야했다.

문제의 해결방법

선임이 매번 db에서 조회하는 것이 불필요하다했다. 그래도 매번 db 조회하는 것이 좋지 않다는 것은 알아 memcached를 사용하고 있었다. db를 조회한뒤 memcached에 60초동안 넣어두고, 또 60초 동안 넣어두니까 이정도면 괜찮지 않냐고 물었다. 

선임의 반응은 탐탁치 않았다. 캐싱을 이용하라 했다. 멤캐시로 겟하고, 늘어나는 것은 멤캐시 인크리먼트를 시켜서 불필요하게 db를 조회하는 일이 없도록 하는 것이 좋겠다고 하였다. 

(그 당시에는 항상 그냥 해왔던 부분이어서 음.. 꼭 해야하나? 라고 생각했는데 하고나니까 정말 필요했던 것 같다.)

그렇다면, 이제 구현해야할 나의 임무

  1. memcached로 get해서 보여주기
    1. memcached로 get했을때 없으면 초기 db에서 조회해서 memcached save 해주기
  2. 그 db에 insert가 생기는 순간에 memcached increment해주기.(매번 db를 조회하지 않을거기때문에) 

그래서 해결했나요?

해결하긴 해결했다. 하지만.. 껌이라고 생각했다 돌씹은 느낌이었다.. 코딱지를 파는 임무를 받았으나 너무 오래 많이파서 코피난 느낌이었다.. 

"memcache get쓰고있고,  save도 쓰고있으니까! increment하나 추가하는게 뭐 얼마나걸리겠어" 했지만 나는 또 삽질에 삽질을 했다. 어디서? increment에서..!


어떤 삽질을 하였나요?

우선 php.net의 memcached 사용법을 보았다. 그리고 memcached incrment 사용법을 보았다.
역시 깔끔깔끔했다.
<?php
$m 
= new Memcached();
$m->addServer('localhost'11211);

$m->set('counter'0);
$m->increment('counter');
$n $m->increment('counter'10);
var_dump($n);

$m->set('counter''abc');
$n $m->increment('counter');
// ^ will fail due to item value not being numeric
var_dump($n);
?>

The above example will output:

int(11)
bool(false)

음 increment는 당연하게 int만 되는 것이군. false 혹은 true를 반환하는 군! 했다.

예제와 똑같은 코드를 사용하고 싶다만, 우리 회사는 코드이그나이터의 캐싱드라이버를 사용하고 있다. 프레임워크가 도와주는데 굳이 직접 생성하여 쓸필요가 없지! 했다.


그럼 이제 내가 항상 쓰던 save를 해볼까 ^-^ 했다.

$this->cache->memcached->save('yujinee', 1, 0);

'yujinee'라는 키에 1이라는 값을 영구적(0)으로 넣고자 했다. 음 굿! 잘 된다.


그럼 이제 내가 항상 하던 get을 해볼까?

echo $this->cache->memcached->get('yujinee');

'yujinee'라는 키로 조회를 하면? 1이 나온다. 


그럼 이제 처음으로 써보는 increment 고고고~! 

$this->cache->memcached->increment('yujinee');
echo  $this->cache->memcached->get('yujinee');
내가 기대한 값은 increment에 키값만 넣은 경우 1이 늘어나기 때문에 yujinee에는 2가 되어있는 상황. 하지만.. 1이 나왔다.
var_dump($this->cache->memcached->increment('yujinee')); 로 찍어보니.. 
bool(false) 가 나왔다. 

나의 삽질목록.

  1. 아 뭐야~ php.net참고해보니 int가 아닐때 false를 뱉던데.. save 할때 int로 값을 줘볼까? 
    1. $this->cache->memcached->save('yujinee', (int) 1, 0); 이렇게! 
    2. $this->cache->memcached->increment('yujinee', 10); 을 하면..1
    3. bool(false);
  2. 아 뭐지..^^;;; ? 다른 것들도 안되는게 있나? 다 찍어보자! 
    1.  $this->cache->memcached->is_supported() 된다. 
    2. $this->cache->memcached->get_metadata() 잘 된다. 심지어 data도 int로 들어가있는 것을 확인할 수 있었다.
    3. $this->cache->memcached->decrement() 안된다. 얘도 자꾸만 false이다.

Codeigniter cache driver
Codeigniter memcache always return false 다 검색해봤다. 

안나온다 나같은 상황이 ㅜ 그래서 직접 선언해서 사용해보았고, 그제서야 문제를 알수있었다. 


문제는 raw 정보! 잡았다 요놈!

$m = new Memcached();
$m->addServer('localhost', 11211);

$m->set('counter', 0);
$m->increment('counter');
$n = $m->increment('counter', 10);

어이없게도 위의 예제코드는 잘만돌아갔다. 그럼 뭐가 문제였던걸까? 문제는 세이브할때 raw를 true로 주지 않았기때문이었다. 
save($id, $data, $ttl = 60, $raw = FALSE) 
여기서 $raw가 false 였었고, 코드이그나이터에서 제공하는 드라이버로 get을 했을때는 int를 반환하지만, 실제로 memcache로 접근해서 찍어보니
array ^^로 구성되어있는 것을 확인할 수 있었다. 

그럼 이제 끝~

내가 항상 사용할때, 그리고 여러 예제들을 보았을때 raw에 대한 파라미터는 주로 생략되어있었어서 저게 문제일거라 생각도 하지 못했다.
코드이그나이터가 원망스럽기도했다. array였으면 array라고 알려주던가 왜 int라고 알려줘서 전혀 감이 오지 않았다. 
교훈은 그거였다. 내가 사용하는 함수가 어떻게 되어있는지를 먼저 확인해볼것! 파라미터를 확인해볼것! 괜히 이상한데를 삽질해서 많은 시간을 버렸다. 
그래도 결과물에 굉장히 만족한다. 오래걸리던 페이지가 디비에 접근하지 않으니 엄청빨라졌따. :> 다음에도 비슷한 조건이 있다면, 꼭 정확한 정보가 아니어도 되는데 너무 많은 db조회를 낭비하고 있따면 cache로 바꿔야겠따. 너무 오래 이걸 골머리를 앓아서 창피하다. 머리가 안돌아갔따.. ㅜㅜ누군가는 이걸봐서 덜 삽질했음 좋겠다.


+ Recent posts