Skip to content

Latest commit

 

History

History
377 lines (303 loc) · 11.3 KB

README.md

File metadata and controls

377 lines (303 loc) · 11.3 KB

redis-plus-plus-modules

Introduction

This library aims to supply a C++ interface to all major/popular Redis modules. It uses redis-plus-plus, which in turn uses hiredis.

The following Redis Modules are fully implemented:

The following Redis Modules are in the process of being implemented:

Motivation

After using redis-plus-plus for a while, one simply gets addicted to the ease of having proper interfaces to Redis commands. These interfaces save a lot of boiler-plate code and therefore a lot of time, and that's why I decided to write this library.

Design

The goal of this library is to use redis-plus-plus and hiredis with no modification. These two projects are included as git submodules and are built as part of the final redis-plus-plus-modules library.

redis-plus-plus-modules is a C++ library in the form of C++ headers, containing C++ template classes. This means that there is no library to link with. The only requirement is that one or more of the desired header files are included:

This Class Diagram was generated by Doxygen: Class Diagram, generated with Doxygen

Building

GNU/Automake is used as building tool and g++ is used for building.

git clone https://github.com/wingunder/redis-plus-plus-modules.git
cd redis-plus-plus-modules
./bootstrap.sh
./configure
make -j8

Tests can be performed by running:

make test

Quickstart

Quickstart using Docker

The fastest way to get started, is to simply use Docker and docker-compose. A Dockerfile and a simple docker-compose.yml file is supplied.

Optionally you could start off, by building the Docker image called rppm (short for redis-plus-plus-modules). This step is not needed, but just demostrates that building a pure Docker image of this library is possible.

$ docker build . -t rppm:0

For running applications inside Docker, you need to use docker-compose. The following demonstrates the running of the unit tests and some examples, inside Docker.

$ docker-compose up -d
Starting redis-plus-plus-modules_redis_1 ... done
Starting redis-plus-plus-modules_test_1       ... done
Creating redis-plus-plus-modules_multi_info_1  ... done
Creating redis-plus-plus-modules_single_info_1 ... done

To view the logs of the test example, simply run:

$ docker-compose logs test

To view the logs of the singleInfo example, simply run:

$ docker-compose logs single_info
Attaching to redis-plus-plus-modules_single_info_1
single_info_1  | make: Entering directory
'/usr/src/redis-plus-plus-modules/examples/singleInfo'
single_info_1  | g++ -I../../include -L../../lib -o singleInfo
singleInfo.cpp -lhiredis -lredis++ -lpthread
single_info_1  | make: Leaving directory
'/usr/src/redis-plus-plus-modules/examples/singleInfo'
single_info_1  | Expansion rate: 2
single_info_1  | Number of items inserted: 0
single_info_1  | Capacity: 100
single_info_1  | Number of filters: 1
single_info_1  | Size: 232

To view the logs of the multiInfo example, simply run:

$ docker-compose logs multi_info
Attaching to redis-plus-plus-modules_multi_info_1
multi_info_1   | make: Entering directory
'/usr/src/redis-plus-plus-modules/examples/multiInfo'
multi_info_1   | g++ -I../../include -L../../lib -o multiInfo
multiInfo.cpp -lhiredis -lredis++ -lpthread
multi_info_1   | make: Leaving directory
'/usr/src/redis-plus-plus-modules/examples/multiInfo'
multi_info_1   | Expansion rate: 2
multi_info_1   | Number of items inserted: 0
multi_info_1   | Capacity: 100
multi_info_1   | Number of filters: 1
multi_info_1   | Size: 232
multi_info_1   | Max iterations: 0
multi_info_1   | Expansion rate: 1
multi_info_1   | Number of buckets: 16
multi_info_1   | Number of filters: 1
multi_info_1   | Number of items inserted: 0
multi_info_1   | Number of items deleted: 0
multi_info_1   | Size: 216
multi_info_1   | Bucket size: 10

You can now use the docker-compose.yml file and beef it up with your own application(s).

Quickstart without using Docker

First of all you'll need to have access to a Redis database with the loaded module(s) that you'd like to program against.

Once your Redis database is set up and running, you can run the MODULE LIST command on it, in order to see if the modules are available:

$ redis-cli MODULE LIST
1) 1) "name"
   2) "ai"
   3) "ver"
   4) (integer) 10002
2) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) (integer) 10007
3) 1) "name"
   2) "bf"
   3) "ver"
   4) (integer) 20205
4) 1) "name"
   2) "search"
   3) "ver"
   4) (integer) 20006
5) 1) "name"
   2) "timeseries"
   3) "ver"
   4) (integer) 10408
6) 1) "name"
   2) "rg"
   3) "ver"
   4) (integer) 10006
7) 1) "name"
   2) "graph"
   3) "ver"
   4) (integer) 20402

In the above example, 7 modules are available. The 3rd module, BloomFilter (bf), supplies BloomFilter (BF), CuckooFilter (CF), Count-Min-Sketch (CMS) and Top-K (TOPK).

The ./test directory contains test cases for all implemented API calls. In order to run the tests, simply run:

make test

If you have gotten this far and the test succeeded, we can continue with a simple example. For the impatient, just look at this example and the other examples in the examples directory.

We're going to create a Redis instance, using redis-plus-plus:

#include <iostream>
#include <redismods++/BloomFilter.h>

int main() {

    // Setup the connection options.
    sw::redis::ConnectionOptions opts;
    opts.host = "127.0.0.1";
    opts.port = 6379;
    opts.password = "";

    // Choose the instance type.
    using RedisInstance = sw::redis::Redis;
    // use RedisInstance = sw::redis::RedisCluster;

    // Create a redis-plus-plus object.
    RedisInstance redis(opts);

    // Create a BloomFilter object.
    redis::module::BloomFilter<RedisInstance> bloomFilter(redis);

    getInfo<RedisInstance>("some_test_key", bloomFilter, redis);

    return 0;
}

Now we'll implement the getInfo() template function. BTW, it needs to be a template function, as we're keeping the option open to use it on non-clustered, as well as clustered Redis servers.

#include <unordered_map>

template <typename RedisInstance>
void
getInfo(const std::string &key,
        redis::module::BloomFilter<RedisInstance> &bloomFilter,
        RedisInstance &redis)
{
    // Make sure the key does not exist.
    // Note: The BloomFilter object does not have a 'del' call,
    //       so we need to call the native redis 'DEL' command
    //       via the underlying redis-plus-plus lib.
    redis.del(key);

    // Create a BloomFilter.
    bloomFilter.reserve(key, 0.1, 100, false);

    // Prepare the output buffer.
    std::unordered_map<std::string, sw::redis::OptionalLongLong> output;
    bloomFilter.info(key, output);

    // Print the result.
    for (auto &item : output) {
        std::cout << item.first << ": ";
        if (item.second) {
            std::cout << *item.second;
        }
        else {
            std::cout << "nil";
        }
        std::cout << std::endl;
    }

    // Clean up.
    redis.del(key);
}

We now need to compile it. Note that we need to link with the hiredis, redis++ and pthread libraries. The hiredis and redis++ libraries are installed in the ${REDIS_PLUS_PLUS_MODULES_DIR}/lib directory. All include files are in the ${REDIS_PLUS_PLUS_MODULES_DIR}/include directory.

$ g++ -I${REDIS_PLUS_PLUS_MODULES_DIR}/include -L${REDIS_PLUS_PLUS_MODULES_DIR}/lib -o singleInfo singleInfo.cpp -lhiredis -lredis++ -lpthread

Finally, we can run it:

$ LD_LIBRARY_PATH=$REDIS_PLUS_PLUS_MODULES_DIR/lib ./singleInfo
Expansion rate: 2
Number of items inserted: 0
Size: 232
Number of filters: 1
Capacity: 100

Code Documentation

A Doxygen configuration file, DoxyFile is included, so you can simply install Doxygen and run it:

$ doxygen

The above should create an html and latex directory, where you can find the generated Doxygen output files.

APIs

NOTE: This project is still under heavy development. Although a lot of effort will go into keeping the API stable, it is not guaranteed.

RedisBloom API Documentation

TODO

  • Finish the RedisGraph implementation
  • Clean-up API and release the first version
  • Add APIs for: RediSearch, RedisTimeSeries, RedisAI and RedisGears
  • Install procedure and at least a Debian package

Contributing

Contributions are very welcome. Also please feel free to open issues and post reviews.

Authors

The initial version of redis-plus-plus-modules was written by wingunder. Some ideas and code originate from sewenew and his amazing redis-plus-plus library.

Copyright

This software is copyrighted under Apache License V2.0.

History

This project was started during the RedisConf 2021 hackathlon.

Links