Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7728625
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T05:45:55+00:00 2026-06-01T05:45:55+00:00

I want get as much as possible from Redis + Hiredis + libevent. I’m

  • 0

I want get as much as possible from Redis + Hiredis + libevent.

I’m using following code (without any checks to be short)

#include <stdlib.h>
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer.h>
#include <hiredis/hiredis.h>
#include <hiredis/async.h>
#include <hiredis/adapters/libevent.h>

typedef struct reqData {
  struct evhttp_request* req;
  struct evbuffer* buf;
} reqData;

struct event_base* base;
redisAsyncContext* c;

void get_cb(redisAsyncContext* context, void* r, void* data) {
  redisReply* reply = r;
  struct reqData* rd = data;

  evbuffer_add_printf(rd->buf, "%s", reply->str);
  evhttp_send_reply(rd->req, HTTP_OK, NULL, rd->buf);

  evbuffer_free(rd->buf);
  redisAsyncDisconnect(context);
}

void cb(struct evhttp_request* req, void* args) {
  struct evbuffer* buf;
  buf = evbuffer_new();

  reqData* rd = malloc(sizeof(reqData));
  rd->req = req;
  rd->buf = buf;

  c = redisAsyncConnect("0.0.0.0", 6380);
  redisLibeventAttach(c, base);

  redisAsyncCommand(c, get_cb, rd, "GET name");
}

int main(int argc, char** argv) {
  struct evhttp* http;
  struct evhttp_bound_socket* sock;

  base = event_base_new();
  http = evhttp_new(base);
  sock = evhttp_bind_socket_with_handle(http, "0.0.0.0", 8080);

  evhttp_set_gencb(http, cb, NULL);

  event_base_dispatch(base);

  evhttp_free(http);
  event_base_free(base);
  return 0;
}

To compile, use gcc -o main -levent -lhiredis main.c assuming libevent, redis and hiredis in system.

I curious when I need to do redisAsyncConnect? In main() once or (as example shows) in every callback. Is there anything I can do to boost performance?

I’m getting about 6000-7000 req/s. Using ab to benchmark this, stuff complicates when trying big numbers (e.g. 10k reqs) – it cannot complete benchmark and freezes. Doing the same thing but in blocking way the results are 5000-6000 req/s.

I’ve extended max file open by limit -n 10000. I’m using Mac OS X Lion.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T05:45:56+00:00Added an answer on June 1, 2026 at 5:45 am

    It is of course much better to open the Redis connection once, and try to reuse it as far as possible.

    With the provided program, I suspect the benchmark freezes because the number of free ports in the ephemeral port range is exhausted. Each time a new connection to Redis is opened and closed, the corresponding socket spends some time in TIME_WAIT mode (this point can be checked using the netstat command). The kernel cannot recycle them fast enough. When you have too many of them, no further client connection can be initiated.

    You also have a memory leak in the program: the reqData structure is allocated for each request, and never deallocated. A free is missing in get_cb.

    Actually, there are 2 possible sources of TIME_WAIT sockets: the ones used for Redis, and the ones opened by the benchmark tool to connect to the server. Redis connections should be factorized in the program. The benchmark tool must be configured to use HTTP 1.1 and keepalived connections.

    Personally, I prefer to use siege over ab to run this kind of benchmark. ab is considered as a naive tool by most people interested in benchmarking HTTP servers.

    On my old Linux PC, the initial program, run against siege in benchmark mode with 50 keepalived connections, results in:

    Transaction rate:            3412.44 trans/sec
    Throughput:                     0.02 MB/sec
    

    When we remove completely the call to Redis, only returning a dummy result, we get:

    Transaction rate:            7417.17 trans/sec
    Throughput:                     0.04 MB/sec
    

    Now, let’s modify the program to factorize the Redis connection, and naturally benefit from pipelining. The source code is available here. Here is why we get:

    Transaction rate:            7029.59 trans/sec
    Throughput:                     0.03 MB/sec
    

    In other words, by removing the systematic connection/disconnection events, we can achieve twice the throughput. The performance with the Redis call is not so far than the performance
    we get without any Redis call.

    To further optimize, you could consider using a unix domain socket between your server and Redis, and/or pool the dynamically allocated objects to reduce CPU consumption.

    UPDATE:

    To experiment with a unix domain socket, it is straightforward: you just have to activate the support in Redis itself by updating the configuration file:

    # Specify the path for the unix socket that will be used to listen for
    # incoming connections. There is no default, so Redis will not listen
    # on a unix socket when not specified.
    #
    unixsocket /tmp/redis.sock
    unixsocketperm 755
    

    and then replace the connection function:

    c = redisAsyncConnect("0.0.0.0", 6379);
    

    by:

    c = redisAsyncConnectUnix("/tmp/redis.sock");
    

    Note: here, hiredis async does a good job at pipelining the commands (provided the connection is permanent), so the impact will be low.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got the following code that get's a URL parameter, selects an option from
I want to get show information from myspace artists. One way I could do
I want to get the first paragraph of a Wikipedia article. So i'm using
I'm using C#, winforms. Got a small problem. I've debugged as much as possible
I want get the time used for a case so I can create an
I want get all of the Geom objects that are related to a certain
I just want get a 2 dimension array of List in c#. In my
I want to get the top #nr_of_rows - (int)(#nr_of_rows / 10 - 1) of
I want to get myself into programming some serious GUI based applications, but when
I want to get print out invoice but also wanna set margins and page

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.