hiredis的pipeline实现

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

大多数同学一直以来对 Redis 管道有一个误解他们以为这是 Redis 服务器提供的一种特别的技术有了这种技术就可以加速 Redis 的存取效率。但是实际上 Redis 管道 (Pipeline) 本身并不是 Redis 服务器直接提供的技术这个技术本质上是由客户端提供的跟服务器没有什么直接的关系。

hiredis pipeline 实现细节以及两种封装

hiredis的pipeline实现

使用方式

发送命令

通过连续调用

redisAppendCommand(context, cmd)

将命令拼接成一个长字符串这个字符串包含所有的命令且符合redis协议。

字符串拼接过程如果原字符串空间不足了就会触发内存再分配和拷贝动作。这是由sds.c完成的。

获取结果

通过反顺序调用

redisGetReply(context, reply)

获取对应cmd的reply

redisGetReply(context, reply)内部实现如下

1.看看是否在context包含的buf中有reply可以get如果有读取一个。这里一定是因为buf中的数据符合redis协议n个reply以特定格式连在一起因此每次可以get一个。如果有reply get则返回成功否则进入下一步2

2.阻塞方式从fd读取replys并存储在context包含的buf中并取出一个reply然后返回。

C++ redis-client 对pipeline的封装

1.没有cluster的情况

 c++ redis-client抽象出了cmd对象每个cmd对象包含命令字符串、返回值buf等。使用pipeline时将cmd对象依次压人pipeline。然后调用pipeline 的flush接口将命令发送给server。flush接口内部则是依次调用redisAppendCommand()最后反向调用redisGetReply()将reply一次保存在cmd对象自己的buf中再提供一个fetchreply接口依次从cmd的buf中取结果。

 2.有cluster的情况

  一个pipeline中的cmd将根据由key所属的slot拆分成多个pipeline每个pipeline按照1.中的方式执行。要注意的是由于cmd的执行顺序被打乱了因此需要保存cmd压人pipeline的次序以供fetchreply使用。

C redis client 对pipeline的封装

1没有cluster的情况

  由于不打算抽象出cmd对象可以设计一个动态数组存储cmd顺序和返回对象的地址。结果正向压入反向取出。

2有cluster的情况

   除了上述动态数组还需要为每个sub pipeline准备一个数组数组中存储cmd的全局顺序。

3为了统一1,2 考虑将1当作2的特例即自有一个sub pipeline的情况也增加一个数组

M 操作和pipeline管道管线区别

Pipeline操作和原生批量操作(M 操作)的对比

我们学过 M 操作也是类似 pipeline将多个命令一次执行一次发送出去节省网络时间。对比如下

M操作在Redis队列中是一个原子操作pipeline不是原子操作

pipeline与M操作都会将数据顺序的传送顺序地返回redis 单线程

M 操作一个命令对应多个键值对而Pipeline是多条命令

1. mget、mset等原生批量操作

mget、mset等批量操作是原子操作

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis