Redis异步

Hiredis

结构图

sds

说明 :简单字符类型,typedef char * sds

API

sds sdsnewlen(const void *init, size_t initlen)

sds sdsnew(const char *init)

sds sdsempty(void)

size_t sdslen(const sds s)

sds sdsdup(const sds s)

void sdsfree(sds s)

size_t sdsavail(const sds s)

sds sdsgrowzero(sds s, size_t len)

grow到至少只用了len长度,多出的被设置为zero

sds sdscatlen(sds s, const void *t, size_t len)

sds sdscat(sds s, const char *t)

sds sdscatsds(sds s, const sds t)

sds sdscpylen(sds s, const char *t, size_t len)

sds sdscpy(sds s, const char *t)

sds sdscatvprintf(sds s, const char *fmt, va_list ap)

sds sdscatprintf(sds s, const char *fmt, ...)

sds sdscatfmt(sds s, char const *fmt, ...)

sds sdstrim(sds s, const char *cset)

void sdsrange(sds s, int start, int end)

截取保留到指定区间

void sdsupdatelen(sds s)

使用strlen(s) 来更新使用的长度

void sdsclear(sds s)

int sdscmp(const sds s1, const sds s2)

sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count)

void sdsfreesplitres(sds *tokens, int count)

void sdstolower(sds s)

void sdstoupper(sds s)

sds sdsfromlonglong(long long value)

sds sdscatrepr(sds s, const char *p, size_t len)

sds *sdssplitargs(const char *line, int *argc)

sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen)

将s中的字符,根据from转化为to 比如 s 为 abc,from为 ac , to 为12,则转化后为1b2

sds sdsjoin(char **argv, int argc, char *sep)

将字符用sep 连接起来

sds sdsMakeRoomFor(sds s, size_t addlen)

保证s有充足的可以空间addlen

void sdsIncrLen(sds s, int incr)

将已使用的长度加上incr作为新的已经使用的长度,incr可以为负数,不会分配和释放空间

sds sdsRemoveFreeSpace(sds s)

释放free空间

size_t sdsAllocSize(sds s)

获取已经分配的大小

hiredis

redisReader

API

redisReader *redisReaderCreate(void)

创建redisReader,并初始化,初始化默认的对象创建函数组为defaultFunctions,初始化maxbuf为REDIS_READER_MAX_BUF(1024 * 16),maxbuf控制当redisReader buffer申请的大小大于maxbuf时,必要时会进行内存释放。

 

void redisReaderFree(redisReader *r)

 

释放redisReader。

 

int redisReaderFeed(redisReader *r, const char *buf, size_t len)

 

将字符流放入到redisReader 的buffer区域。

 

int redisReaderGetReply(redisReader *r, void **reply)

解析redisReader的buffer字符流,并获取到相应结果。

redisReaderGetReply 解析过程依赖于redisReadTask和redisReplyObjectFunctions函数组,其中redisReadTask主要用在处理Array对象,redisReplyObjectFunctions函数组用于创建对象。

 

 

 

outbuf

redisContext 结构体中的变量,作为命令的输出缓冲区,所有命令会写到这个缓冲区,当调用redisGetReply时,如果调用redisReaderGetReply未获取到应答对象,并且redisContext是阻塞模式时,会将该缓冲区的数据发送出去。主动调用redisBufferWrite也会发送。

redisConext

API

redisContext *redisConnect(const char *ip, int port)

redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv)

redisContext *redisConnectNonBlock(const char *ip, int port)

redisContext *redisConnectBindNonBlock(const char *ip, int port, const char *source_addr)

redisContext *redisConnectUnix(const char *path)

redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv)

redisContext *redisConnectUnixNonBlock(const char *path)

redisContext *redisConnectFd(int fd)

int redisSetTimeout(redisContext *c, const struct timeval tv)

int redisEnableKeepAlive(redisContext *c)

void redisFree(redisContext *c)

int redisFreeKeepFd(redisContext *c)

 

int redisBufferRead(redisContext *c)

   读取数据流,写入到redisReader缓冲区。

int redisBufferWrite(redisContext *c, int *done)

   将outbuf缓冲区数据,发送出去

int redisGetReplyFromReader(redisContext *c, void **reply)

   调用redisReaderGetReply,也就是说使用redisReader的API取获取应答。

int redisGetReply(redisContext *c, void **reply)

   使用redisGetReplyFromReader获取应答,如果没有应答,将outbuf缓冲区发送出去,然后循环使用redisBufferRead,读取数据流,使用redisGetReplyFromReader启尝试获取应答,直到获取到应答信息。

 

int redisFormatCommand(char **target, const char *format, ...)

   格式化命令

int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len)

   将已经格式化的命令添加的outbuf发送缓冲区当中

int redisAppendCommand(redisContext *c, const char *format, ...)

   格式化命令,并将命令添加到outbuf 发送缓冲区当中。

 

void *redisCommand(redisContext *c, const char *format, ...)

   格式化命令,并将命令添加到outubuf发送缓冲区中(调用 redisAppendCommand),如果是block模式的话,调用redisGetReply 获取应答。

net

API

int redisCheckSocketError(redisContext *c);

int redisContextSetTimeout(redisContext *c, const struct timeval tv);

说明:设置redisContext 上下文关联的socket描述符的发送超时时间和接收超时时间

int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct ti        meval *timeout);

int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout,                          const char *source_addr);

int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *ti        meout);

int redisKeepAlive(redisContext *c, int interval);

说明:keepalive原理:TCP内嵌有心跳包,以服务端为例,当server检测到超过一定时间(/proc/sys/net/ipv4/tcp_keepalive_time 7200 即2小时)没有数据传输,那么会向client端发送一个keepalive packet,此时client端有三种反应:

1、client端连接正常,返回一个ACK.server端收到ACK后重置计时器,在2小时后在发送探测.如果2小时内连接上有数据传输,那么在该时间的基础上向后推延2小时发送探测包;

2、客户端异常关闭,或网络断开。client无响应,server收不到ACK,在一定时间(/proc/sys/net/ipv4/tcp_keepalive_intvl 75 即75秒)后重发keepalive packet, 并且重发一定次数(/proc/sys/net/ipv4/tcp_keepalive_probes 9 即9次);

3、客户端曾经崩溃,但已经重启.server收到的探测响应是一个复位,server端终止连接。

这个函数是启动c关联的socket套接字的keepalive,设置情况2重发的时间间隔,重发次数,以及下一次发送探测包的时间间隔

adapters

实现的接口规范

如:int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac)

将async层的redisAsyncContext 与 ae事件处理相关联起来。

1、  需要实现redisAeAttach函数设置ac->ev结构体中的读写事件注册删除函数。

如图:

2、需要将实现读事件回调函数,并且该读事件回调函数调用async层的redisAsyncHandleRead函数

如图:

 

3、需要将实现写事件回调函数并调用async层的redisAsyncHandleWrite函数

 如图:

使用RedisAeEvent 结构体将async 与 ae 联通起来,注册事件是,RedisAeEvenet变量传入,回调函数时,将该变量传回。

async

异步上下文

struct redisAsyncContext

结构体成员

redisContext c;    redisContext 上下文用于与redis服务器通讯

int err;          错误码

char * errstr;     错误信息

struct {

void * data;

void (*addRead)(void *privdata);

void (*delRead)(void * privdata);

void (*addWrite)(void * privdata);

void (*delWrite)(void *) privdata);

void (*cleanup)(void *)privdata):

} ev;       事件数据钩子

redisDisconnectCallback *onDisconnect;   回调函数,当连接被断开时调用

redisConnectCallback *onConnect;       回调函数,当第一个写事件接收到时调用

redisCallbackList replies;

struct {

 redisCallbackList invaild;

 struct dict * channels;

 struct dict * patterns;

} pub;                 订阅回调函数

 

API

 

redisAsyncContext *redisAsyncConnect(const char *ip, int port)

说明:代理hiredis redisConnectNonBlock函数,hihredisConnectNonBlock 函数连接服务器后,设置socket为非阻塞状态

 

redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr)

说明:代理redisConnectBindNonBlock 函数,redisConnectBindNonBlock函数连接服务器后,设置socket为非阻塞状态

 

redisAsyncContext *redisAsyncConnectUnix(const char *path)

说明:代理redisConnectUnixNonBlock函数,redisConnectUnixNonBlock函数连接服务器后,设置socket为非阻塞状态

 

int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn)

说明:设置连接回调函数

 

int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn)

说明:设置断开连接回调函数

 

void redisAsyncDisconnect(redisAsyncContext *ac)

void redisAsyncFree(redisAsyncContext *ac)

 

void redisAsyncHandleRead(redisAsyncContext *ac)

读事件回调函数,适配器层实现的读事件回调函数需要调用该函数

void redisAsyncHandleWrite(redisAsyncContext *ac)

写事件回调函数,适配器层实现的写事件回调函数需要调用该函数

 

int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const         char *format, ...)

异步发送命令到Redis服务,有应答调用fn回调函数。

异步处理流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值