Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

캐싱 시스템 리팩토링 #449

Merged
merged 42 commits into from
Apr 24, 2016
Merged

캐싱 시스템 리팩토링 #449

merged 42 commits into from
Apr 24, 2016

Conversation

kijin
Copy link
Member

@kijin kijin commented Apr 17, 2016

캐싱 시스템을 전반적으로 개선하기 위한 PR입니다.

  • 깔끔한 구조의 Rhymix\Framework\Cache 클래스 추가
  • APC, Memcached, Redis, XCache, WinCache, 파일 캐시 등의 "드라이버"들을 재구성
  • 기존의 CacheHandler 호출시 새 클래스로 자동 전달함
  • 관리 모듈의 캐시파일 재생성 루틴을 정비하여 낡은 캐시 파일이 계속 쌓이는 것을 방지
  • 별다른 설정을 하지 않아도 파일 캐시를 기본으로 사용하도록 변경 (실험적)
  • 다수의 작은 파일을 생성하는 파일 캐시보다 성능이 좋고 관리가 편리한 SQLite 캐시 도입 (실험적)
  • 공통 기능 및 기본 제공되는 모듈에서 새 클래스를 직접 호출하도록 변경
  • TTL 대신 유닉스 타임스탬프를 넘겨준 경우의 처리 일관성 개선
  • 관리 화면에 기본 TTL 설정 추가 (5분 ~ 30일, 기본값은 24시간으로 할 예정)
  • 유닛 테스트 작성

캐시 그룹 키를 비롯한 기존의 기능들은 거의 대부분 그대로 유지됩니다.

캐시에 데이터를 저장할 때 TTL 값을 분명히 지정하는데도 나중에 불러올 때 다시 한 번 확인하는 비효율성을 제거했습니다. 데이터를 불러오는 시점에서 TTL 확인에 의존하는 모듈은 약간의 수정이 필요할 듯 합니다. (예: 7c0c4dd)

@kijin kijin added the improvement 기능 개선 요청 또는 기능 개선 PR label Apr 17, 2016
@kijin kijin self-assigned this Apr 17, 2016
@kijin
Copy link
Member Author

kijin commented Apr 17, 2016

캐시가 지원되는지 확인할 필요도 없고 인스턴스를 생성할 필요도 없습니다.

Rhymix\Framework\Cache::set($key, $value, $ttl);

아무 데서나 쉽게 호출할 수 있습니다.

$value = Rhymix\Framework\Cache::get($key);

아예 cache_get(), cache_set() 함수를 추가해서 더 쉽게 만들어 버릴까요? ㅎㅎ

@bjrambo
Copy link
Member

bjrambo commented Apr 17, 2016

@kijin 이렇게하면 이점이 어떤건가요? Rhymix\Framework\Cache::set($key, $value, $ttl); 요거 말하는거..

그리고 사용하는거에서 개발자가 어떻게 할수있는지..

@kijin
Copy link
Member Author

kijin commented Apr 17, 2016

@bjrambo

기존 코드랑 비교해 보아요... 특히 그룹 키가 포함되면 완전 골때립니다.

$oCacheHandler = CacheHandler::getInstance();
if($oCacheHandler->isSupport())
{
    $cache_key = $oCacheHandler->getGroupKey('member', $key);
    $value = $oCacheHandler->get($cache_key);
}

vs.

$value = Rhymix\Framework\Cache::get("member:$key");

뭐 이런 코드야 그냥 복붙해서 쓰면 되니까 큰 차이가 없을 수도 있지만, 대부분의 변화는 성능과 안정성을 높이기 위한 Cache 클래스의 내부 구조 단순화입니다. 접두사 같은 것을 Memcached, APC 등 각 드라이버에서 멋대로 만들지 않고 Cache 클래스에서 일관성있게 처리해 주고, 같은 버전의 라이믹스로 만들어진 여러 사이트가 하나의 Memcached를 공유하더라도 서로의 데이터를 덮어쓰지 않도록 보장하는 등...

@bjrambo
Copy link
Member

bjrambo commented Apr 17, 2016

음..ㅠㅠ 제가 이부분은 잘 몰라서요.

만약 개발된 모듈이나 게시판 모듈같은곳에서 사용하는 캐시들을 처리하는 구간이 저 부분인건가요?

@kijin
Copy link
Member Author

kijin commented Apr 17, 2016

네, 서드파티 모듈에서 캐시를 사용하는 경우는 비교적 드물고요... 현재는 라이믹스 내부에서 모듈 설정이나 회원정보, 위젯 등을 캐싱하는 데만 약간씩 사용됩니다. 캐시를 쓰기 쉽게 만들어 놓았으니 앞으로 점점 확대해 봐야죠.

@bjrambo
Copy link
Member

bjrambo commented Apr 17, 2016

그럼 일반 모듈에서는 사실상 executeQuery함수 사용하는곳 제외하곤 많은 캐시효관ㄴ 없겟군요. 다만 내부 코드가 모두 캐시를 개선하니.. 그부분에서 효과가있고..


// remove module extend cache
FileHandler::removeFile(_XE_PATH_ . 'files/config/module_extend.php');
Rhymix\Framework\Storage::delete(RX_BASEDIR . 'files/config/module_extend.php');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위코드에서는 \가있는데 여긴 없어도 정상적으로 작동하는건가요?
있고없고의 차이점은 어떤건가요..'ㅡ'?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 모듈은 네임스페이스를 안 쓰기 때문에 상관없긴 하지만... Rhymix\Framework 작업할 때는 습관적으로 쓰는데 여기서는 빼먹었네요 ㅎㅎ

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 그렇군요! ㅎㅎ 감사합니닷

@@ -34,7 +34,7 @@ public static function init($config)
{
$class_name = '\\Rhymix\\Framework\\Drivers\\Cache\\' . $config['driver'];
}
elseif (preg_match('/^(apc|memcache|redis|wincache|file)/', strval(array_first($config)), $matches))
elseif (preg_match('/^(apc|dummy|file|memcache|redis|sqlite|wincache|xcache)/', strval(array_first($config)), $matches))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

더미캐시는 어떤..거에요??
그리고, 일부 느리다고 판단되는 캐시들에 대해서도 지원여부 정해두는게 좋지 않을까요

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예를들어, 현재 최저 라이믹스의 버전은 5.5.9(?) 쯔음 되는것같은데, 사실 5.5 에서 opcache는 자동으로 사용되고 있습니다. 하지만 xcache확장모듈을 설치하고 같이 빌드할경우 opcache는 사용할 수 없는 상태가 되지요. 오히려 성능도 별로고, opcache기본으로 지원하는등등을 좀 고려해서 사용자들에게 지원여부를 조금 바꾸는게 어떤가 하고 의견을 드려봅니다.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

더미는 실제로 데이터가 저장되지 않는 테스트용 캐시입니다. 하나쯤 있으면 편리하겠더군요.

나머지는 일단 소스가 준비되어 있어서 모두 추가하긴 했는데, wincache 같은 것은 현재 테스트조차 안 되고 있는 게 현실이죠 ㅡ.ㅡ;;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실제로 재 성능을 재대로 해주지 못한다고 판단하는 xcache나, wincache같이 테스트가 힘든 부분의 대해서는 오히려 지원을 끊는 방법도 생각해볼 필요성이..

뭐 wincache는.. 일반 윈도우 서버 사용자가 있을 수 있으니 냅둬야할지 여부도 정해야할 것 같고요..'ㅁ'..

전체적으로 자주 쓰이는 파일, 맴캐시같은 것들을 위주로하고, 앞으로 활용도라던지 여러가지 좋은점이 있을뻡한 redis나 등등은 좀 기간을 두면서 지켜 보는것이 좋지 않을까 생각됩니다~~

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kijin Wincache 자체가 공식 사이트에서는 PHP 5.2~5.5 대응 버전밖에 없고, pecl에서도 PHP 7.0.0을 지원하는 버전은 DLL이 없는(즉 직접 컴파일해야 하는...) 상황입니다. 게다가 라이믹스 PHP 최소 버전이 PHP 5.5.9인데, Wincache를 사용하고 있다면 PHP 5.5 이하 버전일 가능성이 높습니다.

어차피 PHP 5.5 이상이면 opcache를 쓰는게 훨씬 이득이므로 일단 남겨는 두되 지원은 하지 않는 방향으로 가는게 어떨까 싶습니다.(테스트 해주실 분도 적고 말이죠...)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opcache는 PHP 코드만 캐싱해 주고 사용자 데이터 캐싱 기능을 제공하지 않기 때문에 apc도 개발을 완전히 중단하지 않고 사용자 데이터 캐싱 기능만 분리하여 apcu로 남아 있죠.

윈도우 서버에서도 딱히 대안이 없다면 wincache를 비슷한 방법으로 패치하여 계속 나올지도 모르겠네요. memcached와 redis도 윈도우 환경을 공식적으로 지원하지는 않으니까요.

사실 xcache와 wincache는 apc 드라이버에서 함수명만 바꾼 것이라서, 지원하는 데 딱히 큰 노력이 드는 것은 아니예요. 최대한 많은 기능을 Cache 클래스에 통합했기 때문에 각 드라이버에서는 데이터 저장을 위한 함수명만 지정해 주면 되는 상황이거든요. 따라서 일단 그대로 두고, 추후 문제가 발생할 경우 지원을 중단하거나 다른 드라이버 사용을 권하도록 해보겠습니다.

@kijin
Copy link
Member Author

kijin commented Apr 21, 2016

파일 캐시가 기본으로 켜지도록 해 보았는데, 성능은 꽤 좋아지겠지만 웹호스팅에서 너무 많은 캐시파일이 생성되지 않을까 걱정이 드네요.

이런 경우에 대비해서 캐시파일을 1개만 쓰는 SQLite 드라이버를 추가하긴 했는데, 기본값으로 하기엔 다소 실험적인 기능이라.....

@bjrambo
Copy link
Member

bjrambo commented Apr 21, 2016

일반적으로 웹호스팅에서는 캐싱파일이 웹디스크 용량으로 많이 차지되는경우 불합리적입니다.

cafe24호스팅 최고높은 가격인 호스팅계약하면 6기가인가 8기가정도 하드용량을 제공한다고 하지만, 그건 거품이거든요. 실제로 스트리밍호스팅용 하드디스크구간과 실제 웹을 돌리는 구간과 동일하게 용량이 더해져서 구성이 되거든요. (6기가라고 표기되었던건 실제로는 4기가 + 2기가(스트리밍쪽) 으로 구성)
그래서 실제로 사용하는 웹공간의 하드용량이 4기가 잡히는데 라이믹스를 쓰다보면,
phperror에 대해서 워링 메세지에러 부분과 debugPrint의 대한 모든 내용이 전부 error로그에 같이 쌓이는데, 이 용량만해도 몇주안가서 400메가씩 넘어가요.(하루 접속통계 모듈에서 500정도뜨는 사이트기준)

그런경우나 여러가지 생각했을때 현재의 라이믹스 시스템에서도 어느정도 에러용량 등등을 생각하고 따져봤을때 캐시속도를 위해서 파일케시를 만들었는데, 이게 너무많은 용량이 차지하게 된다면 오히려 더 웹호스팅이용자에겐 라이믹스가 독이될지도 몰라요..

사실 XE때는 그렇게 많이 error_log파일에 대해서 신경을 안써도될정도록 용량이 그렇게 빠르게 차지도 않았던것 같았는데 rhymix올라오고나서는 error_log까지 신경쓰는판인지라..ㅠㅠ

한번 전체적으로 검토해보시고, 캐싱에 용량이나 독이 되는부분이 있지 않는지 전반적인 검토도 필요할것으로 보여지기도 합니다.

@kijin
Copy link
Member Author

kijin commented Apr 22, 2016

기존 방식처럼 사이트 운영에 반드시 필요한 일부 데이터(site_and_module 그룹)만 캐싱하고, 나머지는 캐싱하지 않는 옵션도 필요하겠군요.

@kijin
Copy link
Member Author

kijin commented Apr 23, 2016

dummy 드라이버를 사용하여 일부 데이터(기존 방식에서도 무조건 파일로 캐싱하던 부분)만 캐싱하도록 기본값을 변경했습니다.

@bjrambo
Copy link
Member

bjrambo commented Apr 23, 2016

👍

@kijin
Copy link
Member Author

kijin commented Apr 24, 2016

  • 레이아웃 정보를 캐시에 추가하여 페이지당 쿼리 2개 감소
  • 위젯페이지에 사용하는 문서는 조회수, 추천수, 확장변수 등을 로딩하지 않고 캐시만 사용하도록 변경하여 쿼리 2개 감소
  • 캐시 사용시 메인화면에는 알림센터 쿼리밖에 남지 않음... 알림센터가 캐시파일을 생성해놓고도 재대로 사용하지 않던 문제점 고침. #456 까지 적용하면 알림센터 쿼리도 사라지므로 메인화면 쿼리 0개 달성 가능 ㄷㄷㄷ
  • 추천 내역 조회를 위해 페이지당 최소 4회 ~ 최대 수백 회씩 쿼리가 발생하던 것을 제거하고, 추천자의 세션에 캐싱된 데이터를 사용하도록 변경 (원래 이렇게 하도록 되어 있었으나 추천/비추천/추천삭제 기능추가. #140 에서 망가진 듯)

@kijin kijin merged commit 2d833e5 into rhymix:develop Apr 24, 2016
@kijin kijin deleted the pr/cache-refactor branch April 24, 2016 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement 기능 개선 요청 또는 기능 개선 PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants