注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

Redis测试分析(pipeline模式推荐)  

2012-12-18 07:59:45|  分类: 测试 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
测试环境 
Redis测试版本:2.2.12 
使用Java Jedis客户端进行测试 
测试数据量:50万, 超过2亿 

 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
  Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。

速度 
1) mset函数插入效率最高,插入Redis的速度达到20万条数据/秒。但是该函数所耗内存较高,对于我们实际应用一表每天2.4亿的数据量来说,需要消耗近32G内存; 
2) mset函数中当m值达到200以上时,插入速度接近饱和,因此实际应用中,应设定该值 >= 200,以达到最高的插入效率; 
3) set函数除非特定应用场景需求,否则应尽量不要使用,其插入效率为mset函数的1/20; 
4) 尽管不同的函数都有string与byte[]两种不同的形式,但是对于Redis来说byte[]的形式也是将每个byte看成是一个字符来进行处理的。在实际应用中,对于较长的整型数据(例如:9824224123),可以将其转换为byte[]的形式,4个byte[]可以存储一个int数据,这样会比采用string的形式存储节省一部分的内存开销; 
5) hset函数插入效率与set函数相当; 
6) hmset由于在实际应用中,每条数据对应的key不相同,需要维护一个本机的缓存容器Map<key,Map<field, value>>,因此插入速度要比mset函数慢一些; 

内存 
1) hset和 hmset函数大约可以比set和mset函数节省三分之一的内存; 
2) hset和hmset函数对于每个key所存储的<field, value>数目非常敏感。一旦超过限制,插入效率下降十分明显,同样,内存开销也会显著增加。在实际应用中,应尽量保证每个key下面的<field, value>的数目不超过限制(默认值为64)。 

Pipeline 
redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。 
Redis本身是一个cs模式的tcp server, client可以通过一个socket连续发起多个请求命令。 每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。 
Java代码 
  1. Client: hset a1 field value  
  2. Server: 1  
  3. Client: hset a2 field value  
  4. Server: 1  
  5. Client: hset a3 field value  
  6. Server: 1  
  7. Client: hset a4 field value  
  8. Server: 1  

这种发送模式中由于网络开销延迟,即算redis server端有很强的处理能力,也由于收到的client消息少,而造成吞吐量小。我们可以修改一种处理模式, 
Java代码 
  1. Client: hset a1 field value  
  2. Client: hset a2 field value  
  3. Client: hset a3 field value  
  4. Client: hset a4 field value  
  5. Server: 1  
  6. Server: 1  
  7. Server: 1  
  8. Server: 1  

通过pipeline方式将client端命令一起发出,redis server会处理完多条命令后,将结果一起打包返回client,从而节省大量的网络延迟开销。 
下面以Java的客户端jedis来测试pipeline的效果。 
Java代码 
  1. Pipeline pipeline = jedis.pipelined();  
  2. long start = System.currentTimeMillis();  
  3. for (int i = 0; i < 10000; i++) {  
  4.     pipeline.hset("server""" + i, "" + i);  
  5. }  
  6. List<Object> results = pipeline.execute();  
  7. long end = System.currentTimeMillis();  
  8. System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");  

测试的结果采用pipeline方式,效率几乎与mset一样,每秒插入约15万数据,但内存占用仅为mset的1/3. 

性能

  下面是官方的bench-mark数据:
  测试完成了50个并发执行100000个请求。
  设置和获取的值是一个256字节字符串。
  Linux box是运行Linux 2.6,这是X3320 Xeon 2.5 ghz。
  文本执行使用loopback接口(127.0.0.1)。
  结果:写的速度是110000次/s,读的速度是81000次/s 。
  评论这张
 
阅读(2826)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016