服务器需要加一个缓存,之前已经程序里已经有一个hashtable做缓存,但整体感觉封闭无共享,无硬盘备份,就这两个问题就令人困扰。不共享意味着多个服务器实例都各自维护一个缓存,浪费资源,而无硬盘备份,意味着服务器重启后,所有缓存数据都需要重新构造,虽说缓存数据都是可是随时生成或删除的,但能减少的时间就得减少。
所以缓存很有必要独立出来,刚好最近有看过关于Redis的文章,感觉他能为我省点时间,于是看了下用法后就去测了下性能。
测试的客户端驱动用的是c写的hiredis,本来可以直接用c++的,不过github上有接近两年无更新,所以果断地用hiredis,起码4个月前更新过。开源的就要注意这些。
性能是一个重要的考虑因素,因此我写了一个单线程测试,为代码如下
redisContext *c = reidsConnectWithTimeout(ip,port,timeout);
time_t t0 = time(NULL);
while(iLoopTime > 0){
reply = redisCommand(c,"getset %s %s",keyword,value);
iLoopTime--;
}
cout<<"usage:"<<difftime(time(NULL),t0)<<endl;
因业务需要,value的长度为65535,当iLoopTime = 1000000的时候,花费时间为79s,在虚拟机环境下能每秒处理大于1万次,远高于现有生产服务器的瓶颈。
当跑多线程的时候(每条线程均访问10w次),得如下数据
线程数N | 单线程 | 五线程 | 10线程 | 20线程 | 50线程 |
时间T | 8s | 16s | 38s | 74s | 161s |
处理能力(10w*N / T) | 1.25w/s | 3.125w/s | 2.63w/s | 2.70w/s | 3.10w/s |
以上为单次测试数据,并未进行多次测试取样。
另外测试每次均创建connection,得出结果很大,同样100万时等了几分钟,所以该样本为6万时,每次创建connection需要42s,重复使用6s,相差7倍,究其原因为使用的是tcp,所以下一步要写个connection pool,重复利用connection。
关于配置方面,有几点需要注意,个人觉得maxmemory-policy allkeys-lru会比较通用,起码在现有业务上较好,因为业务上不会对每个key设expire time,除非有用户修改,所以该情况下,内存过大时,应采取allkeys-lru(last recently used)