前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value

就是具体的customerid集合,后续的话,我就可以通过productid来查看该customerid是否买了此商品,如果购买了,就可以有相关的关联推荐,当然这只是系统中

的一个小业务条件,这时候我就可以用到SADD操作方法,代码如下:

        static void Main(string[] args)
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379"); var db = redis.GetDatabase(); var productID = string.Format("productID_{0}", ); for (int i = ; i < ; i++)
{
var customerID = i; db.SetAdd(productID, customerID);
}
}

一:问题

但是上面的这段代码很明显存在一个大问题,Redis本身就是基于tcp的一个Request/Response protocol模式,不信的话,可以用wireshark监视一下:

从图中可以看到,有很多次的192.168.23.1 => 192.168.23.151 之间的数据往返,从传输内容中大概也可以看到有一个叫做productid_xxx的前缀,

那如果有百万次局域网这样的round trip,那这个延迟性可想而知,肯定达不到我们预想的高性能。

二:解决方案【Batch】

刚好基于我们现有的业务,我可以定时的将批量的productid和customerid进行分组整合,然后用batch的形式插入到某一个具体的product的set中去,

接下来我可以把上面的代码改成类似下面这样:

         static void Main(string[] args)
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379"); var db = redis.GetDatabase(); var productID = string.Format("productID_{0}", ); var list = new List<int>(); for (int i = ; i < ; i++)
{
list.Add(i);
} db.SetAdd(productID, list.Select(i => (RedisValue)i).ToArray());
}

从截图中传输的request,response可以看到,这次我们一次性提交过去,极大的较少了在网络传输方面带来的尴尬性。。

三:再次提出问题

  product维度的画像我们可以解决了,但是我们还有一个customerid的维度,也就是说我需要维护一个customerid为key的set集合,其中value的值为

该customerid的各种平均值,比如说“总交易次数”,“总交易金额”。。。等等这样的聚合信息,然后推送过来的是批量的customerid,也就是说你需要定时

维护一小嘬set集合,在这种情况下某一个set的批量操作就搞不定了。。。原始代码如下:

         static void Main(string[] args)
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379"); var db = redis.GetDatabase(); //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
var orderTotalPrice = ; var customerIDList = new List<int>(); for (int i = ; i < ; i++)
{
customerIDList.Add(i);
} //foreach更新每个redis 的set集合
foreach (var item in customerIDList)
{
var customerID = string.Format("customerid_{0}", item); db.SetAdd(customerID, orderTotalPrice);
}
}

四:解决方案【PipeLine】

上面这种代码在生产上当然是行不通的,不过针对这种问题,redis早已经提出了相关的解决方案,那就是pipeline机制,原理还是一样,将命令集整合起来通过

一条request请求一起送过去,由redis内部fake出一个client做批量执行操作,代码如下:

         static void Main(string[] args)
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379"); var db = redis.GetDatabase(); //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
var orderTotalPrice = ; var customerIDList = new List<int>(); for (int i = ; i < ; i++)
{
customerIDList.Add(i);
} var batch = db.CreateBatch(); foreach (var item in customerIDList)
{
var customerID = string.Format("customerid_{0}", item); batch.SetAddAsync(customerID, orderTotalPrice);
} batch.Execute();
}

然后,我们再看下面的wireshark截图,可以看到有很多的SADD这样的小命令,这就说明有很多命令是一起过去的,大大的提升了性能。

最后可以再看一下redis,数据也是有的,是不是很爽~~~

192.168.23.151:> keys *
) "customerid_0"
) "customerid_9"
) "customerid_1"
) "customerid_3"
) "customerid_8"
) "customerid_2"
) "customerid_7"
) "customerid_5"
) "customerid_6"
) "customerid_4"

好了,先就说到这里了,希望本篇对你有帮助。

redis大幅性能提升之使用管道(PipeLine)和批量(Batch)操作的更多相关文章

  1. Redis大幅性能提升之Batch批量读写

    Redis大幅性能提升之Batch批量读写 提示:本文针对的是StackExchange.Redis 一.问题呈现 前段时间在开发的时候,遇到了redis批量读的问题,由于在StackExchange ...

  2. Spring Boot 2.2 正式发布,大幅性能提升 + Java 13 支持

    之前 Spring Boot 2.2没能按时发布,是由于 Spring Framework 5.2 的发布受阻而推迟.这次随着 Spring Framework 5.2.0 成功发布之后,Spring ...

  3. Redis 管道pipeline

    Redis是一个cs模式的tcp server,使用和http类似的请求响应协议. 一个client可以通过一个socket连接发起多个请求命令. 每个请求命令发出后client通常会阻塞并等待red ...

  4. memcache 与 redis 为web app 带来的性能提升

    memcache 与 redis 为web app 带来的性能提升 参考: 1. http://www.cnblogs.com/ToDoToTry/p/3513688.html

  5. 【Redis】1、Jedis对管道、事务以及Watch的操作来应对高并发

    对于一个互联网平台来说,高并发是经常会遇到的场景.最有代表性的比如秒杀和抢购.高并发会出现三个特点: 1.高并发读取 2.高并发写入(一致性) 3.出现超卖问题 前端如何应对? 1.缓存静态数据,例如 ...

  6. VNF网络性能提升解决方案及实践

    VNF网络性能提升解决方案及实践 2016年7月 作者:    王智民 贡献者:     创建时间:    2016-7-20 稳定程度:    初稿 修改历史 版本 日期 修订人 说明 1.0 20 ...

  7. 【转】Redis学习---阿里云Redis多线程性能增强版详解

    [原文]https://www.toutiao.com/i6594620107123589635/ 摘要 Redis做为高性能的K-V数据库,由于其高性能,丰富的数据结构支持,易用等特性,而得到广泛的 ...

  8. paip.cache 缓存架构以及性能提升总结

    paip.cache 缓存架构以及性能提升总结 1         缓存架构以及性能(贯穿读出式(LookThrough) 旁路读出式(LookAside) 写穿式(WriteThrough) 回写式 ...

  9. Web 应用性能提升 10 倍的 10 个建议

    转载自http://blog.jobbole.com/94962/ 提升 Web 应用的性能变得越来越重要.线上经济活动的份额持续增长,当前发达世界中 5 % 的经济发生在互联网上(查看下面资源的统计 ...

随机推荐

  1. 小白解决CENTOS7错误:Cannot find a valid baseurl for repo: base/7/x86_6

    刚入手的MacBook想着学点东西,本汪还是决定玩玩CentOS服务器,安装好了VirtualBox + CentOS. 打开一看,懵逼了!命令行! 行吧,先装个图形界面: $sudo yum gro ...

  2. 【翻译】MongoDB指南/CRUD操作(一)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...

  3. 在 Laravel 中使用图片处理库 Integration/Image

    系统需求 PHP >= 5.3 Fileinfo Extension GD Library (>=2.0) … or … Imagick PHP extension (>=6.5.7 ...

  4. dubbox微服务实例及引发的“血案”

    Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...

  5. jQuery.template.js 简单使用

    之前看了一篇文章<我们为什么要尝试前后端分离>,深有同感,并有了下面的评论: 我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views, ...

  6. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  7. java设计模式之--单例模式

    前言:最近看完<java多线程编程核心技术>一书后,对第六章的单例模式和多线程这章颇有兴趣,我知道我看完书还是记不住多少的,写篇博客记录自己所学的只是还是很有必要的,学习贵在坚持. 单例模 ...

  8. Node.js入门(一)

    一.Node.js本质上是js的运行环境. 二.可以解析js代码(没有浏览器安全级的限制): 提供系统级的API:1.文件的读写 2.进程的管理 3.网络通信 三.可以关注的四个网站: 1.https ...

  9. Apache Cordova开发Android应用程序——番外篇

    很多天之前就安装了visual studio community 2015,今天闲着么事想试一下Apache Cordova,用它来开发跨平台App.在这之前需要配置N多东西,这里找到了一篇MS官方文 ...

  10. 【每日一linux命令2】命令执行顺序:

    二.命令顺序:     若在 shell 内置的命令/bin 以及/usr/bin 之下都出现了命令 pwd,那当我们执行该命令时,会执行哪 一个?答案是第一优先执行 shell 内置的命令,再执行路 ...