Hello World

It's time for a whirlwind tour of Redis before you dive into the rest of the book!

Overview: Redis

Versatile Key-Value store

The beauty of Redis is that it's a key-value store where keys are Strings but the values are data structures. Here is a list

  • String - A simple data type which can be used as a key as well as a value

  • List - Used as a ordered data store as well as a queue

  • Hash - Modeled as a collection of key-value pairs which makes it similar to a Map data structure (in any programming language)

  • Set - A Set in Redis is just like its mathemaical counterpart - stores unique and unordered entries

  • Sorted Set - It is just like a set, except for the fact that each element has an associated score (floating point)

  • Geo - The data type to use when you want to work with geo location (in terms of latitude and longitude)

  • Hyperloglog - A simple yet very efficient data structure to count unique items

  • Streams - It's similar to append-only-log and allows you to consume and process unbounded data sets

Core capabilities

It doesn't end with the data structures!

  • PubSub - Redis Channels provide decoupled, asynchornous, one-to-many messaging pattern with the help of commands such as PUBLISH, SUBSCRIBE, UNSUBSCRIBE etc.

  • Pipeline and Transactions - Use Pipelining to send multiple commands at once therby offset network latency (of sending individual commands). Transactions (using MULTI and EXEC) are a strategy to execute a set of commands atomically. They can be cancelled using DISCARD (Redis does not support rolbacks) and optimistic locking is supported using WATCH, UNWATCH

  • Stream Processing - As mentioned above, this is powered by the Streams data type

  • Redis Modules - Modules provide the ability to extend Redis and develop custom data structures/commands

  • Lua scripting - Redis gives you the ability to xecute Lua scripts inside it, thanks to the inbuilt Lua interpreter

  • Replication - Redis provides Master-Slave replication capability which is asynchronous by default

  • Persistence - Redis also provides you the ability to persist data on disk using tunable persistence mechanisms - RDB (periodic snapshots), AOF (save data on each modification) or a combination of both

  • High Availability - Automated failover is made possible using Redis Sentinel

  • Partitioning - Redis Cluster provides both automated data partionining as well as high avaiability capabilities

  • Keyspace notifications - You can subscribe to internal Redis Channels in order to get notifications about changes made to the data. The notifications are related to the key (e.g. votes) which got affected as well as the command/event which was executed (e.g. SET)

  • Redis CLI - Redis has a full-fledged CLI allowing you to interact with it using just a terminal

  • Expiry - Use the EXPIRE and other related commands to define a timeout for when you want a key to be automatically deleted by Redis

Overview: Core data structures

Sneak peek of the core data types listed above

String

Strings are quite versatile and they can be manipulated using simple SET and GET commands. You can even store integers as a value. Redis will recognize it and allow them to operated using beINCR, INCRBY, DECR and DECRBY commands

List

Internally implemented as Linked Lists which ensures constant time operations at head and tail. Basic commands include LPUSH, RPUSH to push data, LREM to delete, LTRIM to limit the list size, LRANGE to find sub-list, LPOP, RPOP to get data (BLPOP and BRPOP are the blocking variations). Lists are heavily used as a foundation for implementing job queues

Hash

It's ability to store key-value pairs makes Hash an ideal candidate for storing objects (thier attributes and values e..g user, order etc.). HSET and HGET are the basic commands to work with a Hash (HMSET and HMGET are the euqivalent commands to operate on multiple values at once). You can also use HGETALL to get the all key-value pairs in the Hash

Set

SADD and SREM are used to add and delete elements from a Set respectively. You can check for existence with SISMEMBER and list all elements using SMEMBERS. Other interesting operations include finding union (SUNION) and intersection (SINTER) of sets. You can calculate the difference between sets using SDIFF and its cardinality (number of elements) with SCARD

Sorted Set

Add element (along with thier score) using ZADD and bump up the score with ZINCRBY. ZSCORE will give you the score of a specific element while ZRANK will give you the index of the member (rank based on score). Sorted Sets are heavily used in leaderboards, time series use cases etc. because of their flexible sorting capabilities offered by ZRANGE, ZREVRANGE and other similar commands

Geo

It's a compact (limited set of commands) data structure which makes it very easy to work with geo spatial co-ordinates. Just add members and thier location (latitude and longitude) using GEOADD and query for thier exact postion or hash using GEOPOS and GOHASH respectively. Use GEODIST to calculat the distance between points in a Geo data set and get a sorted result of distances within a radius from a specific location or member using GEORADIUS and GEORADIUSBYMEMBER

Hyperloglog

Counting unique items is possible by storing them in a Set and then invoking SCARD. But, the beauty of Hyperloglog is that it's memory requirements are not proportional to the number of elements stored in it (~12000 bytes at max). This is because of it's probabilistic nature where there is a chance of an error (> 1 %). Just use PFADD to push elements and PFCOUNT to count them. PFMERGE is a handy command which allows you to merger multiple Hyperloglogs into a single one

Streams

Introduced in Redis 5.0 (not officially released at the time of writing), Streams can be used to ingest infinite data using XADD and access/process them using XREAD. Another variation is XREADGROUP which is similar to the Consumer Groups feature in Apache Kafka and can be used to split the processing workload among mulitple consumers. XRANGE provides the ability to find chunks of data in the Stream and makes it possible to perform time series analysis (by providing your own time as the ID or use the one returned by XADD)