RedisGraph
Relational databases (SQL) struggle with deep relationships (JOINs). Graph databases are designed for this, but they can be slow and memory-hungry. RedisGraph takes a different approach by using Linear Algebra to solve graph problems.
1. What is RedisGraph?
RedisGraph is a high-performance graph database module. It implements the Property Graph Model:
- Nodes: Entities (e.g., Person, Movie).
- Relationships: Connections (e.g., ACTED_IN, KNOWS).
- Properties: Attributes on both nodes and relationships (e.g., name, year, rating).
The Secret Sauce: Sparse Matrices
Most graph databases use “Adjacency Lists” (pointers). RedisGraph represents the graph as Sparse Matrices.
- Traversing a graph becomes Matrix Multiplication.
- This allows it to process millions of relationships in parallel using optimized CPU instructions (SIMD).
graph LR subgraph Graph_View A((Alice)) -- KNOWS --> B((Bob)) B -- KNOWS --> C((Charlie)) A -- KNOWS --> C end subgraph Matrix_View style Matrix_View fill:var(--bg-main),stroke:var(--border-muted),color:var(--fg-default) M1[ Alice Bob Charlie] M2[Alice 0 1 1 ] M3[Bob 0 0 1 ] M4[Charlie 0 0 0 ] M1 --- M2 M2 --- M3 M3 --- M4 end
2. The Cypher Query Language
RedisGraph uses Cypher, the industry-standard language for graphs (originally from Neo4j). It uses “ASCII Art” to describe patterns.
(p:Person): A node labeled Person.-[r:FRIEND]->: A relationship labeled FRIEND.MATCH (a)-[:FRIEND]->(b) RETURN b: Find all friends of ‘a’.
3. Java & Go Implementation
import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.graph.ResultSet;
import redis.clients.jedis.graph.Record;
public class RedisGraphExample {
public static void main(String[] args) {
JedisPooled client = new JedisPooled("localhost", 6379);
// 1. Create Data
// CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})
client.graphQuery("social",
"CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})");
// 2. Query Data
// MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name
ResultSet rs = client.graphQuery("social",
"MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name");
// 3. Iterate Results
while(rs.hasNext()) {
Record record = rs.next();
System.out.println(record.getString(0) + " knows " + record.getString(1));
}
}
}
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
func main() {
ctx := context.Background()
rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
// 1. Create Data (Using GRAPH.QUERY command)
query := "CREATE (:Person {name:'Alice'})-[:FRIEND]->(:Person {name:'Bob'})"
_, err := rdb.Do(ctx, "GRAPH.QUERY", "social", query).Result()
if err != nil {
panic(err)
}
// 2. Query Data
match := "MATCH (a:Person)-[:FRIEND]->(b:Person) RETURN a.name, b.name"
res, _ := rdb.Do(ctx, "GRAPH.QUERY", "social", match).Result()
// Note: Parsing Graph results in Go raw client is complex.
// In production, use a dedicated RedisGraph Go client library.
fmt.Println("Raw Result:", res)
}
4. Interactive: Graph-to-Matrix Visualizer
Add connections between nodes and see how the Adjacency Matrix updates automatically. This is exactly how RedisGraph stores the structure in memory.
Graph View
Adjacency Matrix
| A | B | C | |
|---|---|---|---|
| A | 0 | 0 | 0 |
| B | 0 | 0 | 0 |
| C | 0 | 0 | 0 |
5. Summary
RedisGraph provides a massive performance leap over traditional table-based relational databases for relationship-heavy queries. By using Linear Algebra instead of pointer chasing, it can handle deep graph traversals in real-time.
It is ideal for:
- Fraud Detection rings
- Social Network feeds
- Recommendation Engines
- Identity & Access Management (IAM) graphs