Redis(hiredis篇) - Go语言中文社区

Redis(hiredis篇)


Hiredis

结构图

173022_ZveM_1380836.png

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 abcfrom 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,初始化maxbufREDIS_READER_MAX_BUF1024 * 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)

解析redisReaderbuffer字符流,并获取到相应结果。

redisReaderGetReply 解析过程依赖于redisReadTaskredisReplyObjectFunctions函数组,其中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,也就是说使用redisReaderAPI取获取应答。

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端有三种反应:

1client端连接正常,返回一个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结构体中的读写事件注册删除函数。

如图:173336_gVKD_1380836.png

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

如图:

173400_HYSi_1380836.png

173400_gDnA_1380836.png


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

 如图:

173418_OLch_1380836.png

173418_5xPY_1380836.png

使用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回调函数。

异步处理流程

174716_Sv2w_1380836.png

转载于:https://my.oschina.net/465759695/blog/644063

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_34388207/article/details/92036836
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢