SlideShare a Scribd company logo
Redis Modules API
Itamar Haber @itamarhaber
Evangely Technicalist
● A way to extend Redis with native code/libraries
● For compiling dynamically loaded libraries
● Distributed as a C header file (redismodule.h)
● C++ and Rust are easily possible, others perhaps
● ABI backwards compatible
● An isolated interface, decoupled from internals
● Made of a high-level API, and the low-level APIs
● Available as of v4
The Redis Module API in a nutshell is
Who We Are
Open source. The leading in-memory database platform,
supporting any high performance operational, analytics or
hybrid use case.
The open source home and commercial provider of Redis
Enterprise (Redise
) technology, platform, products & services.
Itamar Haber @itamarhaber, Evangely Technicalist, formerly
Chief Developer Advocate & Chief OSS Education Officerhello I am
No
The Decision Chart: when to develop a module
Gave serious
thought about
what you need
to solve?
Is there a core
Redis capability
that does it?
Do that!
Can you do it in
the app?
Is Lua good
enough?
Is there an
existing GA
module that
already does it?
Yes
No
No No
Honestly
factored cost of
taking on a new
software
project?
Yes Yes Yes
No
Is it a valid
feature request
to the core?
Yes
Yes
No
mebi
Roll
out
your
own
Try that first.
Hackers love
helping each
other 3:-)
ctx is the call's context.
argv and argc are the arguments and their count.
A module is a C file with commands
#include "redismodule.h"
int MyCommand(RedisModuleCtx *ctx,
RedisModuleString **argv, int argc) {
// My code here
// ...
return REDISMODULE_OK;
}
Redis Modules API - an introduction
Will yield a standard error when condition is met.
Implementing the ZPOP command
/**
ZPOP <key>
*/
int ZPop(RedisModuleCtx *ctx,
RedisModuleString **argv, int argc) {
if (argc != 2) {
RedisModule_WrongArity(ctx);
return REDISMODULE_OK;
}
Off by default, turn on by calling before the return.
Automatically keeps track of things like opened keys,
allocated high level API and Redis objects.
Frees everything after the call to function returns, so you
don't have to.
Activate AutomajikMemory
RedisModule_AutoMemory(ctx);
Performing a call to Redis via the high-level API
RedisModuleCallReply *rep = RedisModule_Call(ctx,
"ZRANGE", "!sllc", argv[1], 0, 0, "WITHSCORES");
if (RedisModule_CallReplyType(rep) ==
REDISMODULE_REPLY_ERROR) {
RedisModule_ReplyWithCallReply(ctx, rep);
return REDISMODULE_OK;
}
• vis a vis Lua's redis.call()
• Variadic arguments via printf format-style
• "!..." means don't replicate to AOF and/or slaves
• RedisModule_Replicate() is exactly like
RedisModule_Call(), only that it replicates rather
than actually calling the command
RedisModule_Call()
Extract the element, a call to ZREM & reply
RedisModuleString *ele =
RedisModule_CreateStringFromCallReply(
RedisModule_CallReplyArrayElement(arr, 0));
RedisModule_Call(ctx, "ZREM", "ss",
key, ele);
RedisModule_ReplyWithCallReply(ctx, rep);
int ZPop(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
if (argc != 2) {
RedisModule_WrongArity(ctx);
return REDISMODULE_OK;
}
RedisModule_AutoMemory(ctx);
RedisModuleCallReply *rep = RedisModule_Call(
ctx, "ZRANGE", "!sllc", argv[1], 0, 0, "WITHSCORES");
if (RedisModule_CallReplyType(rep) == REDISMODULE_REPLY_ERROR) {
RedisModule_ReplyWithCallReply(ctx, rep);
return REDISMODULE_OK;
}
RedisModuleString *ele =
RedisModule_CreateStringFromCallReply(
RedisModule_CallReplyArrayElement(arr, 0));
RedisModule_Call(ctx, "ZREM", "ss", key, ele);
RedisModule_ReplyWithCallReply(ctx, rep);
return REDISMODULE_OK;
}
// Registering the module and its commands
int RedisModule_OnLoad(RedisModuleCtx *ctx,
RedisModuleString **argv, int argc) {
if (RedisModule_Init(ctx, "example", 1,
REDISMODULE_APIVER_1) == REDISMODULE_ERR) {
return REDISMODULE_ERR;
}
if (RedisModule_CreateCommand(ctx,
"example.zpop", ZPop, "Write", 1, 1, 1) ==
REDISMODULE_ERR) {
return REDISMODULE_ERR;
}
return REDISMODULE_OK;
}
# Compile it on Linux:
$ gcc -fPIC -std=gnu99 -c -o zpop.o zpop.c
$ ld -o zpop.so zpop.o -shared -Bsymbolic -lc
# Compile it on OSX:
$ gcc -dynamic -fno-common -std=gnu99 -c -o zpop.o zpop.c
$ ld -o zpop.so zpop.o -bundle -undefined dynamic_lookup
-lc
# Run it:
$ redis-server --loadmodule ./zpop.so
# Use it:
$ redis-cli
redis> ZADD z 0 a 1 b 3 c
(integer) 3
redis> EXAMPLE.ZPOP z
"a"
That's almost it.
There are several other lower-level functions to deal with
examining, extracting from and iterating over the
RedisModule_CallReply type.
It is easy to use the high-level API, and it can invoke (almost)
any Redis command.
And it is not that slow. Where did you hear that? :)
How high can you get?
The low-level APIs provide more and some less exciting
capabilities.
For example, RedisModule_WrongArity() belongs to
the low level API. It is just helper for replying with standard
error.
But since it has nothing to do with RedisModule_Call(),
it is considered "low-level".
The Low-level APIs
● RedisModule_ReplyWith*
● Common keyspace, e.g. RedisModule_DeleteKey()
● Memory management, non-automatic
● RedisModuleString API
● Hash operations (RedisModule_HashGet(), HashSet())
● Sorted Set operations, including range iteration
● Replication control
● Module unload hook (experimental)
Some "groups" of the low-level APIs
● String Direct Memory Access (DMA)
● Blocking commands (a-la BLPOP)
● Callback on keyspace notifications (triggers, WAT?!?)
● Threading API (put them extra 31 cores to use)
● Key locking API (ATM in experimentational state)
● Cluster API (planned)
● @antirez' current goal - make the API robust enough for
implementing Disque as a module <- that's good enough
for me:)
The lower it gets, the cooler it becomes
Do/don't use RedisModule_ReplicateVerbatim()
and/or RedisModule_Replicate()
Call RedisModule_CreateDataType()
The custom data type API
void MyTypeLoad(RedisModuleIO *rdb, int encver);
void MyTypeSave(RedisModuleIO *rdb, void *value);
void MyTypeRewrite(RedisModuleIO *aof,
RedisModuleString *key, void *value);
size_t MyTypeMemUsage(const void *value);
void MyTypeFree(void *value);
● Deep dive into low-level APIs
● How to debug with gdb/lldb
● How to write unit/integration tests
● Calling module commands from clients
Do not fear though! Most is available in the documentation,
existing modules repos and online.
Also, check out ze module: github.com/itamarhaber/zpop
So much more important stuff left to cover...
You can get started with a template HGETSET project, a
skeleton makefile and a bunch of make-my-life-easier
utilities, simply by cloning:
https://github.com/RedisLabs/RedisModulesSDK
The Modules SDK
Redis Modules API - an introduction
:

More Related Content

PDF
Introduction to Redis
PDF
Redis v5 & Streams
PDF
Redis Lua Scripts
PDF
Redis vs Infinispan | DevNation Tech Talk
PDF
RESTLess Design with Apache Thrift: Experiences from Apache Airavata
PDF
Boosting Machine Learning with Redis Modules and Spark
PDF
Postgres clusters
ODP
HornetQ Presentation On JBoss World 2009
Introduction to Redis
Redis v5 & Streams
Redis Lua Scripts
Redis vs Infinispan | DevNation Tech Talk
RESTLess Design with Apache Thrift: Experiences from Apache Airavata
Boosting Machine Learning with Redis Modules and Spark
Postgres clusters
HornetQ Presentation On JBoss World 2009

What's hot (20)

PDF
The basics of fluentd
PDF
Type safe, versioned, and rewindable stream processing with Apache {Avro, K...
PDF
Dynamic pricing of Lyft rides using streaming
PDF
Redis cluster
PDF
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
PDF
Java features. Java 8, 9, 10, 11
PDF
Python Streaming Pipelines on Flink - Beam Meetup at Lyft 2019
PDF
Dive into Fluentd plugin v0.12
ODP
Gsummit apis-2013
PDF
HBaseCon2017 gohbase: Pure Go HBase Client
PDF
Streaming your Lyft Ride Prices - Flink Forward SF 2019
PDF
Ekon24 mORMot 2
PDF
Distributed Postgres
PDF
Managing terabytes: When Postgres gets big
KEY
Everything I Ever Learned About JVM Performance Tuning @Twitter
PDF
Kafka Summit SF 2017 - Shopify Flash Sales with Apache Kafka
PPTX
Ceph at Work in Bloomberg: Object Store, RBD and OpenStack
PPTX
HBaseCon 2015: OpenTSDB and AsyncHBase Update
PDF
Cassandra Explained
PDF
Fluentd Project Intro at Kubecon 2019 EU
The basics of fluentd
Type safe, versioned, and rewindable stream processing with Apache {Avro, K...
Dynamic pricing of Lyft rides using streaming
Redis cluster
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Java features. Java 8, 9, 10, 11
Python Streaming Pipelines on Flink - Beam Meetup at Lyft 2019
Dive into Fluentd plugin v0.12
Gsummit apis-2013
HBaseCon2017 gohbase: Pure Go HBase Client
Streaming your Lyft Ride Prices - Flink Forward SF 2019
Ekon24 mORMot 2
Distributed Postgres
Managing terabytes: When Postgres gets big
Everything I Ever Learned About JVM Performance Tuning @Twitter
Kafka Summit SF 2017 - Shopify Flash Sales with Apache Kafka
Ceph at Work in Bloomberg: Object Store, RBD and OpenStack
HBaseCon 2015: OpenTSDB and AsyncHBase Update
Cassandra Explained
Fluentd Project Intro at Kubecon 2019 EU
Ad

Similar to Redis Modules API - an introduction (20)

PDF
Redis modules 101
PPTX
Developing a Redis Module - Hackathon Kickoff
PDF
Extend Redis with Modules
PDF
How I Implemented the #1 Requested Feature In Redis In Less than 1 Hour with ...
PDF
Fun with Ruby and Redis
PDF
Writing Redis Module with Rust
PPTX
A Quantitative Trader's Perspective
PDF
Redispresentation apac2012
PDF
A Brief Introduction to Redis
PDF
Spark Summit EU talk by Shay Nativ and Dvir Volk
PPTX
RediSearch Mumbai Meetup 2020
PDF
Memory Management Made Simple: Kevin Mcghee, Madelyn Olson
PDF
Paris Redis Meetup Introduction
PPT
Python redis talk
PPTX
Introduction to Redis
PPTX
Redis Modules - Redis India Tour - 2017
PDF
Por que deberias haberle pedido redis a los reyes magos
PPTX
Get more than a cache back! - ConFoo Montreal
PDF
How you can benefit from using Redis - Ramirez
PDF
Tuga IT 2017 - Redis
Redis modules 101
Developing a Redis Module - Hackathon Kickoff
Extend Redis with Modules
How I Implemented the #1 Requested Feature In Redis In Less than 1 Hour with ...
Fun with Ruby and Redis
Writing Redis Module with Rust
A Quantitative Trader's Perspective
Redispresentation apac2012
A Brief Introduction to Redis
Spark Summit EU talk by Shay Nativ and Dvir Volk
RediSearch Mumbai Meetup 2020
Memory Management Made Simple: Kevin Mcghee, Madelyn Olson
Paris Redis Meetup Introduction
Python redis talk
Introduction to Redis
Redis Modules - Redis India Tour - 2017
Por que deberias haberle pedido redis a los reyes magos
Get more than a cache back! - ConFoo Montreal
How you can benefit from using Redis - Ramirez
Tuga IT 2017 - Redis
Ad

More from Itamar Haber (11)

PDF
Redis Streams - Fiverr Tech5 meetup
PDF
Leveraging Probabilistic Data Structures for Real Time Analytics with Redis M...
PDF
Power to the People: Redis Lua Scripts
PDF
What's new in Redis v3.2
PPTX
Redis Developers Day 2015 - Secondary Indexes and State of Lua
PDF
Use Redis in Odd and Unusual Ways
PPTX
Why Your MongoDB Needs Redis
PPTX
Redis & MongoDB: Stop Big Data Indigestion Before It Starts
PPTX
Benchmarking Redis by itself and versus other NoSQL databases
PPTX
Redis Indices (#RedisTLV)
PPTX
Redis Use Patterns (DevconTLV June 2014)
Redis Streams - Fiverr Tech5 meetup
Leveraging Probabilistic Data Structures for Real Time Analytics with Redis M...
Power to the People: Redis Lua Scripts
What's new in Redis v3.2
Redis Developers Day 2015 - Secondary Indexes and State of Lua
Use Redis in Odd and Unusual Ways
Why Your MongoDB Needs Redis
Redis & MongoDB: Stop Big Data Indigestion Before It Starts
Benchmarking Redis by itself and versus other NoSQL databases
Redis Indices (#RedisTLV)
Redis Use Patterns (DevconTLV June 2014)

Recently uploaded (20)

PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Machine learning based COVID-19 study performance prediction
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPT
Teaching material agriculture food technology
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Cloud computing and distributed systems.
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
Network Security Unit 5.pdf for BCA BBA.
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Advanced methodologies resolving dimensionality complications for autism neur...
Building Integrated photovoltaic BIPV_UPV.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
The Rise and Fall of 3GPP – Time for a Sabbatical?
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Machine learning based COVID-19 study performance prediction
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Teaching material agriculture food technology
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Cloud computing and distributed systems.
Encapsulation_ Review paper, used for researhc scholars
Understanding_Digital_Forensics_Presentation.pptx
NewMind AI Weekly Chronicles - August'25 Week I
Review of recent advances in non-invasive hemoglobin estimation
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Per capita expenditure prediction using model stacking based on satellite ima...

Redis Modules API - an introduction

  • 1. Redis Modules API Itamar Haber @itamarhaber Evangely Technicalist
  • 2. ● A way to extend Redis with native code/libraries ● For compiling dynamically loaded libraries ● Distributed as a C header file (redismodule.h) ● C++ and Rust are easily possible, others perhaps ● ABI backwards compatible ● An isolated interface, decoupled from internals ● Made of a high-level API, and the low-level APIs ● Available as of v4 The Redis Module API in a nutshell is
  • 3. Who We Are Open source. The leading in-memory database platform, supporting any high performance operational, analytics or hybrid use case. The open source home and commercial provider of Redis Enterprise (Redise ) technology, platform, products & services. Itamar Haber @itamarhaber, Evangely Technicalist, formerly Chief Developer Advocate & Chief OSS Education Officerhello I am
  • 4. No The Decision Chart: when to develop a module Gave serious thought about what you need to solve? Is there a core Redis capability that does it? Do that! Can you do it in the app? Is Lua good enough? Is there an existing GA module that already does it? Yes No No No Honestly factored cost of taking on a new software project? Yes Yes Yes No Is it a valid feature request to the core? Yes Yes No mebi Roll out your own Try that first. Hackers love helping each other 3:-)
  • 5. ctx is the call's context. argv and argc are the arguments and their count. A module is a C file with commands #include "redismodule.h" int MyCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { // My code here // ... return REDISMODULE_OK; }
  • 7. Will yield a standard error when condition is met. Implementing the ZPOP command /** ZPOP <key> */ int ZPop(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc != 2) { RedisModule_WrongArity(ctx); return REDISMODULE_OK; }
  • 8. Off by default, turn on by calling before the return. Automatically keeps track of things like opened keys, allocated high level API and Redis objects. Frees everything after the call to function returns, so you don't have to. Activate AutomajikMemory RedisModule_AutoMemory(ctx);
  • 9. Performing a call to Redis via the high-level API RedisModuleCallReply *rep = RedisModule_Call(ctx, "ZRANGE", "!sllc", argv[1], 0, 0, "WITHSCORES"); if (RedisModule_CallReplyType(rep) == REDISMODULE_REPLY_ERROR) { RedisModule_ReplyWithCallReply(ctx, rep); return REDISMODULE_OK; }
  • 10. • vis a vis Lua's redis.call() • Variadic arguments via printf format-style • "!..." means don't replicate to AOF and/or slaves • RedisModule_Replicate() is exactly like RedisModule_Call(), only that it replicates rather than actually calling the command RedisModule_Call()
  • 11. Extract the element, a call to ZREM & reply RedisModuleString *ele = RedisModule_CreateStringFromCallReply( RedisModule_CallReplyArrayElement(arr, 0)); RedisModule_Call(ctx, "ZREM", "ss", key, ele); RedisModule_ReplyWithCallReply(ctx, rep);
  • 12. int ZPop(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc != 2) { RedisModule_WrongArity(ctx); return REDISMODULE_OK; } RedisModule_AutoMemory(ctx); RedisModuleCallReply *rep = RedisModule_Call( ctx, "ZRANGE", "!sllc", argv[1], 0, 0, "WITHSCORES"); if (RedisModule_CallReplyType(rep) == REDISMODULE_REPLY_ERROR) { RedisModule_ReplyWithCallReply(ctx, rep); return REDISMODULE_OK; } RedisModuleString *ele = RedisModule_CreateStringFromCallReply( RedisModule_CallReplyArrayElement(arr, 0)); RedisModule_Call(ctx, "ZREM", "ss", key, ele); RedisModule_ReplyWithCallReply(ctx, rep); return REDISMODULE_OK; }
  • 13. // Registering the module and its commands int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (RedisModule_Init(ctx, "example", 1, REDISMODULE_APIVER_1) == REDISMODULE_ERR) { return REDISMODULE_ERR; } if (RedisModule_CreateCommand(ctx, "example.zpop", ZPop, "Write", 1, 1, 1) == REDISMODULE_ERR) { return REDISMODULE_ERR; } return REDISMODULE_OK; }
  • 14. # Compile it on Linux: $ gcc -fPIC -std=gnu99 -c -o zpop.o zpop.c $ ld -o zpop.so zpop.o -shared -Bsymbolic -lc # Compile it on OSX: $ gcc -dynamic -fno-common -std=gnu99 -c -o zpop.o zpop.c $ ld -o zpop.so zpop.o -bundle -undefined dynamic_lookup -lc # Run it: $ redis-server --loadmodule ./zpop.so # Use it: $ redis-cli redis> ZADD z 0 a 1 b 3 c (integer) 3 redis> EXAMPLE.ZPOP z "a"
  • 15. That's almost it. There are several other lower-level functions to deal with examining, extracting from and iterating over the RedisModule_CallReply type. It is easy to use the high-level API, and it can invoke (almost) any Redis command. And it is not that slow. Where did you hear that? :) How high can you get?
  • 16. The low-level APIs provide more and some less exciting capabilities. For example, RedisModule_WrongArity() belongs to the low level API. It is just helper for replying with standard error. But since it has nothing to do with RedisModule_Call(), it is considered "low-level". The Low-level APIs
  • 17. ● RedisModule_ReplyWith* ● Common keyspace, e.g. RedisModule_DeleteKey() ● Memory management, non-automatic ● RedisModuleString API ● Hash operations (RedisModule_HashGet(), HashSet()) ● Sorted Set operations, including range iteration ● Replication control ● Module unload hook (experimental) Some "groups" of the low-level APIs
  • 18. ● String Direct Memory Access (DMA) ● Blocking commands (a-la BLPOP) ● Callback on keyspace notifications (triggers, WAT?!?) ● Threading API (put them extra 31 cores to use) ● Key locking API (ATM in experimentational state) ● Cluster API (planned) ● @antirez' current goal - make the API robust enough for implementing Disque as a module <- that's good enough for me:) The lower it gets, the cooler it becomes
  • 19. Do/don't use RedisModule_ReplicateVerbatim() and/or RedisModule_Replicate() Call RedisModule_CreateDataType() The custom data type API void MyTypeLoad(RedisModuleIO *rdb, int encver); void MyTypeSave(RedisModuleIO *rdb, void *value); void MyTypeRewrite(RedisModuleIO *aof, RedisModuleString *key, void *value); size_t MyTypeMemUsage(const void *value); void MyTypeFree(void *value);
  • 20. ● Deep dive into low-level APIs ● How to debug with gdb/lldb ● How to write unit/integration tests ● Calling module commands from clients Do not fear though! Most is available in the documentation, existing modules repos and online. Also, check out ze module: github.com/itamarhaber/zpop So much more important stuff left to cover...
  • 21. You can get started with a template HGETSET project, a skeleton makefile and a bunch of make-my-life-easier utilities, simply by cloning: https://github.com/RedisLabs/RedisModulesSDK The Modules SDK
  • 23. :