Why is Redis so fast?

Posted by cmattoon on Tue, 06 Aug 2019 13:03:17 +0200

1. Introduction to Redis

Redis is an open source, Key-Value database written in ANSI C, complied with BSD protocol, supported network, memory-based and persistent

2. Data structure of Redis

  • string
set mykey somevalue

get mykey

set mykey somevalue nx

set mykey somevalue xx

set mykey hello ex 10 nx

set mykey hello xx 10 nx

del mykey

// Judging the data type of key
type key

set counter 100

incr counter

incrby counter 10

decr counter

decrby counter 100

exists count  
  • Lists
rpush mylist A

rpush mylist B

lpush mylist first

rpush mylist A B C D

lrange mylist 0 -1

rpop mylist

lpop mylist

ltrim mylist 0 2

// It's basically the same as rpop, but if tasks doesn't have data, it's going to wait five seconds.
brpop tasks 5
  • Hashes
hmset user:1000 username antirez birthyear 1977 verified 1

// Gets the specified key
hget user:1000 username

// Get all the key s
hgetall user:1000

// Get multiple key s
hmget user:1000 username birthyear

// Adding 10 operations to birthyear
hincrby user:1000 birthyear 10
  • Sets
sadd myset 1 2 3

smembers myset

// Determine whether a value is in the key
sismember myset 3

sadd news:1000:tags 1 2 5 77

smembers news:1000:tags
  • Sorted sets
zadd hackers 1940 "Alan Kay"

zrange hackers 0 -1

zrange hackers 0 -1 withscores

zrangebyscore hackers -inf 1950

zremrangebyscore hackers 1940 1960

zrank hackers "Anita Borg"

3.Redis usage scenarios

1. Caching
Caching is now a must-kill technology used by almost all large and medium-sized websites. Reasonable use of caching can not only improve the speed of website access, but also greatly reduce the pressure of the database. Redis provides key expiration functionality and flexible key elimination strategies, so Redis is now used in many caching situations.

2. Rankings
Many websites have the application of ranking, such as the monthly sales list of Jingdong, the new listing of goods on time, etc. Redis provides an ordered set of data classes to implement a variety of complex ranking applications.

/**
* Test Commodity List
*/
public static void testTop(){
    String rankKey = "product_mobile_phone";

    Jedis jedis = new Jedis("localhost");
    jedis.zadd(rankKey, 100,"iphone_xs");
    jedis.zadd(rankKey, 110,"iphone_xs_max");
    jedis.zadd(rankKey, 90,"xiaomi_9");
    jedis.zadd(rankKey, 120,"huawei_p30");

    Set<String> products = jedis.zrevrange(rankKey, 0, -1);
    System.out.println(products);
}

3. Counter
What is a counter, such as e-commerce website merchandise browsing, video site video playback number and so on. In order to ensure real-time data efficiency, every browse must be given + 1, and if the concurrency is high, it is undoubtedly a challenge and pressure to request database operation every time. The incr command provided by Redis implements counter function, memory operation, and very good performance, which is very suitable for these counting scenarios.

4. Distributed Session
In cluster mode, session replication function of container is usually used to satisfy the needs of few applications. When applications are multiplied and relatively complex, session service centered on memory databases such as Redis is generally built. Session is no longer managed by container, but managed by session service and memory database.

5. Distributed Lock
Distributed technology is used in many Internet companies. The technical challenge brought by distributed technology is concurrent access to the same resource, such as global ID, inventory reduction, second kill scenarios. The scenarios with small concurrency can be realized by pessimistic and optimistic database locks. However, in the case of high concurrency, the number of users can be used. It is not ideal to control concurrent access of resources by database lock, which greatly affects the performance of database. The setnx function of Redis can be used to write distributed locks. If the setnx function returns 1, the success of acquiring locks will be explained. Otherwise, the failure of acquiring locks will result in more details to be considered in practical application.

import java.util.Collections;
import redis.clients.jedis.Jedis;

/**
 * @Description
 * @Author luohong <luohong.lh@alibaba-inc.com>
 * @Date 06/08/19
 */
public class RedisClient {

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    final Jedis jedis = new Jedis("localhost");
                    String lockKey = "hello";
                    String requestId = "world";

                    try{
                        if (tryGetLock(jedis, lockKey, requestId, 10)) {
                            System.out.println("get lock success");
                        } else {
                            System.out.println("get lock failed");
                        }
                    }finally {
                        tryUnlock(jedis, lockKey, requestId);
                    }

                }
            }).start();
        }
    }

    /**
     * Attempt to acquire distributed locks
     * @param jedis
     * @param lockKey
     * @param requestId
     * @param expireTime
     */
    public static boolean tryGetLock(Jedis jedis, String lockKey, String requestId, int expireTime){
        String result = jedis.set(lockKey, requestId, "NX", "EX", 10);
        return "OK".equals(result);
    }

    /**
     * Release lock
     * @param jedis
     * @param lockKey
     * @param requestId
     * @return
     */
    public static boolean tryUnlock(Jedis jedis, String lockKey, String requestId){
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        return "OK".equals(result);
    }
}

get lock failed
get lock failed
get lock failed
get lock failed
get lock failed
get lock failed
get lock failed
get lock success
get lock failed
get lock failed

6. Social Network
The basic functions of social networking sites are praise, tread, attention/attention, common friends, etc. The visits of social networking sites are usually relatively large, and the traditional relational database type is not suitable for storing this type of data. The data structure provided by Redis, such as hash and collection, can easily realize these functions.

7. Latest List
Redis list structure, LPUSH can insert a content ID at the head of the list as a keyword, LTRIM can be used to limit the number of lists, so that the list will always be N IDs, without querying the latest list, directly according to the ID to the corresponding content page.

8. Message System
Message queuing is a necessary middleware for large websites, such as ActiveMQ, RabbitMQ, Kafka and other popular message queuing middleware. It is mainly used for business decoupling, traffic peaking and asynchronous processing of low real-time business. Redis provides publish/subscribe and blocking queuing capabilities, enabling a simple message queuing system. In addition, this can not be compared with professional message middleware.

4. Principles of Redis High Performance

  • Most requests are pure memory operations (very fast)
  • Single thread avoids unnecessary context switching and contention conditions
  • Non-blocking IO-IO multiplexing
  • Simple data structures, most of the read/write operations are O(n)

Because the process execution process is linear, when we call the low-speed system I/O(read,write,accept, etc.), the process may block, at this time the process will block on the call, can not perform other operations, blocking is normal.

Next, consider the following problem: a server process communicates with a client process, and the server reads (sockfd1, bud, bufsize), when the client process does not send data, then read (blocking call) will block until the client calls write(sockfd,but,size) to send data. This is no problem when communicating with one client and server; when multiple clients communicate with the server, if the server blocks one client sockfd1, when another client's data arrives at sockfd2, the server can't handle it, and still blocks in read(sockfd1... ) At this point, the problem arises, can't deal with another customer's service in time, what to do?

I/O multiplexing to solve! I/O multiplexing! Continue with the above questions, there are multiple customer connections, sockfd1, sockfd2, sockfd3.. sockfdn. At the same time listen on the n customers, when one of them sends a message, it returns from the blocking of select, then calls read to read the sockfd of the received message, and then loops back to the blocking of select, so that the message of another customer can not be processed because of blocking on one of them. "I/O multiplexing" in English is "I/O multiplexing", you can Baidu multiplexing, you can get this map:

Topics: Jedis Redis Database Session