Friday 2 October 2020

Redis Basics

 Redis is an open source, in-memory data structure store, used as a database, cache and message broker. 

It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.


Redis persistence - Data is saved in memory for fast access.

Persistence can be managed by the below options:

RDB - Redis Database File - keeps snapshots of Redis state - helps in disaster recovery - default

AOF - Append Only File - keeps appending the data to a file on the list

Redis conf file can be updated for enabling AOF or updating snapshot frequency with RDB

Enable password for accessing the redis can be done using redis.conf by enabling requirepass


Redis Architecture

Redis follows master-slave replication architecture. 

It allows replica Redis instances to be exact copies of master instances. 

The replica will automatically reconnect to the master every time the link breaks, and will attempt to be an exact copy of it regardless of what happens to the master.

Redis uses by default asynchronous replication, which being low latency and high performance.

Redis cluster - will have a set of masters and slave/replicas. If a master node crahes, the replica will take over.

Redis Sentinel - If it is not possible to have a fully fledged redis cluster, redis sentinel can be used for automatic failover to the replicas

A Redis cluster is divided up among 16,384 slots — the maximum number of nodes or shards in a Redis cluster.

Since most clusters consist of a much smaller number of nodes, these hash slots are logical divisions of the keys. 

In an oversimplified example of a 4-node cluster, we’d have the following layout:

------------------------------------

Slots                    Node

------------------------------------

0 – 4,095                    Node #0

4,096 – 8,191            Node #1

8,192 – 12,287    Node #2

12,288 – 16,384 Node #3

The data will get distributed according to the hash slots. If more number of nodes are added, then rebalancing will be required of the hash slots.

Redis cluster is not able to guarantee strong consistency. 

That’s because when you send a write request to a Redis cluster, the master writes the data first on itself and immediately returns success to the client. Then, the replication to the slave nodes asynchronously starts. 

What happens if the master node crashes before the data gets replicated and a slave node is promoted to be the new master? 

Basically, the client will receive success but the write was actually lost.


Basic Redis features with sample usage using redis-cli

Redis string key/value - can be set/retrieved using simple set/get of key-value, expiry can also be specified:

127.0.0.1:6379> set zip 432985792 ex 10

OK

127.0.0.1:6379> get zip

"432985792"

127.0.0.1:6379> get zip

(nil)

127.0.0.1:6379> exists zip

(integer) 0


127.0.0.1:6379> set counter 100

OK

127.0.0.1:6379> incr counter

(integer) 101

127.0.0.1:6379> incrby counter 50

(integer) 151

127.0.0.1:6379> decr counter

(integer) 150

127.0.0.1:6379> expire counter 5000

(integer) 1


Redis Hash data structure

Keeps data in key value pair like individual hashMap in java.

can be used for storing data equivalent to what we store in an RDBMS record, but is really flexible.

It can be used for storing denormalized data.

127.0.0.1:6379> hmset user:1000 username antirez birthyear 1977 verified 1

OK

127.0.0.1:6379> hgetall user:1000

1) "username"

2) "antirez"

3) "birthyear"

4) "1977"

5) "verified"

6) "1"

127.0.0.1:6379> hget user:1000 username

"antirez"

127.0.0.1:6379> hget user:1000 birthyear

"1977"

127.0.0.1:6379> hexists user:1000 firstname

(integer) 0

127.0.0.1:6379> hexists user:1000 username

(integer) 1

127.0.0.1:6379> hmset user:1001 username prasune birthyear 1984 verified 1

OK


Redis List

can be used for storing items in the order of insertion, there is support for insertion at the beginning as well as the end.

can use LPUSH to the list for new items getting added to the timeline in redis cache or tweets or messages in an ordered way.

127.0.0.1:6379> rpush chat_messages hi "how are you?"

(integer) 2

127.0.0.1:6379> lrange chat_messages 0 -1

1) "hi"

2) "how are you?"

127.0.0.1:6379> lpush chat_messages "before hi"

(integer) 3

127.0.0.1:6379> lrange chat_messages 0 -1

1) "before hi"

2) "hi"

3) "how are you?"

127.0.0.1:6379> rpush chat_messages "can we meet today?"

(integer) 4

127.0.0.1:6379> lrange chat_messages 0 -1

1) "before hi"

2) "hi"

3) "how are you?"

4) "can we meet today?"

127.0.0.1:6379> lpop chat_messages

"before hi"

127.0.0.1:6379> lrange chat_messages 0 -1

1) "hi"

2) "how are you?"

3) "can we meet today?"


Redis Set

can use sinter for scenarios like find all online users who are friends toa a particular user - 

by maintaining set of all online users and another set of all friends of the particular user.


127.0.0.1:6379> sadd set1 1 2 3

(integer) 3

127.0.0.1:6379> sadd set2 3 4 5

(integer) 3

127.0.0.1:6379> sinter set1 set2

1) "3"

127.0.0.1:6379> smembers set1

1) "3"

2) "1"

3) "2"


Redis Sorted Set

can be used for scenarios where we want to keep score for an exam and display toppers as well as rank of a particular user.


127.0.0.1:6379> zadd score 1544 prasune

(integer) 1

127.0.0.1:6379> zadd score 555 dfmo

(integer) 1

127.0.0.1:6379> zadd score 123 xyz

(integer) 1


127.0.0.1:6379> zrevrange score 0 -1

1) "prasune"

2) "dfmo"

3) "xyz"


127.0.0.1:6379> zrange score 0 -1

1) "xyz"

2) "dfmo"

3) "prasune"


127.0.0.1:6379> zscore score prasune

"1544"

127.0.0.1:6379> zrank score prasune

(integer) 2

127.0.0.1:6379> zrevrank score prasune

(integer) 0


127.0.0.1:6379> zpopmax score

1) "prasune"

2) "1544"


Redis publish/subscribe

Redis also have a publish subscribe mechanism by specifying a topic name.

Useful for chatting application like scenarios to publish message to all the users that have subscribed to a topic.

127.0.0.1:6379> publish news dfoibgnvomdobe 

(integer) 0

127.0.0.1:6379> publish news dfoibgnvomdobe 

(integer) 1

127.0.0.1:6379> publish news testing

(integer) 1


127.0.0.1:6379> subscribe news

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "news"

3) (integer) 1

1) "message"

2) "news"

3) "dfoibgnvomdobe"

1) "message"

2) "news"

3) "testing"


Handling geospatial indexes with radius queries

This will be useful for use cases like figuring out a near by cab for a customer in a taxi aggregator app.

geoadd uberdb 13.138 15.3583 cab1 14.4363 14.43766 cab2

(integer) 2

127.0.0.1:6379> georadius uberdb 14 15 200 km withdist

1) 1) "cab1"

   2) "100.7491"

2) 1) "cab2"

   2) "78.1989"

127.0.0.1:6379> georadius uberdb 14 15 200 km withcoord

1) 1) "cab1"

   2) 1) "13.13799887895584106"

      2) "15.35830007022889276"

2) 1) "cab2"

   2) 1) "14.43630069494247437"

      2) "14.43765892850307608"


No comments:

Post a Comment