此次性能测试开始时一头雾水,redis听说过、会拼写,仅限于此。
从安装到怎么写数据、怎么查数据、看配置,再到打压对比,学习的过程比较曲折,折磨了一个多星期,终于有概念啦,非常宝贵的一次经历,谢谢两位BOSS和两位开发的配合。
按时间顺序
第一轮测试需求-测redis写的并发能力
需求:我们用redis来存储 用户收藏的数据,看下redis写的并发能力
单CPU,320TPS
然后改成异步写 3267TPS 90%的响应时间:0.018
第二轮测试需求-测NodeJS+redis写能力
需求:我们用redis来存储 用户收藏的数据,看使用nodejs是不是更快
测试场景 CPU使用率 TPS/秒 90%响应时间
redis+tomcat7(Servlet异步)55% 8636 0.006
redis+nodeJS(异步、4核) 88% 4382 0.011
redis+tomcat6 60% 4508 0.012
第三轮测试需求-NodeJS和Servlet 异步-纯Hello world的基准
需求:想知道Nodejs和Servlet异步 纯Hello world的基准
测试场景 CPU使用率 TPS/秒 90%响应时间
纯NodeJS(4核) 60% 20654 0.003
纯Servlet异步 60% 21092 0.003
res.write("Hello World");
写法比 res.end('Hello World!\t'); 的效率高
第四轮测试需求-测redis纯10万数据不同存储方式使用内存对比
需求:想知道10万key数据(Map,List)两种存储方式 分别使用的内存。细则:每个Map需要有10个key/value的键值对,每个List需要存储10个value。
和研发沟通
1)研发问:你到底是想用Map 还是想用List?
我回:我两个都要用,需要你帮我写两个存数据的方法
研发回:好的
2)研发问:你是想你每次调用我帮你往一个map写10个key/value?
我回:不是,一个Map是怎么存的?
研发回:一个Map中只要key/value不同就可以存储进去。
我回:根据现实情况,我需要的是 一个用户,存10个数据信息,我传用户、key、value给你,你帮我存就行,我自己来做外循环,用户不变,key和value变,循环10次。
研发回:可行
3)研发问:我是用NodeJS写 还是用Servlet异步写?
我回:你觉得哪个简单好写 就用哪个,我想看的是10万key数据 不同方法需要用多少内存。
研发回:那我用NodeJS
我回:OK
开发写代码,我写测试脚本
测试结果
10万Map占内存:40.42M
10万List占内存:29.27M
10万Keys List存储 100个value: 180M
随着数据量的增大,每个list中 key和value 所占用的空间 会相应减少,直到一个平衡。
事后总结
测试需求
1)测试redis写的并发能力
2)比较 redis+tomcat 和 redis nodejs 的性能
3)纯tomcat和nodejs 性能比较
4)redis 中10万keys用List和map的存储消耗内存比较
需求的目的:想知道redis的并发写的基准数据、想知道nodejs的性能、想知道tomcat和nodejs的性能的基准数据,想知道redis不同存储方式消耗内存(为将来项目中我们应用场景和硬件配置提供参考数据)
测试准备
1)研发准备了redis、nodejs、tomcat6、tomcat7(Servlet异步)、nodejs的helloworld、servlet的helloworld等小程序
2)测试准备搭建测试环境、编写测试脚本
3)硬件环境 服务器端:1个4核的Cpu, 内存10G ; 客户端工具:Loadrunner , 2个6核的Cpu、 内存16G
测试过程
1)第一个场景 redis并发写能力,一开始每秒TPS只有200多个左右,研发调整了代码后提高到800多,因为CPU消耗少,研发又改了代码 给redis开启了多线程处理,但是性能非常不稳定,然后调整了redis写日志的方式,最终性能稳定在3267TPS
这里测试消耗了许多时间,1)不知道怎么用redis (比如怎么去查数据 是否真的写入) 2)redis的配置
2)第二个场景 nodejs 和tomcat7的Servlet异步的 测试经过和第一个场景差不多,每一步都有研发的配合,性能一点点地提高
3)第三个场景 nodejs 纯helloworld比较搞,因为页面非常简单,但是性能就是不高,每一行代码研发来回看了几次,最终找到 res.write("Hello World");写法比 res.end('Hello World!\t'); 的效率高
4)第四个场景 因之前测试时也观察过内存,但内存消耗的都特别大(跟打压时存储的数据量有关系),得出的内存消耗值不具有对比性和可参考性。
BOSS规划10万Keys 每个Map 十个键值对,每个List存储10个字符串。
研发第一次提交的脚本,打压时没有往redis写数据。
第二次提交的脚本才是正确的,但不知道是什么原因10万keys 需要好久才能打压完,消耗的内存也比较多。
于是请研发帮忙 写两种存储方式 插入10万数据。
在这个过程中遇到两个问题
1) nodejs for循环 for (var i=0,tmp=100000;i++) 因为等号两边都有空格和行尾有空格 导致启动失败。
2)发现存储的value值为同一个值
研发修改后,最后打压结果为:10万keys(List 和 map)所消耗的内存分别为 29M和40M。
期间存在疑惑:
1)每个Map 十个键值对,每个List存储10个字符串 两者的存储数量是同一级别?
2)和之前用loadrunner打压时 同样的数据 所消耗内存不同,不知道为什么?
又开始找原因,向BOSS请教。
问题1)存储数量级别是一致的
问题2)BOSS说redis本身也是一个server,也是会消耗内存的,你可以在打压完了之后,再去看内存消耗。
根据BOSS提供的方法,去验证,此时研发已经下班啦,电话研发问请清楚了代码存放位置,只好自己动手改,因是第一次看Nodejs来回尝试了好多回,才写数据的功能折腾出来,再次打压后,发现和程序直接往redis中写数据的消耗内存 差不多,没有重现之前内存消耗比较大的现象。
第二天问研发 你之前给我的List写数据的代码是怎么样的,你还记得不?研发已回想不起来啦。(这里得到一个经验教训:每个case对应的代码 都需要保存起来,不要覆盖更新)
测试总结
测试是一项需要有规划的工作,没有规划就会出现各种被动。一开始做redis测试时完全按照BOSS要求去做,做完一件,以为事情结束啦,接着又有新的测试需求下来,没有去列全case,导致出现准备不足、考虑不周、测试所需时间估算不足等问题。(测写的case,其实是可以和测内存合并在一个case中的)
测试需要普及下研发基础知识,比如:Map、List 常用类型的数据结构。
和研发合作的过程中,自己需要去备份代码脚本。
如果测试一个数据库
1)测试读写性能(监控CPU、内存、硬盘消耗)
2)测试内存/硬盘消耗
看每个参数配置,知道参数含义,根据业务场景,在性能测试时设置不同值,来测试哪种情况下性能最好。
如果测试新语言
1)简单hello world的基准性能
2)有逻辑操作
当性能差时,和研发一起,想换新的方法来测试。
可以提前在网络上搜索基本的性能指标 有个基础的概念。