Basic knowledges about Redis

Introduction & What is Redis?

An in memory database stored by key-value, usually use as a database to cache, is very quick access.

A comment on the video: 

Redis is an in-memory but persistent on disk database, so it represents a different trade off where very high write and read speed is achieved with the limitation of data sets that can’t be larger than memory.

Which means it’s not like it’s being stored only in memory and is not persistent. It stores everything in memory and write on disk is optional but still there for use

 

Below is the note content I learn from the above video. So, feel free to take a quick look and practice along with the video.

Redis Installation

On Mac:

Install by Homebrew: brew install redis

Run server Redis: redis-server

Open new tab/window to access to Redis CLI by redis-cli, type quit to quit

Basic Commands

Setting a value for a keySET key value , the value will store as string

Getting a value for a keyGET key

Check if key is existEXISTS key

Check key match a pattern:

  • All keys: KEY *

Clear all cacheflushall

Clear all input on terminalclear

127.0.0.1:6379> SET age 16
OK
127.0.0.1:6379> GET age
"16"
127.0.0.1:6379> EXISTS age
(integer) 1
127.0.0.1:6379> EXISTS name
(integer) 0
127.0.0.1:6379> KEYS *
1) "age"
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> KEYS *
(empty list or set)

Handling Expirations

If have no expiration -> key-value will live forever

Expire age in 10 seconds: expire key timevalue

Ex: expire age 10

Check time key live(time to live – ttl): ttl key

after out of time, the key will be deleted and value is nil

Set expire key-value at the same time: setex age 10 16

that mean set age have value is 16 in 10 seconds

Example code:

127.0.0.1:6379> SET age 16
OK

127.0.0.1:6379> expire age 10
(integer) 1
127.0.0.1:6379> ttl age
(integer) 4
127.0.0.1:6379> ttl age
(integer) 1
127.0.0.1:6379> ttl age
(integer) -2
127.0.0.1:6379> GET age
(nil)

127.0.0.1:6379> setex age 10 16
OK
127.0.0.1:6379> get age
"16"
127.0.0.1:6379> ttl age
(integer) -2
127.0.0.1:6379> get age
(nil)

Lists

Add item to a list is the value: lpush key value

Get list value of a key: lrange key startRange endRange

by get key WILL NOT work because this only work for string, and this is a list

Push value to the left of the list: lpush key value

Push value to the right of the list: rpushkey value

Pop a item out of the list from the left: lpop key, similar have rpop key

Example code:

127.0.0.1:6379> KEYS *
1) "friends"

127.0.0.1:6379> lrange friends 0 -1
1) "thanh"

127.0.0.1:6379> lpush friends nga
(integer) 2

127.0.0.1:6379> lrange friends 0 -1
1) "nga"
2) "thanh"

127.0.0.1:6379> rpush friends xuan
(integer) 3

127.0.0.1:6379> lrange friends 0 -1
1) "nga"
2) "thanh"
3) "xuan"

127.0.0.1:6379> lpop friends
"nga"
127.0.0.1:6379> lrange friends 0 -1
1) "thanh"
2) "xuan"

Sets

Add a key with value to a set: sadd key value

Get all members in a set: smembers key

Remove a value out of a set: srem key value

Example code:

// Add "running" to set
127.0.0.1:6379> sadd hobbies running
(integer) 1
127.0.0.1:6379> smembers hobbies
1) "running"

// Add again, will not duplicate value
127.0.0.1:6379> sadd hobbies running
(integer) 0

// Check all members in a set
127.0.0.1:6379> smembers hobbies
1) "running"
127.0.0.1:6379> sadd hobbies tennis
(integer) 1
127.0.0.1:6379> smembers hobbies
1) "tennis"
2) "running"
127.0.0.1:6379> smembers hobbies
1) "tennis"
2) "running"

// Remove a member in a set
127.0.0.1:6379> srem hobbies tennis
(integer) 1
127.0.0.1:6379> smembers hobbies
1) "running"

Hashes

key-value pair inside key-value pair

Set to a hash one key and its field’s value: HSET key field value

Get a value of a field: HGET key field

Get all value of a field: HGETALL key field

Delete field in a key: HDEL key field1 field2

Check a field in key exists: HEXISTS key field 

127.0.0.1:6379> HSET person name thanh 
(integer) 1 
127.0.0.1:6379> HGET person name 
"thanh" 

127.0.0.1:6379> HGETALL person 
1) "name" 
2) "thanh"
127.0.0.1:6379> HSET person age 30 
(integer) 1
127.0.0.1:6379> HGETALL person 
1) "name" 
2) "thanh" 
3) "age" 
4) "30"

127.0.0.1:6379> HDEL person age 
(integer) 1 
127.0.0.1:6379> HGETALL person 
1) "name" 
2) "thanh"

NodeJS Examples

Link demo, my short summary:

Step 1: install and create redis instance, run redis server

Install redis to project: npm i redis

In code, get redis by: const Redis = require("redis")

Create instance of Redis: const redisClient = Redis.createClient()

Step 2: set a key value with an expiration

Use redisClient as normal redis(as practice). For example:

Set a key value with expiration time for data response to cache:

redisClient.setex(photos, 3600, JSON.stringify(data))

Step 3: Check key and its value in redis CLI

After run app again, we could access to Redis CLI to check if the key photos with value in cache, use key *

Step 4: Use cache value from keys for the response data

Then we check the cache in redis and use it to replace for the data response:

 

(If want to remove all the cache, use flushall)

api.get("/photos", async(req, res) => {
  const albumId = req.query.albumId

  redisClient.get(`photos/?ablumId=${albumId}`, async(errors, photos) => {  
    if (errors) console.log(errors)
    if (photos !== null) {
      return res.json(JSON.parse(photos))
    } else {
      const { data } = await axios.get(url)
      res.json(data)
    }
  })
})

Step 5: Create function for re-use logic of get or set cache

function getOrSetCache will take a key and a callback

function getOrSetCache(key, callback) {
  return new Promise(resolve, reject) {
    redisClient.get(key, async (error, data) => {
      if (error) return reject(error)
      if (data !== null) return resolve(JSON.parse(data))
      
      const freshData = await callback()
      redisClient.setex(key, 3600, JSON.stringify(freshData))
      resolve(freshData)
    })
  }
}

Then we will use this function in the get and use similar for other request if want to cache:

api.get("/photos", async(req, res) => {
  const albumId = req.query.albumId
  const photos = await getOrSetCache(`photos/?ablumId=${albumId}`, async () => {
    const { data } = await axios.get(url)
    return data
  }) 

  res.json(photos)
})

That’s all for today learning, thank you for your reading.

Please follow and like us:

Leave a Reply

Your email address will not be published. Required fields are marked *

RELATED POST

Gỡ lỗi chương trình

Hôm nay mình muốn nói về “Gỡ lỗi”(Debugging) , một qui trình sửa lỗi trong chương trình phần mềm. (Phần…

Giới thiệu về CLI và các câu lệnh làm việc với file trong Linux

Chào mừng bạn đến với blog số 5 của series “Linux dành cho lập trình viên”. Trong các blog trước, mình…

.gitkeep

Khi bắt đầu một dự án xây dựng web, một trong những công việc đầu tiên là tạo cấu trúc…

Chiến lược tải, thực thi code JavaScript

Ba thành phần chính cấu tạo nên một trang web là HTML, CSS và JavaScript.  HTML là ngôn ngữ đánh dấu…