Redis

📢 This article was translated by gemini-3-flash-preview

Redis Basics: This article
Redis Distributed Cache: https://blog.yexca.net/en/archives/225/

Redis is an in-memory key-value database and is one of the most widely used storage middleware in the IT industry.

Since Redis is memory-based, it offers high read/write performance, making it ideal for storing hot data (products, news, info). It is an open-source high-performance key-value database developed in C. It supports rich value types and is often referred to as a structured NoSQL (Not Only SQL) database.

NoSQL refers to non-relational databases. It’s not meant to replace relational databases but to complement them.

Relational Databases (RDBMS):

  • MySQL
  • Oracle
  • DB2
  • SQLServer

Non-relational Databases (NoSQL):

  • Redis
  • MongoDB
  • MemCached

Redis Download, Installation, and Execution

Download links:

For Windows, just unzip it. For Linux:

  1. Unzip: tar -zxvf redis-4.0.0.tar.gz -C /usr/local
  2. Install dependencies: yum install gcc-c++
  3. Enter the directory and compile: make
  4. Enter the src directory and install: make install

File Descriptions:

  • /usr/local/redis-4.0.0/src/redis-server: Redis server startup script
  • /usr/local/redis-4.0.0/src/redis-cli: Redis client script
  • /usr/local/redis-4.0.0/redis.conf: Redis configuration file

To start the server (Windows example):

1
redis-server.exe redis.windows.conf

The default port is 6379 with no password. Once started, you can connect via a client.

  • Command Line Connection

Connect using redis-cli.exe:

1
redis-cli.exe -h ip -p port -a password

If omitted, it defaults to 127.0.0.1:6379.

You can set a password by modifying the configuration file (redis.windows.conf):

1
requirepass 123456

Restart the server for changes to take effect.

  • GUI Connection

Github: https://github.com/qishibo/AnotherRedisDesktopManager

Download, install, create a new connection, and enter your details.


Docker Deployment

Pull the image:

1
docker pull redis

Get the configuration file for your version (e.g., redis.conf).

Create data mapping directories:

1
2
mkdir /home/redis
mkdir /home/redis/data

Modify the config file and transfer it to the server (e.g., using scp from Win to Linux):

1
scp pathOfFile root@IP:/PathOfFile

Run:

1
docker run -p 6379:6379 --name redis -v /home/redis/redis.conf:/etc/redis/redis.conf  -v /home/redis/data:/data -d redis redis-server /etc/redis/redis.conf

Reference: https://cloud.tencent.com/developer/article/1670205


Redis Data Types

Redis keys are always strings. Values support 5 common data types:

  • String: Standard text or binary data.
  • Hash: A map of fields and values.
  • List: Ordered collection of strings (allows duplicates).
  • Set: Unordered collection of unique strings.
  • Sorted Set (zset): Unique strings associated with a score, ordered by score.

Redis Data Types

Common Redis Commands

Redis commands are case-insensitive.

Common String commands:

1
2
3
4
5
6
7
8
# Set value for a key
SET key value
# Get value of a key
GET key
# Set value with expiration in seconds
SETEX key seconds value
# Set value only if key does not exist
SETNX key value

Hash commands (ideal for storing objects):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Set field in a hash
HSET key field value
# Get value of a field
HGET key field
# Delete a field
HDEL key field
# Get all fields
HKEYS key
# Get all values
HVALS key

List commands (insertion order):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Insert at head
LPUSH key value1 [value2]
# Get range of elements
LRANGE key start stop
# Remove and get last element
RPOP key
# Get list length
LLEN key
# Block until element is available to pop from tail
BRPOP key1 [key2] timeout

Lists behave like queues (FIFO).

Set commands (unique, unordered):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Add members
SADD key member1 [member2]
# Get all members
SMEMBERS key
# Get member count
SCARD key
# Intersection of sets
SINTER key2 [key2]
# Union of sets
SUNION key1 [key2]
# Remove members
SREM key member1 [member2]

Sorted Set commands (members + double score):

1
2
3
4
5
6
7
8
# Add members with scores
ZADD key score1 member1 [score2 member2]
# Get range of members by index
ZRANGE key start stop [WITHSCORES]
# Increment score of a member
ZINCRBY key increment member
# Remove members
ZREM key member1 [member2]

Generic commands (apply to all types):

1
2
3
4
5
6
7
8
# Find keys matching a pattern (e.g., KEYS *)
KEYS pattern
# Check if key exists
EXISTS key
# Get data type of key
TYPE key
# Delete a key
DEL key

Operating Redis in Java

To work with Redis in Java, you need a client library, similar to how you use JDBC for MySQL.

Popular Java clients:

  • Jedis
  • Lettuce
  • Spring Data Redis

Jedis has a clean API identical to Redis commands and is officially recommended. Lettuce handles threading better and offers higher performance. Spring Data Redis integrates these into the Spring ecosystem, providing a convenient Starter (spring-boot-starter-data-redis).

Spring Data Redis

Part of the Spring Data project, it simplifies Redis operations through configuration and high-level abstractions.

Maven Dependency:

1
2
3
4
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

The core class is RedisTemplate, which categorizes operations into specialized interfaces:

  • ValueOperations: String operations
  • SetOperations: Set operations
  • ZSetOperations: ZSet operations
  • HashOperations: Hash operations
  • ListOperations: List operations

Configure the Redis datasource in application.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# application
spring:
  profiles:
    active: dev
  redis:
    host: ${sky.redis.host}
    port: ${sky.redis.port}
    password: ${sky.redis.password}
    database: ${sky.redis.database}

# -dev
sky:
  redis:
    host: localhost
    port: 6379
    password: 123456
    # Optional: defaults to database 0
    database: 10 

Redis has 16 default databases (0-15).

Create a configuration class for the RedisTemplate bean:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Configuration
@Slf4j
public class RedisConfiguration {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        log.info("Creating RedisTemplate object");
        RedisTemplate redisTemplate = new RedisTemplate();
        // Set connection factory
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // Set key serializer to String
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

While Spring Boot auto-configures a RedisTemplate, the default uses JdkSerializationRedisSerializer, which might make data unreadable in the Redis CLI.

String Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@SpringBootTest
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void testString(){
        // set
        redisTemplate.opsForValue().set("name", "Tom");
        // get
        String name =(String) redisTemplate.opsForValue().get("name");
        System.out.println(name);
        // setex (set with expiration)
        redisTemplate.opsForValue().set("code", "1234", 2, TimeUnit.MINUTES);
        // setnx (set if absent)
        redisTemplate.opsForValue().setIfAbsent("lock","1");
        redisTemplate.opsForValue().setIfAbsent("lock","2");
    }
}

Hash Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@Test
public void testHash(){
    HashOperations hashOperations = redisTemplate.opsForHash();
    // hset
    hashOperations.put("100", "name", "Jerry");
    hashOperations.put("100", "age", "20");
    // hget
    String name =(String) hashOperations.get("100", "name");
    System.out.println(name);
    // hkeys
    Set keys = hashOperations.keys("100");
    System.out.println(keys);
    // hvals
    List values = hashOperations.values("100");
    System.out.println(values);
    // hdel
    hashOperations.delete("100", "name");
}

List Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@Test
public void testList(){
    ListOperations listOperations = redisTemplate.opsForList();
    // lpush
    listOperations.leftPushAll("mylist", "a", "b", "c");
    listOperations.leftPush("mylist", "d");
    // lrange
    List mylist = listOperations.range("mylist", 0, -1);
    System.out.println(mylist);
    // rpop
    listOperations.rightPop("mylist");
    // llen
    Long size = listOperations.size("mylist");
    System.out.println(size);
}

Set Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void testSet(){
    SetOperations setOperations = redisTemplate.opsForSet();
    // sadd
    setOperations.add("set1","a","b","c","d");
    setOperations.add("set2","a","b","x","y");
    // smembers
    Set members = setOperations.members("set1");
    System.out.println(members);
    // scard
    Long size = setOperations.size("set1");
    System.out.println(size);
    // sinter
    Set intersect = setOperations.intersect("set1", "set2");
    System.out.println(intersect);
    // sunion
    Set union = setOperations.union("set1", "set2");
    System.out.println(union);
    // srem
    setOperations.remove("set1", "a", "b");
}

Sorted Set Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@Test
public void testZset(){
    ZSetOperations zSetOperations = redisTemplate.opsForZSet();
    // zadd
    zSetOperations.add("zset1", "a", 10);
    zSetOperations.add("zset1", "b", 12);
    zSetOperations.add("zset1", "c", 9);
    // zrange
    Set zset = zSetOperations.range("zset1", 0, -1);
    System.out.println(zset);
    // zincrby
    zSetOperations.incrementScore("zset1", "c", 10);
    // zrem
    zSetOperations.remove("zset1", "a", "b");
}

Generic Command Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@Test
public void testCommon(){
    // keys
    Set keys = redisTemplate.keys("*");
    System.out.println(keys);
    // exists
    Boolean name = redisTemplate.hasKey("name");
    System.out.println(name);
    // type
    for (Object key : keys) {
        DataType type = redisTemplate.type(key);
        System.out.println(type.name());
    }
    // del
    redisTemplate.delete("set2");
}