使用管道(PipeLine)和批量(Batch)操作

前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到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}", 1); for (int i = 0; i < 10; 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中去,

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

 1         static void Main(string[] args)
2 {
3 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379");
4
5 var db = redis.GetDatabase();
6
7 var productID = string.Format("productID_{0}", 1);
8
9 var list = new List<int>();
10
11
12 for (int i = 0; i < 10; i++)
13 {
14 list.Add(i);
15 }
16
17 db.SetAdd(productID, list.Select(i => (RedisValue)i).ToArray());
18 }

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

三:再次提出问题

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

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

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

 1         static void Main(string[] args)
2 {
3 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379");
4
5 var db = redis.GetDatabase();
6
7
8 //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
9 var orderTotalPrice = 100;
10
11 var customerIDList = new List<int>();
12
13 for (int i = 0; i < 10; i++)
14 {
15 customerIDList.Add(i);
16 }
17
18 //foreach更新每个redis 的set集合
19 foreach (var item in customerIDList)
20 {
21 var customerID = string.Format("customerid_{0}", item);
22
23 db.SetAdd(customerID, orderTotalPrice);
24 }
25 }

四:解决方案【PipeLine】

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

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

 1         static void Main(string[] args)
2 {
3 ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.23.151:6379");
4
5 var db = redis.GetDatabase();
6
7
8 //批量过来的数据: customeridlist, ordertotalprice,具体业务逻辑省略
9 var orderTotalPrice = 100;
10
11 var customerIDList = new List<int>();
12
13 for (int i = 0; i < 10; i++)
14 {
15 customerIDList.Add(i);
16 }
17
18 var batch = db.CreateBatch();
19
20 foreach (var item in customerIDList)
21 {
22 var customerID = string.Format("customerid_{0}", item);
23
24 batch.SetAddAsync(customerID, orderTotalPrice);
25 }
26
27 batch.Execute();
28 }

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

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

192.168.23.151:6379> keys *
1) "customerid_0"
2) "customerid_9"
3) "customerid_1"
4) "customerid_3"
5) "customerid_8"
6) "customerid_2"
7) "customerid_7"
8) "customerid_5"
9) "customerid_6"
10) "customerid_4"

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

 
分类: redis

使用管道(PipeLine)和批量(Batch)操作的更多相关文章

  1. redis使用管道pipeline提升批量操作性能(php演示)

    Redis是一个TCP服务器,支持请求/响应协议. 在Redis中,请求通过以下步骤完成: 客户端向服务器发送查询,并从套接字读取,通常以阻塞的方式,用于服务器响应. 服务器处理命令并将响应发送回客户 ...

  2. Redis 管道pipeline

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

  3. PreparedStatement批量(batch)插入数据

    JDBC操作数据库的时候,需要一次性插入大量的数据的时候,如果每次只执行一条SQL语句,效率可能会比较低.这时可以使用batch操作,每次批量执行SQL语句,调高效率. public Boolean ...

  4. redis 批量删除操作

    redis 批量删除操作 需要在redis里面清空一批数据,redis没有支持通配符删除, 只有del key1 key2 ... 但是可以通配符获取 KEYS PATTERN 然后利用linux管道 ...

  5. [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]

    场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...

  6. 【转】批量复制操作(SqlBulkCopy)的出错处理:事务提交、回滚

    原文地址:http://blog.csdn.net/westsource/article/details/6658109 默认情况下,批量复制操作作为独立的操作执行. 批量复制操作以非事务性方式发生, ...

  7. 使用Ajax实现的批量删除操作(C#)

    今天做了一个简单的批量删除操作,虽然简单,但是很多问题出现,终究还是技术不够熟练. 现在在这里跟大家分享一下.仅供学习... 1.在前台获取用户点击的信息id,把这里id封装到一个数组里面:(rows ...

  8. mySql事务_ _Java中怎样实现批量删除操作(Java对数据库进行事务处理)?

      本文是记录Java中实现批量删除操作(Java对数据库进行事务处理),在开始之前先来看下面这样的一个页面图: 上面这张图片显示的是从数据库中查询出的出租信息,信息中进行了分页处理,然后每行的前面提 ...

  9. C#利用SqlDataAdapte对DataTable进行批量数据操作

    C#利用SqlDataAdapte对DataTable进行批量数据操作,可以让我们大大简化操作数据的代码量,我们几乎不需要循环和不关心用户到底是新增还是修改,更不用编写新增和修改以及删除的SQL语句, ...

  10. MyBatis魔法堂:各数据库的批量Update操作

    一.前言   MyBatis的update元素的用法与insert元素基本相同,因此本篇不打算重复了.本篇仅记录批量update操作的sql语句,懂得SQL语句,那么MyBatis部分的操作就简单了. ...

随机推荐

  1. response设置输出文件编码

    在java后台的Action代码或者Servlet代码中用response的方法来设置输出内容的编码方式,有以下三个方法: 1.response.setCharacterEncoding(" ...

  2. 2.3 CMMI2级——项目跟踪和控制(Project Monitoring and Control)

    计划不是用来看的,是用来执行的.PP讲述了如何做计划,PMC讲述的就是如何跟踪计划的执行并在实际情况偏离计划时采取纠正行动. 我们先看看SG1,SG1讲述的是如何根据计划来跟踪计划的执行问题. SG1 ...

  3. nodejs学习笔记(2)--Express下安装模版引擎ejs

    成功安装完express后,输入express -help,根据提示安装ejs(如下图): 根据提示-e实现安装ejs,注意此处有坑:之前安装的时候根据教程(node.js开发指南第五章5.2.2节) ...

  4. 安装了SQL2005再安装SQL 2008R2,提示此计算机上安装了 Microsoft Visual Studio 2008 的早期版本和检查是否安装了 SQL Server 2005 Express 工具的解决方案

    工作电脑上安装了SQL 2005, 但是客户电脑上安装的是SQL 2008R2,有时候连接他们的库调试没法连接,很不方便.然后又安装了个SQL2008 R2,期间遇到这两个问题,网上搜索了一下收到了解 ...

  5. php反射机制

    PHP5添加了一项新的功能:Reflection.这个功能使得phper可以reverse-engineer class, interface,function,method and extensio ...

  6. 二、Android学习第二天——初识Activity(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 一. Android学习第二天——初识Activity 昨天程序搭建成功以 ...

  7. JavaScript添加、查找、删除元素的一个实例

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Centos 内存占满 释放内存

    free -m 查看内存使用情况 top,然后按下shift+m,按内存占用百分比排序 centos 为了提高效率,把部分使用过的文件缓存到了内存里.如果不需要这样的文件性能,那就可以释放. 如下两个 ...

  9. js生成[n,m]的随机数

    一.预备知识 Math.ceil();  //向上取整. Math.floor();  //向下取整. Math.round();  //四舍五入. Math.random();  //0.0 ~ 1 ...

  10. PCA原理与实践

    在对数据进行预处理时,我们经常会遇到数据的维数非常之大,如果不进行相应的特征处理,那么算法的资源开销会很大,这在很多场景下是我们不能接受的.而对于数据的若干维度之间往往会存在较大的相关性,如果能将数据 ...