Overview

  • About Redis pipelining
  • About Redis memory optimization
  • About Redis expire
  • About Redis transactions

Pipelining

Request/Response protocols and RTT

  • Redis is a TCP server using the client-server model and what is called a Request/Response protocol.
  • This means that usually a request is accomplished with the following steps:
    • The client sends a query to the server, and reads from the socket, usually in a blocking way, for the server response.
    • The server processes the command and sends the response back to the client.
  • Clients and servers are connected via a networking link. Such a link can be very fasr(a loopback interface) or very slow(a connection established over the Internet with many hops between two hosts).
  • The time is called RTT(Round Trip Time). This will affect the performances when a client needs to perform many requests in a row. [当客户端需要在一个批处理中执行多次请求时,RTT就会对性能产生较大的影响。] 比如说,假设RTT时间很长,250ms,这时候即使服务器每秒能处理100k的请求数,我们每秒也只能处理4个请求。
  • If the interface used is a loopback interface, the RTT is much shorter(for instance my host reports 0.044ms pinging 127.0.0.1), but it is still a lot if u need to perform many writes in a row.

Redis Pipelining

  • A Request/Response server can be implemented so that it is able to process new requests even if the client didn't already read the old responses. [服务器能够在旧的请求还未被响应的情况下处理新的请求,那么就可以将多个命令发送到服务器,而不用等待回复,直接在最后一个步骤中读取该回复即可。]

Summary

  • so,如果不用管道,四个请求需要8个TCP报文,4次RTT。如果网络延迟0.125s,那么需要1s完成四个请求。redis的处理能力完全发挥不出来。
  • 为了提高效率,处理利用mset、mget之类的单条命令处理多个key外,
  • 我们还可以使用pipelining的方式,从client打包多条命令,一起发出,不需要等待单条命令的响应返回,redis server会处理完多条命令后将结果打包返回给client。
  • 假设tcp报文不会因为过长而被拆分,上述4个请求就只需要两个tcp报文。
  • 但是也不是说打包的命令越多越好,因为打包的命令越多,内存消耗也越多。因为redis必须在处理完所有命令前缓存之前所有命令的处理结果。

Test

  • public void pipeLine() {
    Jedis jedis = null;
    try {
    jedis = new Jedis(REDIS_HOST, REDIS_PORT);
    Pipeline pipeline = jedis.pipelined();
    for (int i = 0; i < COUNT; i++) {
    pipeline.incr(testKey);
    }
    pipeline.sync();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    if(jedis != null) jedis.disconnect();
    } } public void withoutPipeline() {
    Jedis jedis = null;
    try {
    jedis = new Jedis(REDIS_HOST, REDIS_PORT);
    for (int i = 0; i < COUNT; i++) {
    jedis.incr(testKey);
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    if (jedis != null) jedis.disconnect();
    }
    } public static void main(String[] args) {
    PipelineTest pipelineTest = new PipelineTest();
    long start = System.currentTimeMillis(); pipelineTest.withoutPipeline(); long mid = System.currentTimeMillis();
    System.out.println("Without pipeline, using: " + (mid - start)); pipelineTest.pipeLine(); System.out.println("With pipeline, using: " + (System.currentTimeMillis() - mid)); }
  • 输出:(100条incr请求)
    Without pipeline, using: 9816
    With pipeline, using: 45

Memory Optimization

Special encoding of small aggreagte data types

  • Redis2.2以后,存储集合数据的时候会采用内存压缩技术。
  • 比如对Hash、List、Set以及Sorted Set,当这些集合中的所有数都小雨一个给定的元素,并且集合中元素数量小于某个值时,存储的数据会被以一种十分节省内存的方式进行编码。理论上能节省10倍以上内存。并且该编码技术对用户和redis api透明。
  • 实质上是用CPU换内存。
  • 阈值可以在redis.conf中修改。

Using 32 bit instances

  • 使用32bit的redis,那么对每个key将使用更少的内存。

Bit and byte level operations

  • Redis2.2引入了位级别和字级别的操作:GETRANGE, SETRANGE, GETBIT, SETBIT。
  • 通过使用这些命令,你可以把redis的字符串当成一个随机读取的(字节)数组。
  • 例子:如果用户的id是连续的整数,那么你可以使用bitmap位图来纪录用户的性别,可以直接操作在bit之上。

Uses hashes when possible

  • 小的散列表(小是指散列表内部存储的对象少)使用的内存非常小。
  • TBD...

Expire

EXPIRE Key seconds

  • 超时后只有在对key执行DEL、SET或GETSET时才会清除。[?????]
  • 过期精度:从Redis2.6起,过期时间误差缩小到0-1ms。
  • Redis如何淘汰过期key:
    • Redis keys过期有两种方式:主动和被动方式。
    • 被动:当一些客户端尝试访问它们时,key会被发现并主动的过期。
    • 主动:Redis每10s:
      • 测试随机的20个key,进行相关过期检测;
      • 删除已过期的key;
      • 若有多于25%的key过期,则重复步骤1
    • 以上,这是一个平凡的概率算法。

Redis Transactions

Introduction

  • MULTI, EXEC, DISCARD,WATCH是redis事务相关的命令。
  • 事务可以一次执行多个命令,并且:
    • 事务是一个单独的隔离操作:事务中所有命令都会序列化、按顺序地执行。执行过程中,不会被其他client的请求打断。
    • 原子操作:要么全部执行,要么全部不执行。
  • EXEC:
    • EXEC负责触发并执行事务中的所有命令
    • 如果client在使用MULTI开启了一个事务之后,如果没有执行EXEC,那么事务中所有命令都不会执行。
  • 当使用AOF方式做持久化时,redis会使用单个write命令将事务写到磁盘中。然而,若此时redis server由于某些原因挂掉,那么可能只有部分事务命令会被成功写入到磁盘中。
  • 若在redis重启时发现AOF文件出现了这样的问题,那么它会退出,并汇报一个错误。

为什么Redis不支持roll back

  • 这种做法的优点:

    • 因为不需要支持roll back,因此redis内部可以保持简单且快速。
    • redis命令只会因为错误的语法而失败(并且这些错误不能在入队时发现),或是因为命令用在了错误类型的key上。理论上这些错误应该在开发过程被发现。

使用check-and-set乐观锁

  • WATCH命令可以为redis事务提高check-and-set(CAS)行为
  • TBD...

<Redis Advance><Pipelining><Memory Optimization><Expire><Transactions>的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. canvas手机端绘图解决方案

    解决方案js:https://pan.baidu.com/s/1jIys2aU 我们使用canvas通常会遇到一个问题就是坐标系的问题,如果按象限来说,一般canvas是在第四象限,但是我们通常都喜欢 ...

  2. Confluence 6 创建一个项目空间

    火星移民小组的程序需要一个地方能够调出他们任务的相关关键信息和资源,你的任务就是帮助他们实现和管理这个需求.这部分是比较容易实现的,因为这些信息需要让空间项目组中完全可见. 这样的话,你就可以设置项目 ...

  3. Arthur and Brackets CodeForces - 508E (贪心,括号匹配)

    大意: n个括号, 位置未知, 给出每对括号左右间距, 求输出一个合法括号序列. 最后一个括号间距一定为1, 从右往左遍历, 每次括号划分越小越好. #include <iostream> ...

  4. 『计算机视觉』Mask-RCNN_推断网络其三:RPN锚框处理和Proposal生成

    一.RPN锚框信息生成 上文的最后,我们生成了用于计算锚框信息的特征(源代码在inference模式中不进行锚框生成,而是外部生成好feed进网络,training模式下在向前传播时直接生成锚框,不过 ...

  5. php 字符编码转换

    <?php/** * Created by PhpStorm. * User: yxp * Date: 2016/11/8 * Time: 16:47 */ /** * 将非GBK字符集的编码转 ...

  6. leetcode-algorithms-1 two sum

    leetcode-algorithms-1 two sum Given an array of integers, return indices of the two numbers such tha ...

  7. Excel中如何匹配另外一个Excel中的数据

    场景: 我在Excel中想展示通过一列匹配到另外Excel中的数据.对于程序员来说,就是left join 出 B表的数据. 但是在Excel中怎么做呢,我又不想每次都在把数据导入到数据库中操作. 这 ...

  8. 32. Longest Valid Parentheses最长有效括号

    参考: 1. https://leetcode.com/problems/longest-valid-parentheses/solution/ 2. https://blog.csdn.net/ac ...

  9. 字符序列(characts)

    字符序列(characts) 问题描述: 从三个元素的集合[A,B,C]中选取元素生成一个N 个字符组成的序列,使得没有两个相邻的 子序列(子序列长度=2)相同,例:N=5 时ABCBA 是合格的,而 ...

  10. UNIX发展史简介

    1965年贝尔实验室(Bell Labs).通用电气(General Electric)和麻省理工学院(MIT)欲共同打造MULTICS(Multiplexed Information and Com ...