[hiredis 源码走读] 异步回调机制剖析

本文深入剖析了hiredis的异步回调机制,包括请求回调流程、时序保证以及实现高性能的原因。hiredis利用tcp链接的时序性和redis的单线程处理,确保命令的异步回调顺序。同时,通过非阻塞网络通信和多路复用技术,如libev结合epoll,实现了高并发性能。

hiredis 是 redis 的一个 c - client,异步通信非常高效。单链接异步压测,轻松并发 10w+,具体请参考《hiredis + libev 异步测试》。本章主要剖析 hiredis 异步回调机制原理,围绕三个问题,展开描述。

  1. 异步回调原理。
  2. 异步回调如何保证 request/response 时序。
  3. 单链接异步读写 redis,为何能并发 10w+。

文章来源🔥:《[hiredis 源码走读] 异步回调机制剖析


1. 异步回调原理

先看看异步通信流程。

高性能异步框架通信流程

设计图来源:《异步服务框架通信流程


1.1. demo

hiredis demo,除了提供访问 redis 的同步异步接口,还支持支持大部分主流事件库,它非常实用。

[wenfh2020: hiredis/examples]$ tree
.
├── CMakeLists.txt
├── example-ae.c
├── example-glib.c
├── example-ivykis.c
├── example-libev.c
├── example-libevent-ssl.c
├── example-libevent.c
├── example-libuv.c
├── example-macosx.c
├── example-qt.cpp
├── example-qt.h
├── example-ssl.c
└── example.c

1.2. 使用

hiredis 回调接口使用简单,做得非常精简。例如结合 libev 实现异步回调 demo,只要绑定三个接口即可。

int main (int argc, char **argv) {
#ifndef _WIN32
    signal(SIGPIPE, SIG_IGN);
#endif

    redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
    if (c->err) {
        /* Let *c leak for now... */
        printf("Error: %s\n", c->errstr);
        return 1;
    }

    redisLibevAttach(EV_DEFAULT_ c);
    redisAsyncSetConnectCallback(c,connectCallback);
    redisAsyncSetDisconnectCallback(c,disconnectCallback);
    redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
    redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
    ev_loop(EV_DEFAULT_ 0);
    return 0;
}

1.3. 回调接口

hiredis 异步通信上下文 redisAsyncContext 结构,三个回调接口分别是:

  1. 链接回调 redisConnectCallback
  2. 断开链接回调 redisDisconnectCallback
  3. 正常数据通信回调 redisCallbackFn
// async.h
/* Reply callback prototype and container */
typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*);
typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status);
typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status);

typedef struct redisCallback {
   
   
    struct redisCallback *next; /* simple singly linked list */
    redisCallbackFn *fn;
    int pending_subs;
    void *privdata;
} redisCallback;

/* List of callbacks for either regular replies or pub/sub */
typedef struct redisCallbackList {
   
   
    redisCallback *head, *tail;
} redisCallbackList
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值