# 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 `String`s 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 `Channel`s 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). `Transaction`s (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](https://redis.io/modules) provide the ability to extend Redis and develop custom data structures/commands
* **Lua scripting** - Redis gives you the ability to xecute [Lua](https://www.lua.org/) 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 `Channel`s 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**

`String`s 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 be`INCR`, `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 `Hyperloglog`s 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](https://kafka.apache.org/) 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`)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abhishek-gupta.gitbook.io/practical-redis/hello-redis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
