Hiredis source code learning

Source: Internet
Author: User
Some time ago, when I learned about Redis, I heard the name of hiredis, And I was just doing asynchronous learning. I went to the Code to learn it. I almost don't know much about C. It is limited to the simplest syntax and has never been written in the production environment. So I should first look at the simple code of the Client. Next time I look at the Memcached code, it should be smoother. Hiredis is written in C.

Some time ago, when I learned about Redis, I heard the name of hiredis, And I was just doing asynchronous learning. I went to the Code to learn it. I almost don't know much about C. It is limited to the simplest syntax and has never been written in the production environment. So I should first look at the simple code of the Client. Next time I look at the Memcached code, it should be smoother. Hiredis is written in C.

Some time ago, when I learned about Redis, I heard the name of hiredis, And I was just doing asynchronous learning. I went to the Code to learn it. I almost don't know much about C. It is limited to the simplest syntax and has never been written in the production environment. So I should first look at the simple code of the Client. Next time I look at the Memcached code, it should be smoother.

Hiredis is a Redis client written in C. It encapsulates the Redis protocol and provides two APIs, synchronous and asynchronous. The Hiredis code is located at https://github.com/redis/hiredis.

One-minute entry

Synchronous API call method:

redisContext *context = redisConnect("127.0.0.1", 6379);reply = redisCommand(context, "SET foo %s", value); printf("PING: %s\n", reply->str);freeReplyObject(reply)redisFree(context);

The call method of Redis AE asynchronous API uses Redis's own AE event library. For details about why Redis does not use libevent or libev, refer to Reason:

void connectCallback(const redisAsyncContext *c, int status) {    printf("Connected...\n");}void disconnectCallback(const redisAsyncContext *c, int status) {    printf("Disconnected...\n");}void getCallback(redisAsyncContext *c, void *r, void *privdata) {    redisReply *reply = r;    if (reply == NULL) return;    printf("argv[%s]: %s\n", (char*)privdata, reply->str);    redisAsyncDisconnect(c);}redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);loop = aeCreateEventLoop();redisAeAttach(loop, c);redisAsyncSetConnectCallback(c,connectCallback);redisAsyncSetDisconnectCallback(c,disconnectCallback);redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");

Libev asynchronous API call becauseadapters/*.hEncapsulation is good, so it is almost the same as AE call:

void connectCallback(const redisAsyncContext *c, int status) {    printf("Connected...\n");}void disconnectCallback(const redisAsyncContext *c, int status) {    printf("Disconnected...\n");}void getCallback(redisAsyncContext *c, void *r, void *privdata) {    redisReply *reply = r;    if (reply == NULL) return;    printf("argv[%s]: %s\n", (char*)privdata, reply->str);    /* Disconnect after receiving the reply to GET */    redisAsyncDisconnect(c);}redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);redisLibevAttach(EV_DEFAULT_ c);redisAsyncSetConnectCallback(c,connectCallback);redisAsyncSetDisconnectCallback(c,disconnectCallback);redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");

Hiredis also supports libevent, which I will not list.

For more information, see https://github.com/redis/hiredis/tree/master/examples.

Main Structure
  • RedisReply
  • RedisReader
  • RedisContext
Process Synchronization connection

The code for synchronous connection is inhiredis.cAndnet.c.

redisConnect/redisConnectWithTimeout/redisConnectNonBlockAll callednet.cInsideredisContextConnectTcp. Usefcntl(fd, F_SETFL, flags)Set whether to block the connection.

O_NONBLOCKThat is, the Socket is not blocked, but it is still synchronized.

In fact, hiredis uses non-blocking (poll) Methods no matter whether it is blocked or not.connectWhen you connect to the server,-1 is returned anderrnoIsEINPROGRESS, Which is normal in non-blocking mode. Why is the blocking mode forced to use non-blocking?pollConnection? To support the timeout function. After the connection is successful, hiredis is reset to blocking or non-blocking mode as required.

For details about how to design the timeout function, refer to http://blog.csdn.net/ast_224/article/details/2957294.

Command

Using va_list to solve the problem of variable parameters (C also supports variable-length parameters, and I was shocked. I was really C blind ).

int redisFormatCommand(char **target, const char *format, ...) {    va_list ap;    int len;    va_start(ap,format);}

redisvCommandUsed to execute the Redis blocking command. It will call__redisBlockForReply, Internal callredisBufferWriteWrite the buffer from the socket, and then wait synchronously.redisBufferReadRead data,redisGetReplyFromReaderParse the returned data.

Asynchronous connection

The code for asynchronous calling is inasync.c.

The important structure isredisAsyncContextAndredisAeEventsThe important method of the former is to register the callback function:addRead/delRead/addWrite/delWriteThe latter is used to store loop/fd/event stream.

During asynchronous connectionredisContextConnectTcpNon-blocking connection to the server.

UseaeCreateEventLoopCreate an event loop and then useredisAeAttachTocontextRegister events, suchaeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e)RegisterreadEvent, and set the callback callredisAeReadEvent,redisAeReadEventThen host this eventredisAsyncHandleRead(Defined in async. c and called by three event libraries ).

Therefore, hiredis uses the adapter encapsulation to shield the API differences between AE, libevent, and libev, so that you can choose flexibly. It is said that AE was rewritten from two libevent libraries, but I think the style of AE is similar to that of libev, while the style of libevent is better understood.

If we compare the complexity of the Code with the IOLoop of Tornado, we can see that the API encapsulation of Tornado is too user-friendly, and the code of C is complicated to write, system APIs, resource control, and error control are all troublesome.

For details about the Redis AE event library, refer to http://my.oschina.net/u/917596/blog/16107720.osc_h4_6. Libevent a simple tutorial http://www.wangafu.net /~ Nickm/libevent-book/01_intro.html.

About C

As a C scum, I barely read hiredis. I feel that the C foundation is not enough. I will list some of the doubts in the learning process:

  • IFDEFUse, can prevent repeated import of the same head file definition, here there is a detailed explanation http://faculty.cs.niu.edu /~ Mcmahon/CS241/c241man/node90.html
  • __cplusplus: C ++ defines this variable, but C does not. Therefore, when the C ++ compiler recognizes the sourceifdefTo useexternCompile C code.
  • Long: long can only store 32 bits. long can store 64 bits, that is, 0-2 ^ 64-1.
  • c->flags |= REDIS_BLOCK/c->flags &= ~REDIS_BLOCK;Simple bit operations.
  • Sds (simple dynamic string) is a C String structure implemented by Redis itself.
  • ((void)fd)It seems that the fd pointer is converted to a non-typed pointer, and it is of no use.

Link: http://blog.log4d.com/2014/03/hiredis/
3a1ff193cee606bd1e2ea554a16316ee

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.