原文链接

批量操作优化:

  • 在使用redis的时候,客户端通过socket向redis服务端发起请求后,等待服务端的返回结果。
  • 客户端请求服务器一次就发送一个报文 -> 等待服务端的返回 -> 关闭连接
  • 如果是100个请求、1000个请求,那就得请求100次、1000次
  • 所以使用多个请求的时候使用管道来操作(如果管道打包的命令太多占用的内存也会越大,适量)
  • 以下是使用3种方式进行的测试(循环写入1000次):

    public static void main(String[] args) {
    
        long start = System.currentTimeMillis();
    for (int i = 0; i < 1000; i++) {
    template.opsForHash().put("user1", "status" + i, "value" + i);
    }
    System.out.println(System.currentTimeMillis() - start); start = System.currentTimeMillis();
    final byte[] rawKey = rawKey("user2");
    template.execute(new RedisCallback<Object>() { @Override
    public Object doInRedis(RedisConnection connection)
    throws DataAccessException {
    for (int i = 0; i < 1000; i++) {
    final byte[] rawHashKey = rawHashKey("status" + i);
    final byte[] rawHashValue = rawHashValue("value" + i); connection.hSet(rawKey, rawHashKey, rawHashValue);
    }
    return null;
    }
    });
    System.out.println(System.currentTimeMillis() - start); start = System.currentTimeMillis();
    final byte[] rawKey2 = rawKey("user3");
    template.execute(new RedisCallback<Object>() { @Override
    public Object doInRedis(RedisConnection connection)
    throws DataAccessException {
    connection.openPipeline();
    for (int i = 0; i < 1000; i++) {
    final byte[] rawHashKey = rawHashKey("status" + i);
    final byte[] rawHashValue = rawHashValue("value" + i); connection.hSet(rawKey2, rawHashKey, rawHashValue);
    }
    return connection.closePipeline();
    }
    });
    System.out.println(System.currentTimeMillis() - start);
    }
  • 请求结果

    20:54:51.653 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
    20:54:51.693 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
    42283
    20:54:51.695 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
    20:55:33.922 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
    42228
    20:55:33.923 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
    20:55:34.058 [main] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
    136
  • 可以看出在使用管道打包发送请求所用的时间不到1s。而发送1000次请求所用的时间达到了42s。

从请求结果看到多次 Opening RedisConnection 和 Closing Redis Connection 的日志.

阅读源代码我们可以发现我们对redis的所有操作都是通过回调execute函数执行的,其代码如下:

public <T> T execute(RedisCallback<T> action, boolean exposeConnection) {
return execute(action, exposeConnection, false);
}
// execute实现如下:
// org.springframework.data.redis.core.RedisTemplate<K, V> --- 最终实现
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
Assert.isTrue(initialized, "template not initialized; call afterPropertiesSet() before using it");
Assert.notNull(action, "Callback object must not be null");
RedisConnectionFactory factory = getConnectionFactory();
RedisConnection conn = null;
try {
if (enableTransactionSupport) {
// only bind resources in case of potential transaction synchronization
conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
} else {
conn = RedisConnectionUtils.getConnection(factory);
}
boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
RedisConnection connToUse = preProcessConnection(conn, existingConnection);
boolean pipelineStatus = connToUse.isPipelined();
if (pipeline && !pipelineStatus) {
connToUse.openPipeline();
}
RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
T result = action.doInRedis(connToExpose);
// close pipeline
if (pipeline && !pipelineStatus) {
connToUse.closePipeline();
}
// TODO: any other connection processing?
return postProcessResult(result, connToUse, existingConnection);
} finally {
if (!enableTransactionSupport) {
RedisConnectionUtils.releaseConnection(conn, factory);
}
}
}

这里面每次执行action.doInRedis(connToExpose)前都要调用RedisConnectionUtils.getConnection(factory);获得一个连接,进入RedisConnnectionUtils类中,getConnection(factory)最终调用的是doGetConnection(factory, true, false, enableTranactionSupport)这个函数。这个函数我们可以看下api文档,发现实际上并不是真的创建一个新的redis连接,它只是在connectFactory中获取一个连接,也就是从连接池中取出一个连接。当然如果connectFactory没有连接可用,此时如果allowCreate=true便会创建出一个新的连接,并且加入到connectFactory中。

基本上可以确定真实的情况是spring-data-redis已经帮我们封装了连接池管理,我们只需要调用一系列操作函数即可,这给操作redis带来了极大的方便。

【转载】redis优化的更多相关文章

  1. Redis 优化查询性能

    一次使用 Redis 优化查询性能的实践   应用背景 有一个应用需要上传一组ID到服务器来查询这些ID所对应的数据,数据库中存储的数据量是7千万,每次上传的ID数量一般都是几百至上千数量级别. 以前 ...

  2. 一次使用 Redis 优化查询性能的实践

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,一次使用 Redis 优化查询性能的实践 应用背景 有一个应用需要上传一组ID到 ...

  3. [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam

    [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam https://blog.csdn.net/u010089444/article/details/76 ...

  4. 【转载】Redis优化经验

    转载地址:http://blog.sina.com.cn/s/blog_4be888450100z2ze.html 内存管理优化 Redis Hash是value内部为一个HashMap,如果该Map ...

  5. 【转载】redis优化配置和redis.conf说明

    转载地址:http://blog.csdn.net/luozhonghua2014/article/details/40568707?utm_source=tuicool&utm_medium ...

  6. [转载] Redis

    转载:http://snowolf.iteye.com/blog/1630697 大约一年多前,公司同事开始使用Redis,不清楚是配置,还是版本的问题,当时的Redis经常在使用一段时间后,连接爆满 ...

  7. [转载] Redis 起步

    转载地址:http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html Rdis和JQuery一样是纯粹为应用而产生的,这里记录的是在C ...

  8. [转载] Redis资料汇总专题

    转载自http://www.cnblogs.com/tommyli/archive/2011/12/14/2287614.html 1.Redis是什么? 十五分钟介绍 Redis数据结构 Redis ...

  9. Redis优化之CPU充分利用

    Linux Redis Server之CPU充分利用 不知道大家有没有注意到你们公司的集群配置是否是有一种配置是这样的: 多个Redis Server分布在同一个节点,只是端口不同,如果有的话,应该是 ...

随机推荐

  1. px像素单位与IOS像素单位的换算

    本文转载至  http://blog.csdn.net/fanyuna/article/details/24032663 30px转成磅为单位=22磅=二号 磅=(像素/96)*72 =(30/96) ...

  2. Spring学习笔记--使用Spring基于Java的配置

    我们需要使用@Component注解来定义一个配置类,在配置类中我们定义Bean: package com.moonlit.myspring; import org.springframework.c ...

  3. zookeeper报错Will not attempt to authenticate using SASL (unknown error)

    Will not attempt to authenticate using SASL (unknown error) 转自:http://blog.csdn.net/mo_xingwang/arti ...

  4. HDU 5875 Function 大连网络赛 线段树

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total ...

  5. PacificA: Replication in Log-Based Distributed Storage Systems

    PacificA: Replication in Log-Based Distributed Storage Systems - Microsoft Research https://www.micr ...

  6. Webpack4.x 入门

    概览 新建项目 npm init -y 安装webpack & webpack-cli (c)npm install -D webpack (c)npm install -D webpack- ...

  7. 如何实现手游app瘦身?

    手游服务商来说,手游包体大一直是个很困扰的问题.一款手游产品而言,包体大小和更新方式对于有效用户的转化率往往起到非常关键的作用,话说手游安装包越小,用户转化率越高,那该如何实现app瘦身呢? 工具/原 ...

  8. MySQL优化(二):SQL优化

    一.SQL优化 1.优化SQL一般步骤 1.1 查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; Com_select:执行SELECT操作的次数,一次查询累加1.其他类似 以下 ...

  9. python学习笔记——字符串

    类方法string.upper(str)需要引入string模块,实例方法str.upper()不需要引入string模块 无与伦比的列表解析功能 # coding=utf-8 # 列表解析 prin ...

  10. UVA Team Queue

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013840081/article/details/26180081 题目例如以下: Team Qu ...