为最差情况做优化

December 29, 2012 · One minute read

在做KC第一个版本的时候,为了让原先几百个系统实例运行在一台服务器上,我只把目录服务留在了内存,其它衍生数据都采用运行时计算的方法生成。同时为了达到给定的延迟指标,我大量使用了缓存。结果是不言而喻的,性能测试的结果非常好,但是实际运行起来却总是不太稳定。

缓存并不总是好的。首先缓存占用了内存,即使看起来常驻内存的量不是很大,可是一旦发生内存不足,虚拟机开始回收缓存所占内存的时候,就可能会发生内存颠簸和缓存命中率急剧下降的情况。其次缓存干扰了文件系统缓存。现代操作系统的缓存机制已经相当强大,像KC这种依赖大量IO的系统,与其大量缓存易于生成的数据,不如把宝贵的内存还给文件系统作缓存来的更有价值。而且缓存也影响了算法,有些时候对数据生命周期很清晰的时候,用栈内存比堆内存更加高效。

问题的实质是我把性能压在了概率上。缓存是非常依赖工作负载性质的,换句话说就是缓存命中率。命中率越高,性能就越好。可是真实世界的工作负载是很难预估的,缓存命中率就会波动,或者工作负载上去了,但是内存不可能弹性上涨,限制了系统的可扩展性。所以系统设计的时候,应该为最差情况做优化,避免过早的使用缓存,而改用可清晰估计的算法来做实现。