1. RTT

Redis 是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下 Redis 客户端执行一条命令分为如下四个过程:

  • 发送命令
  • 命令排队
  • 命令执行
  • 返回结果

客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。服务端处理命令,并将结果返回给客户端。客户端和服务端通过网络进行连接。这个连接可以很快,也可能很慢。无论网络如何延迟,数据包总是能从客户端到达服务端,服务端返回数据给客户端。

这个时间被称为 RTT (Round Trip Time),例如上面过程的发送命令和返回结果两个过程。当客户端需要连续执行多次请求时很容易看到这是如何影响性能的(例如,添加多个元素到同一个列表中)。例如,如果 RTT 时间是250毫秒(网络连接很慢的情况下),即使服务端每秒能处理100k的请求量,那我们每秒最多也只能处理4个请求。如果使用的是本地环回接口,RTT 就短得多,但如如果需要连续执行多次写入,这也是一笔很大的开销。

下面我们看一下执行 N 次命令的模型:

2. Pipeline

我们可以使用 Pipeline 改善这种情况。Pipeline 并不是一种新的技术或机制,很多技术上都使用过。RTT 在不同网络环境下会不同,例如同机房和同机房会比较快,跨机房跨地区会比较慢。Redis 很早就支持 Pipeline 技术,因此无论你运行的是什么版本,你都可以使用 Pipeline 操作 Redis。

Pipeline 能将一组 Redis 命令进行组装,通过一次 RTT 传输给 Redis,再将这组 Redis 命令按照顺序执行并将结果返回给客户端。上图没有使用 Pipeline 执行了 N 条命令,整个过程需要 N 次 RTT。下图为使用 Pipeline 执行 N 条命令,整个过程仅需要 1 次 RTT:

Redis 提供了批量操作命令(例如 mget,mset等),有效的节约了RTT。但大部分命令是不支持批量操作的。

3. Java Pipeline

Jedis 也提供了对 Pipeline 特性的支持。我们可以借助 Pipeline 来模拟批量删除,虽然不会像 mget 和 mset 那样是一个原子命令,但是在绝大数情况下可以使用:

public void mdel(List<String> keys){
Jedis jedis = new Jedis("127.0.0.1");
// 创建Pipeline对象
Pipeline pipeline = jedis.pipelined();
for (String key : keys){
// 组装命令
pipeline.del(key);
}
// 执行命令
pipeline.sync();
}

4. 性能测试

下表给出了不同网络环境下非 Pipeline 和 Pipeline 执行 10000 次 set 操作的效果:

网络 延迟 非Pipeline Pipeline
本机 0.17ms 573ms 134ms
内网服务器 0.41ms 1610ms 240ms
异地机房 7ms 78499ms 1104ms
因测试环境不同可能会得到不同的测试数据,本测试 Pipeline 每次携带 100 条命令。

我们可以从上表中得出如下结论:

  • Pipeline 执行速度一般比逐条执行要快。
  • 客户端和服务端的网络延时越大,Pipeline 的效果越明显。

5. 批量命令与Pipeline对比

下面我们看一下批量命令与 Pipeline 的区别:

  • 原生批量命令是原子的,Pipeline 是非原子的。
  • 原生批量命令是一个命令对应多个 key,Pipeline 支持多个命令。
  • 原生批量命令是 Redis 服务端支持实现的,而 Pipeline 需要服务端和客户端的共同实现。

6. 注意点

使用 Pipeline 发送命令时,每次 Pipeline 组装的命令个数不能没有节制,否则一次组装的命令数据量过大,一方面会增加客户端的等待时间,另一方面会造成一定的网络阻塞,可以将一次包含大量命令的 Pipeline 拆分成多个较小的 Pipeline 来完成。

好了,以上就是这篇文章的全部内

原文链接:https://www.jb51.net/article/164284.htm

Redis利用Pipeline加速查询速度的方法的更多相关文章

  1. sql处理百万级以上的数据提高查询速度的方法

    原文:http://blog.csdn.net/zhengyiluan/article/details/51671599 处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中 ...

  2. 《转》sql处理百万级以上的数据提高查询速度的方法

    处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考 ...

  3. SQL Server 百万级数据提高查询速度的方法

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  4. SQL 百万级数据提高查询速度的方法

    ----------------[转] 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描.2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 ...

  5. SQL Server 百万级数据提高查询速度的方法(转)

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描.2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及 ...

  6. 利用Redis cache优化app查询速度实践

    注意:本篇文章译自speeding up existing app with a redis cache,如需要转载请注明出处. 发现问题 在应用解决方法之前,我们需要对我们面对的问题有一个清晰的认识 ...

  7. 关于mysql处理百万级以上的数据时如何提高其查询速度的方法

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  8. MySQL加速查询速度的独门武器:查询缓存

    [导读] 与朋友或同事谈到MySQL查询缓存功能的时候,个人喜欢把查询缓存功能Query Cache比作荔枝, 是非常营养的东西,但是一次性吃太多了,就容易上火而流鼻血,虽然不是特别恰当的比喻,但是有 ...

  9. 提高MySQL查询速度

    参考百度知道 关于mysql处理百万级以上的数据时如何提高其查询速度的方法 最近一段时间由于工作需要,开始关注针对Mysql数据库的select查询语句的相关优化方法. 由于在参与的实际项目中发现当m ...

随机推荐

  1. 标准库函数gets()和puts()

    问题: 用标准库函数gets()和puts()实现字符串的输入输出.函数gets()用于从键盘读入一个字符串(包括空格符).它仅以回车符作为分隔符.函数gets()中的参数应是一个已存储字符串的字符数 ...

  2. Nginx-rtmp点播之业务流程分析

    1. 点播的播放流程分析 1.1 ngx_rtmp_cycle 在握手结束后,即进入该函数中做进一步处理. void ngx_rtmp_cycle(ngx_rtmp_session_t *s) { n ...

  3. cygwin下make指令不存在 & cmd也能用make的配置方法

    最近做毕设需要使用Mask R-CNN,就配置了相关环境,在安装pycocotools时要make,于是决定用cygwin来做.但在路径下make时出现了问题: bash错误:make指令不存在.一番 ...

  4. Runtime 源码阅读

    Runtime 属性说明 /** * 每一个 Java 应用程序都有一个关联的运行时对象 * * @author unascribed * @see java.lang.Runtime#getRunt ...

  5. Python re 正则表达式【一】【转】

    数量词的贪婪模式与非贪婪模式 正则表达式通常用于在文本中查找匹配的字符串.Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符:非贪婪的则相反,总是尝试匹配尽 ...

  6. Linux0.11之进程0创建进程1(1)

    进程0是由linus写在操作系统文件中的,是预先写死了的.那么进程0以后的进程是如何创建的呢?本篇文章主要讲述进程0创建进程1的过程. 在创建之前,操作系统先是进行了一系列的初始化,分别为设备号.块号 ...

  7. python数据存储--JSON

    HTML正文存储为两种格式:JSON和CSV. 存储为JSON: 首先利用Requests访问http://seputu.com获取HTML文档: #!coding:utf-8 import requ ...

  8. django使用session来保存用户登录状态

    先建好登录用的model,其次理解使用cookie和session的原理,一个在本机保存,一个在服务器保存 使用session好处,可以设置登录过期的时间, 编写views中login的函数 def ...

  9. ubuntu安装成功之后需要做些什么?

    1.安装VMtool 1.1打开虚拟机之后-> 安装VMtool 1.2 点击之后,桌面就会出现一个VMtool光驱文件,如果提示光驱被占用就先用root登录 1.3在命令行挂载 sudo mo ...

  10. django在进行模板render(渲染)时,对传过来的是字典中包含字典应用方法

    网上自强学堂参考的 views.py def home(request): info_dict = {'site': u'自强学堂', 'content': u'各种IT技术教程'} return r ...