【转载】redis优化
原文链接
批量操作优化:
- 在使用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优化的更多相关文章
- Redis 优化查询性能
一次使用 Redis 优化查询性能的实践 应用背景 有一个应用需要上传一组ID到服务器来查询这些ID所对应的数据,数据库中存储的数据量是7千万,每次上传的ID数量一般都是几百至上千数量级别. 以前 ...
- 一次使用 Redis 优化查询性能的实践
因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,一次使用 Redis 优化查询性能的实践 应用背景 有一个应用需要上传一组ID到 ...
- [转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam
[转载]机器学习优化方法总结:SGD,Momentum,AdaGrad,RMSProp,Adam https://blog.csdn.net/u010089444/article/details/76 ...
- 【转载】Redis优化经验
转载地址:http://blog.sina.com.cn/s/blog_4be888450100z2ze.html 内存管理优化 Redis Hash是value内部为一个HashMap,如果该Map ...
- 【转载】redis优化配置和redis.conf说明
转载地址:http://blog.csdn.net/luozhonghua2014/article/details/40568707?utm_source=tuicool&utm_medium ...
- [转载] Redis
转载:http://snowolf.iteye.com/blog/1630697 大约一年多前,公司同事开始使用Redis,不清楚是配置,还是版本的问题,当时的Redis经常在使用一段时间后,连接爆满 ...
- [转载] Redis 起步
转载地址:http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html Rdis和JQuery一样是纯粹为应用而产生的,这里记录的是在C ...
- [转载] Redis资料汇总专题
转载自http://www.cnblogs.com/tommyli/archive/2011/12/14/2287614.html 1.Redis是什么? 十五分钟介绍 Redis数据结构 Redis ...
- Redis优化之CPU充分利用
Linux Redis Server之CPU充分利用 不知道大家有没有注意到你们公司的集群配置是否是有一种配置是这样的: 多个Redis Server分布在同一个节点,只是端口不同,如果有的话,应该是 ...
随机推荐
- SG函数入门
sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3.mex{2 ...
- GitHubDesktop的使用方法
author:headsen chen date:2018-05-30 17:24:55 notice:This article is created by headsen chen hims ...
- iOS 界面翻转切换动画
[UIView beginAnimations:nil context:NULL]; [UIView setAnimationCurve:UIViewAnimationCurveLinear]; [ ...
- dao---service---action分层结构
此文转载于http://blog.csdn.net/jay198746/article/details/4698709 之前有看过一些ssh2中采用dao---service---action分层结构 ...
- 在R语言环境中设置JRE路径
解决办法: 1.如果没有java运行环境,则需安装对应版本的jre,如R64就需要安装jre64位的,并且要注意在系统环境变量中指定java_home 2.如果有java运行环境,检查你的java版本 ...
- 巨蟒python全栈开发flask13项目开始5
1.Toy回复App消息 2.离线维度消息数量存储 3.Toy批量收取消息 4.Toy主动发起消息&&AI对接 5.Toy_info 1.Toy回复App消息 2.离线维度消息数量存储 ...
- input即时————模糊匹配(纯html+jquery简单实现)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- Oracle 删除表
drop table books;的指令会将表放到回收站里, 用 flashback table "BIN$1Oiy3qm/QJubov1BwBUOgw==$0" to befor ...
- 【opencv】ubuntu opencv imshow()报错
错误提示: ubuntu opencv imshow() 报错 windows.cpp报错 the function is not implemented If you are on Ubuntu o ...
- 《iOS Human Interface Guidelines》——Popover
弹出框 弹出框是当人们点击一个控件或屏幕上一个区域时显示的一个暂时的界面. API NOTE 在iOS 8及以后的系统中.你能够使用UIPopoverPresentationController来显示 ...