五.redis pipeline

本文通过实测 Redis Pipeline 功能,探讨其在网络延迟较小环境下的性能优势及内存消耗考量,提供了 JRedis 客户端使用 Pipeline 的案例,并分析了其在大量操作场景下的效率提升和潜在限制。

redis是一个cs模式的tcp server,使用和http类似的请求响应协议。一个client可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常 会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client。基本的通信过程如下

Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR
X
Server: 3
Client: INCR X
Server: 4
基 本上四个命令需要8个tcp报文才能完成。由于通信会有网络延迟,假如从client和server之间的包传输时间需要0.125秒。那么上面的四个命 令8个报文至少会需要1秒才能完成。这样即使redis每秒能处理100个命令,而我们的client也只能一秒钟发出四个命令。这显示没有充分利用 redis的处理能力。除了可以利用mget,mset 之类的单条命令处理多个key的命令外
我们还可以利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下
Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X
Server:
1
Server: 2
Server: 3
Server: 4
假 设不会因为tcp 报文过长而被拆分。可能两个tcp报文就能完成四条命令,client可以将四个incr命令放到一个tcp报文一起发送,server则可以将四条命令 的处理结果放到一个tcp报文返回。通过pipeline方式当有大批量的操作时候。我们可以节省很多原来浪费在网络延迟的时间。需要注意到是用 pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并是不是打 包的命令越多越好。具体多少合适需要根据具体情况测试。下面是个jredis客户端使用pipeline的测试
package jredisStudy;
import org.jredis.JRedis;
import
org.jredis.connector.ConnectionSpec;
import
org.jredis.ri.alphazero.JRedisClient;
import
org.jredis.ri.alphazero.JRedisPipelineService;
import
org.jredis.ri.alphazero.connection.DefaultConnectionSpec;
public class
PipeLineTest {
public static void main(String[] args)
{
long start =
System.currentTimeMillis();

usePipeline();
long
end =
System.currentTimeMillis();

System.out.println(end-start);

start =
System.currentTimeMillis();

withoutPipeline();

end =
System.currentTimeMillis();

System.out.println(end-start);
}

private static void withoutPipeline()

{
try
{

JRedis jredis = new
JRedisClient("192.168.56.55",6379);

for(int i =0 ; i < 100000 ;
i++)

{

jredis.incr("test2");

}

jredis.quit();
} catch (Exception
e) {
}

}
private static void usePipeline()
{
try
{

ConnectionSpec spec = DefaultConnectionSpec.newSpec("192.168.56.55", 6379, 0,
null);

JRedis jredis = new
JRedisPipelineService(spec);

for(int i =0 ; i < 100000 ;
i++)

{

jredis.incr("test2");

}

jredis.quit();
} catch (Exception
e) {
}

}
}
输出
103408 //使用了pipeline
104598 //没有使用
测试结果不是很明显,这应该是跟我的测试环境有关。我是在自己win连接虚拟机的linux。网络延迟比较小。所以pipeline
优势不明显。如果网络延迟小的话,最好还是不用pipeline。除了增加复杂外,带来的性能提升不明显。

转载于:https://my.oschina.net/91jason/blog/374825

### Python 中 `redis.Redis` 的用法 为了有效利用 Redis 数据库,在 Python 环境中通常会借助 `redis-py` 库来操作 Redis 实例。下面是一个简单的例子展示如何连接到本地运行的 Redis 服务器并执行基本的操作。 #### 安装依赖包 首先需要确保已经安装了 `redis-py` 这个客户端库,可以通过 pip 来完成安装: ```bash pip install redis ``` #### 创建连接实例 创建一个新的 Redis 连接对象非常简单,只需要指定主机名和其他必要的参数即可[^1]。 ```python import redis # 建立与Redis数据库的连接,默认端口为6379 r = redis.Redis(host='localhost', port=6379, db=0) # 测试连接是否正常工作 print(r.ping()) # 输出 True 表明连接成功 ``` #### 执行键值对操作 一旦建立了有效的连接,则可以开始向 Redis 发送命令来进行数据存储和检索活动。 ```python # 设置单个字符串类型的key-value result_set = r.set('foo', 'bar') print(result_set) # 返回True表示设置成功 # 获取之前设定好的value value_get = r.get('foo').decode() print(value_get) # 输出 "bar" ``` #### 使用管道提高效率 当有多个指令要发送给 Redis 时,使用 Pipeline 可以减少网络往返次数从而提升性能。 ```python pipe = r.pipeline() # 将多条命令放入队列中等待一次性提交 pipe.set('name', 'Alice') pipe.sadd('groups', 'admin', 'user') # 提交所有排队中的命令,并获取返回的结果列表 responses = pipe.execute() for response in responses: print(response) ``` 通过上述代码片段可以看出,`redis.Redis` 类提供了丰富的接口用于访问 Redis 功能集内的各种特性,从基础的数据结构管理到更复杂的事务处理都能得到良好支持[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值