<Redis Advance><Pipelining><Memory Optimization><Expire><Transactions>
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>的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- php 路途一点启示
wo: 面试了很多说后台不适合女孩,我不相信,而且我还很笨 he:不是立马就能让别人认可你,其中过程要经历很多得,有时候也要换个方式的'' wo: 我只是想用学的知识得到实践 he:那学习的过程不是 ...
- selenium配置Chrome驱动
1.http://chromedriver.storage.googleapis.com/index.html chrome下载驱动地址 和对应的版本驱动,不用FQ 2.配置方法:如在e盘创建一个 ...
- IDEA能运行,但是出现红色下划线的问题报 cannot resolve method
能编译通过并运行说明SDK导入正确,但是为啥我们点击每一个Java文件会出现好多红色的下划线 ,并提示idea cant resolve symbol.原因就是可能没有清除原来的历史缓存,导致一些错误 ...
- 【微信公众号开发】【8】网页授权获取用户基本信息(OAuth 2.0)
前言: 1,在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名. 请注意,这 ...
- input事件在ie9以下不兼容问题完美解决
上周四好不容易加了几天班把刚接手的一个pc页面做完,周五同事说要兼容ie7~ie9,结果在上面一跑,输入都没法输入. 我的需求是用6个span作为虚拟的密码输入框,实际上是用一个藏在页面里的input ...
- python low版线程池
1.low版线程池设计思路:运用队列queue 将线程类名放入队列中,执行一个就拿一个出来import queueimport threading class ThreadPool(object): ...
- PostgreSQL进程和内存结构
PostgreSQL数据库启动时,会先启动一个叫做Postmaster的主进程,还会fork一些辅助子进程,这些辅助子进程各自负责一部分功能,辅助子进程分类如下: $ ps -ef | grep po ...
- loj 10117 简单题(cqoi 2006)
题目来源:CQOI 2006 有一个 n 个元素的数组,每个元素初始均为 0.有 m条指令,要么让其中一段连续序列数字反转——0变 1,1 变 0(操作 1),要么询问某个元素的值(操作 2). 例如 ...
- JavaScript中var和this定义变量的区别
JavaScript中var和this定义变量的区别 在js中声明变量时可以使用var和this,但使用this的有很大一部分参考书是没有的,经过查阅相关资料总结如下: 用var和this声明变量,存 ...
- iOS 强大第三方资源库
Github用法 git-recipesGit recipes in Chinese. 高质量的Git中文教程. lark怎样在Github上面贡献代码 my-git有关 git 的学习资料 giti ...