redis-search-values-demo

Search in redis values server-side with a special lua-script

In the article proposed an approach to a maintenance task of searching in large amount of values stored in Redis. A real use-case of applying the approach is described. A working example of code for Node.js is provided. In the repository you can find full source code of the solution.

Andrey Bobkov, 2023, https://github.com/a-bobkov

This is a published page of the GitHub public Repository Redis-Search-Values-Demo.

πŸ™‹β€ƒ Context

Imagine, that you maintain a relatively big internet shop, working 24/7 and having many customers. There are about 37 millions shopping carts saved as PHP-session data. Everything was fine, but one day you discover a bug in the code of the shop. Due to that bug some sessions contain inconsistent data. How many? Good question… Anyway you don’t want just to delete all existing sessions, because in that case all guest customers of the shop would be disappointed by the fact, that their shopping carts just disappeared.

So you have a question, what sessions are broken. It is not so easy to answer, because there are 37 million of sessions, taking more than 20 gigabytes and all the sessions are stored in Redis 6. You know, that Redis is a very popular key-value storage, it is very fast and reliable, but provides poor functionality to investigate stored values. In Redis you can not simply query data with a filter by stored values.

πŸ“β€ƒ Goal

So here we have a task of investigation of large amount of values stored in Redis. This is an important but not so simple real life maintenance task.

Furthermore, in the real life we always have limits. The main limit for the task is to not block the shop in any case - shop should serve customers 24/7. Another limit is that we expect to find the broken sessions in a reasonable time, preferably in an hour, because we care about our customers and don’t want them to suffer many days while we are solving the problem.

Let’s see, how we can do it!

πŸŒ±β€ƒ Approach

In order to not block the shop by a long query, we can use a special SCAN command of Redis (see Redis SCAN). This command gives the possibility to search keys chunk by chunk, not blocking the server for a long time. That is a good thing, but not enough, because the command itself can not filter data by value, but only by key. Since we want the search to be finished in a reasonable time, we don’t want to download from server all the data found by SCAN and filter them client-side. Also, we don’t want to install any additional Redis modules or create secondary indices.

We decide to use programmability of Redis (see Redis programmability), making sort of a wrapper around the SCAN command. We will scan Redis-entries server-side, filtering the data by value on server with a special Lua-script (see Redis Lua API reference), returning to the client only needed data of the broken sessions.

Let’s implement it!

πŸŒ³β€ƒ Solution

The implemented solution consists of:

β€ƒπŸŸ‘β€‚ NodeJS-script searchBrokenSessions.js, that can be run locally;

β€ƒπŸ”΅β€‚ Lua-script scanBrokenSessions.lua, that is instantiated on the Redis-server.

The NodeJS-script connects to a Redis-server, instantiates the Lua-script on it and runs the Lua-script continually until all sessions are scanned.
The Lua-script scans sessions and analyses them, if a session broken or not, returning to the client only needed data of the broken sessions.

By the way, the NodeJS-script is an example of creating and using a JavaScript async generator.

πŸŠβ€ƒ Result

The solution with SCAN parameter COUNT 5000 has scanned 37 million of sessions on a live remote server in 22 minutes and has found 604 broken sessions.

πŸ”β€ƒ Example run

πŸ»β€ƒ Feedback

To keep my motivation high, you may

⭐ the GitHub public repository Redis-Search-Values-Demo

Your verbal opinion is appreciated via Discussions and Issues

πŸ“’β€ƒ Other investigations

If you are interested to see the list of my published investigations, you may find it here: https://a-bobkov.github.io/