phpの圧縮を考える
背景
- 自社サービスでcacheとしてredisを使ってるもののredisのサイズがバカにならなくなってきた
- redisのDBサイズが大きくなってくるとBGSAVE時にi/oが出てサイトが遅延するケース(?)
- redisの使い方が雑なのでお手当してサイズ圧縮したい
現状のredisへの保存
protected function _getUserList() {
$userList = array();
$key = __METHOD__;
$cacheRes = Cache::read($key);
if ( $cacheRes ) {
$userList = $cacheRes;
return $userList;
}
$userList = UserDb::selectUserList()
$ret = Cache::save($key, $userList , 60);
return $userList;
}
# 保存内容は利用者に任せているのでバカでかいarrayとかが保存されがち
圧縮すればいいんじゃない?
protected function _getUserList() {
$userList = array();
$key = __METHOD__;
$cacheRes = Cache::read($key);
if ( $cacheRes ) {
$userList = json_decode(gzuncompress($cacheRes), true);
return $userList;
}
$userList = UserDb::selectUserList()
$comp = gzcompress(json_encode($userList))
$ret = Cache::save($key, $comp, 60);
return $userList;
}
サイズの変化
圧縮有無 | サイズ |
---|---|
なし | 573byte |
あり | 187byte |
70%ほど削減できる模様
速度影響はどうか?
100万回読んでみる
$before = microtime(true);
for ( $i = 1; $i<=100000; $i++ ) {
AppGameMaster::getInstance()->isGameMaster($this->userId);
}
$after = microtime(true);
$diff = $after - $before;
AppDebug::dBug($diff);
圧縮有無 | 処理秒数 |
---|---|
なし | 2.870146sec |
あり | 2.798397sec |
ほとんど誤差らしい
異なる圧縮方式
圧縮形式 | 内容 | 計測 | サイズ |
---|---|---|---|
gzdeflate/gzinflate | デルタ圧縮 | 0.2774169sec | 181byte |
gzcompress/gzuncompress | ZLIBフォーマット圧縮 | 0.2798397sec | 187byte |
gzencode/gzdecode | GIZPコマンドと同 | phpVer都合で利用できず | --- |
参考
雑感
- cacheなのでgzdeflate()あたりがパフォーマンス的には高い
- ただメソッド名が馴染みがないので大規模開発の場合、gzcompressやgzencodeの方が可読性は高いか?