File system performance patch
|Reported by:||vminakov||Owned by:|
just wanted to share some thoughts on file system optimization. The problem arose, when we deployed roundcube on our production platform. Load average on 2 servers (24 cores, 16GB ram) went to 70. And that's with nginx, php-fpm and apc turned on.
The bottleneck was file system. Roundcube was running on NFS (I know, that's absolutely ridiculous) and was doing almost a million 'stat' calls per minute. The reason for that is include path.
$include_path = INSTALL_PATH . PATH_SEPARATOR; $include_path.= INSTALL_PATH . 'program' . PATH_SEPARATOR; $include_path.= INSTALL_PATH . 'program/lib' . PATH_SEPARATOR; $include_path.= INSTALL_PATH . 'program/include' . PATH_SEPARATOR;
So, whenever you need a class like rcube_session, PHP makes 4 stat calls (on '.', on 'program/', on 'program/lib' and on 'program/include'), which are very expensive not only in NFS, but in other file systems as well. In order to get rid of useless stat calls, I reduced the include path, tried to move everything that's possible to autoloader, and where it wasn't possible, used absolute paths. Load dropped to 1.5.
Autoloader allows you to optimize class loading in one place, without the need to refactor everything. Unfortunately, Roundcube doesn't rely heavily on autoloader. Probably, because it lacks clear folder structure. Library classes mixed with function files and core classes, no naming conventions and no hierarchical folder structure. Look at Zend Framework. Although it's being criticised for lack of performance, it has a very clear structure and requires just one include path: autoloader knows exactly where class files are.
Absolute paths also have a benefit, which is often left unnoticed. They allow you to turn off 'stat' in APC. That is, if the file has been cached by APC, PHP will never do 'stat' calls to check, if the file has been modified. And it's only possible with absolute paths http://www.php.net/manual/en/apc.configuration.php#ini.apc.stat. Turning off 'stat' in APC led to another drop in load averages: down to 0.7.
I've attached a patch, which is dirty, but gives an idea what I've done. I really think that more attention should be given to refactoring. And not just for a sake of it.
Change History (6)
Changed 2 years ago by vminakov
comment:1 Changed 2 years ago by vminakov
- Component changed from Addressbook to Core functionality
- Type changed from Bugs to Feature Patches
- Version changed from 0.5.1 to 0.4.2