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

memcache 사용시 opcache가 무력화되는 문제 #2299

Closed
kijin opened this issue Sep 12, 2018 · 6 comments
Closed

memcache 사용시 opcache가 무력화되는 문제 #2299

kijin opened this issue Sep 12, 2018 · 6 comments

Comments

@kijin
Copy link
Contributor

kijin commented Sep 12, 2018

#2189 문제 해결을 위해 적용된 소스 중 config/config.inc.php

/**
 * Invalidates a cached script of OPcache when version is changed.
 * @see https://github.com/xpressengine/xe-core/issues/2189
 **/
if(
	!is_dir(_XE_PATH_ . 'files/cache/store/' . __XE_VERSION__)
	&& function_exists('opcache_get_status')
	&& function_exists('opcache_invalidate')
)
{
	foreach($GLOBALS['__xe_autoload_file_map'] as $script) {
		opcache_invalidate(_XE_PATH_ . $script, true);
	}
	opcache_invalidate(_XE_PATH_ . 'config/func.inc.php', true);
}

그런데 apc, memcache(d) 등을 사용하는 경우 files/cache/store/버전 폴더가 존재하지 않습니다. 따라서 위의 조건이 항상 참이 되어, PHP 요청할 때마다 매번 opcache_invalidate()가 발생합니다.

오브젝트 캐시를 쓰는 사이트라면 상당히 규모가 크거나 운영자가 성능을 중요하게 여기는 곳일 텐데, 저렇게 자꾸 캐시를 지워버리는 바람에 opcache의 성능 개선 효과를 별로 보지 못하고 있습니다.

몇몇 파일을 opcache_invalidate()하는 것만으로도 뜻밖에 큰 문제가 되는 이유는 opcache가 무척 단순한 구조로 되어 있기 때문입니다. opcache_invalidate()를 자주 사용하면 wasted memory가 늘어나는데, 이것을 가비지컬렉션하여 다른 데이터를 캐싱하는 데 재사용하는 것이 아니라, 그냥 일정 비율 이상이 되면 opcache를 통째로 초기화해 버립니다. 위의 코드에 해당되는 파일들만 몇 번씩 opcache_invalidate()해도 초기화가 일어날 만큼 기본값(128M 중 5%)이 낮기 때문에, 실제로 모 사이트에서 약 10초 주기로 계속 초기화되는 것을 목격했습니다. 캐시 사용 효과가 사실상 제로인 셈이지요.

설상가상으로 PHP 자체의 버그 (1, 2) 때문에 opcache를 너무 자주 초기화하면 corruption이 발생하여 엉뚱한 곳에서 에러가 나기까지 합니다. 총체적인 난국인데 그렇다고 성능에 어마어마한 영향을 주는 opcache를 쓰지 않을 수도 없고... 최대한 아껴쓰는 방법밖에 없겠습니다.

  1. file 이외의 오브젝트 캐시를 사용하는 경우에도 조건을 제대로 파악하도록 해주세요.
  2. 특별한 문제가 없는 사이트라면 아예 저 코드를 사용하지 않도록 했으면 좋겠습니다. opcache 관련 문제가 잦은 특정한 환경에서만 상수를 넣어서 컨트롤하면 어떨까요?
@ghost ghost self-assigned this Sep 12, 2018
@ghost ghost added the type/bug label Sep 12, 2018
@ghost ghost added this to the 1.9-next milestone Sep 12, 2018
@ghost ghost added this to 해결 예정 in 이슈 진행 상황 Sep 12, 2018
@ghost ghost moved this from 해결 예정 to 해결 중 in 이슈 진행 상황 Sep 19, 2018
@gaejabong
Copy link
Contributor

+1

@ghost ghost modified the milestones: 1.11.0, 1.11-next Sep 27, 2018
@kijin
Copy link
Contributor Author

kijin commented Oct 1, 2018

index.php에도 무조건 opcache_invalidate를 호출하는 코드가 있습니다. 위에서 언급한 코드를 주석처리했는데도 이것 때문에 wasted memory가 점점 늘어나고, 시간이 지나면 자동으로 리셋되면서 캐시 손상이 발생하는군요.

@gaejabong
Copy link
Contributor

저도 @kijin 님께서 말씀하신 부분을 주석처리하고 나서 opcache 효율이 많이 좋아졌습니다. 주석처리 하기 전에는 제가 관리하고 있는 서버에서도 10초에 1번 꼴로 초기화 되었습니다. 지금은 수십분에서 수시간 정도는 유지되는데 wasted memory는 꾸준히 늘어나서 결국 리셋되기는 하더라고요.

@ghost
Copy link

ghost commented Oct 10, 2018

관련 코드를 제거하는 것 외에는 방법이 없어 보이네요.
/index.php 파일에서 관련 코드를 제거하고 추후 다른 방법을 고민해보겠습니다.

@kijin
Copy link
Contributor Author

kijin commented Oct 10, 2018

@bnu 네, opcache_invalidate가 제때 이루어지지 않는 극소수의 (서버 세팅이 명백하게 잘못된) 사이트를 배려하기 위해 대다수의 정상적인 사이트의 성능과 안정정을 저하시킬 필요는 없다고 생각합니다. 코어 버전이 바뀔 때 변경되는 파일이 반드시 autoload map에 포함되어 있다는 보장도 없으니, 어차피 제대로 된 해결책도 아니고요.

@ghost
Copy link

ghost commented Oct 10, 2018

@kijin 네. 모든 파일에 대해 수행하고 있지 않기 때문에 완벽한 해결책은 아니나, 주로 mysql.class.php 파일이 대상이 되었던 문제 보고가 많아서 autoload map에 표기된 파일을 대상으로 하는 것에 대해서는 일부 효과가 있었다고는 보입니다.

자동화는 말씀하신 것처럼 또 다른 문제를 발생시키므로 별도의 방법을 고민해보겠습니다.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

No branches or pull requests

2 participants