One, foreword

In Internet applications, caching becomes a key component of high concurrency architectures. This blog mainly introduces typical scenarios of cache use, practical case studies, Redis usage specifications and general Redis monitoring.

Second, common cache comparison

Common caching scheme, there is a local Cache, including a HashMap/ConcurrentHashMap, Ehcache, Memcache, Guava Cache, the Cache middleware including Redis, Tair, etc.

! [](https://static001.geekbang.org/infoq/b9/b9a1dd4d76799c13d77d28d665b495aa.png)

Three, Redis usage scenarios

Counting 1.

Redis implements fast counting and caching.

For example, the number of online viewers of a video or live broadcast will increase by 1 each time the user plays the video.

2. Centralized Session management

Sessions can be stored in the application service JVM, but there are consistency issues with this option, and high concurrency can cause JVM memory overflow. Redis centrally manages user sessions. In this case, as long as the high availability and scalability of Redis is ensured, every update or login query is directly obtained from Redis information.

3. The speed limit

For example, a user can obtain a verification code only five times per minute.

4. List

The query speed of relational database is generally slow in terms of ranking, so we can use Redis SortedSet to sort hot data.

For example, in the project, if the ranking list of anchors’ earning money needs to be counted, the ID of anchors can be used as member, and the popularity value corresponding to the activity gifts awarded on that day can be used as score, and the daily list of anchors’ activities can be obtained through ZrangebyScore.

5. Distributed lock

In real multi-process concurrent scenarios, distributed locks are used to limit the concurrent execution of programs. It is used to prevent cache breakdown in high concurrency scenarios.

When another process executes setnx, it finds that the identifier bit is already 1 and has to give up or wait.

Iv. Case analysis

1. Expiration setting the -set command deletes the expiration time

All Redis data structures can be set to expire. If a string has an expiration time set, then resetting it will cause the expiration time to disappear. Therefore, it is necessary to evaluate the capacity of Redis reasonably in the project, so as to avoid the frequent set leading to no expiration policy and indirectly leading to full memory.

Redis source code screenshot below:

! [](https://static001.geekbang.org/infoq/78/788e492c3f8d5d132f8b82035ab1835a.png)

2. [Case] About Jedis 2.9.0 and the following version expiration setting BUG

It is found that Jedis has a bug when invoking expiredAt command, and finally invokes pexpire command. This bug will cause the key to expire for a long time, resulting in Redis memory overflow and other problems. You are advised to upgrade to Jedis 2.9.1 or later.

BinaryJediscluster.java

@Override public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) { return new JedisClusterCommand<Long>(connectionHandler, maxAttempts) { @Override public Long execute(Jedis connection) { return connection.pexpire(key, millisecondsTimestamp); Pexpire}}. RunBinary (key); }Copy the code

Compare pEXPIRE and pexpireAt:

For example, the time we are currently using is 2018-06-14 17:00:00, and its Unix timestamp is 1528966800000 milliseconds. When we use the PEXPIREAT command, the corresponding key will expire immediately because it is a past time.

However, if we misuse the PEXPIRE command, the key will not expire immediately, but will expire after 1528966800000 milliseconds. The key will expire after several W days, which may cause Redis memory overflow and server crash.

3. [Case] Cache breakdown

The cached key has an expiration policy. If there are a large number of concurrent requests for the key at this point in time, these requests will generally return the source data from the back-end DB and set it back to the cache. At this time, the large number of concurrent requests may temporarily suspend the back-end DB.

There are two commonly used optimization schemes in the industry:

** The first type: ** Uses distributed locks to ensure that only one thread can return to the source backend DB under high concurrency.

** To ensure that the Redis key to the high concurrency request is always valid, use the non-user request back to the source, instead of active back to the source. You can typically use an asynchronous task to actively flush the cache.

4. The redis-standalone architecture forbids the use of non-0 libraries

Redis switches between select 0 and select 1, causing performance loss.

The RedisTemplate retrieves the link when executing the execute method.

Perform to RedisConnectionUtils. Java, there will be a way for a link.

JedisConnectionFactory. Java is called JedisConnection constructor, pay attention to the side of the dbIndex is database number, such as: 1

Following the JedisConnection code, a select DB operation occurs when the select library is greater than 1. There is no need to execute the cut library command if you are using the 0 library all the time. Where does select 0 come from?

RedisTemplate does this automatically. Let’s go back to the original RedisTemplate and execute(…). Method of place.

Below or RedisConnectionUtils. Java, link closed code execution.

According to the code comments, if the library number is not 0, the Spring-data-Redis framework will reset select 0!

! [](https://static001.geekbang.org/infoq/23/23ca3a4196da725c7222f39e594a33b5.png)

The author in vivo shopping mall business, commodity details page interface after the above tuning, the performance of more than 3 times.

Further verify that database switching affects performance by a factor of at least 3 (depending on the business).

Rediscluster, a cluster database with a default 0 library, avoids this problem by not selecting another database.

Be careful of the o(n)Redis command

Redis is single-threaded, so thread-safe.

Redis uses non-blocking IO and most commands have O(1) time complexity.

Using time-consuming commands is very dangerous, consuming a large amount of processing time for a single thread, causing all requests to be slowed down.

For example, get the element smembers mySet of all sets, return all members of the specified Hash, O(N).

The Value set of the cache becomes larger. When there is a high number of interface requests, relevant data will be read from Redis. The reading time of each request becomes longer, and the continuous superposition leads to hot keys, a certain Redis fragment is blocked, and the CPU usage reaches 100%.

6. [Case] Cache hot key

In Redis, hot keys with high access frequency are called hot keys. When a hot key is requested to a Server host, the host resources are insufficient or even break down due to a large number of requests, affecting normal services.

Hot key problems can be caused by the following two causes:

  1. Users consume far more data than they produce, such as hot items or instant hits, hot news, hot comments, etc. These typical scenarios of over-read and under-write will generate hot issues.

  2. If requests are fragmented and exceed the performance limit of a single Server, for example, hashes with a fixed name fall into the same Server and the number of visits exceeds the Server limit, hot keys may occur.

How to identify hot keys in actual services?

  1. Estimate which hot keys are based on business experience;

  2. Client statistics collection, local statistics or report;

  3. If the server has a proxy layer, you can collect and report data at the proxy layer.

Once we identify the hot key, how do we solve the hot key problem?

  1. Redis cluster expansion: Add fragmented copies to balance read traffic.

  2. Hashing hot keys further, such as backing up a key as key1,key2… KeyN: N backups of the same data are distributed to different fragments. During access, one of the N backups can be randomly accessed to further share read traffic.

  3. Use a level 2 cache, or local cache.

When a hot key is discovered, the data corresponding to the hot key is first loaded to the local cache of the application server to reduce read requests to Redis.

Five, Redis specification

1. Disable non-database 0

Description:

Redis-standalone architecture, which prohibits the use of other databases in Redis.

Reason:

  • Maintain compatibility with Redis Cluster for future service migration.

  • When multiple databases are switched with SELECT, more CPU resources are consumed.

  • Easier automatic o&M management. For example, the scan/dbsize command is only used as the database.

  • Some Redis Clients do not support single-instance multi-database due to thread safety issues.

2. Key design specification

According to the business function named key prefix, prevent cover the key conflict, recommended by a colon separated, for example, the business name: name of the table: id:, such as live: rank: user: weekly: 1:2003.

The length of the Key is less than 30 characters. The Key name itself is a String object. Redis hardcodes the maximum length of the Key to 512MB.

In Redis cache scenarios, you are advised to set TTL values for all keys to ensure that unused keys can be cleared or eliminated in a timely manner.

During Key design, do not contain special characters, such as Spaces, line breaks, single and double quotation marks, and other escape characters.

3. Value design specifications

The size of a single Value must be less than 10KB. If the number of single-instance keys is too large, expired keys may not be reclaimed in time.

For complex data types such as set, hash, and list, keep the number of elements in the data structure as low as possible. The recommended number is not more than 1000.

4. Pay attention to command time complexity

The O(1) command, such as get scard, is recommended.

The O(N) command is concerned with the number of N. The following command needs to control the N value on the service level.

  • hgetall

  • lrange

  • smembers

  • zrange

For example, if the time complexity of the smember command is O(n), when n continues to increase, the Redis CPU continues to soar, blocking the execution of other commands.

5, Pipeline use

Description:

Pipeline is a method of batch submission by Redis, that is, multiple command operations are set up and sent to Redis for execution, which is better than a single submission of the loop.

The Redis client executes a command in four stages: send command -> queue command -> execute command -> return result.

Commonly used Mget and Mset commands can effectively save RTT (round-trip time of command execution), but HGEtall does not have MHGEtall, so it does not support batch operation. At this point, you need to use the Pipeline command

For example: in the live broadcast medium station project, it is necessary to query the daily, weekly and monthly rankings of anchors at the same time, submit multiple commands using PIPELINE and return three list data at the same time.

6, online disable command

  • Disallow Monitor

Do not use the monitor command in the production environment. In the case of high concurrency, the monitor command may cause memory explosion and affect Redis performance

  • Disable Keys

The keys operation iterates through all keys and blocks other commands if too many keys result in a slow query. Therefore, disable keys and keys pattern commands.

It is recommended to use scan command instead of keys command online.

  • Prohibit the use of Flushall and Flushdb

Delete all records in all databases in Redis, and this command is atomic, does not terminate execution, once executed, will not fail to execute.

  • Disallow use of Save

Block the current Redis server until the persistence operation is complete, causing prolonged blocking for instances with large memory.

  • BGREWRITEAOF

Manual AOF, manual persistence can cause long periods of blocking for instances with large memory.

  • Config

Config is the client configuration mode, which is not conducive to Redis operation and maintenance. You are advised to set this parameter in the Redis configuration file.

Six, Redis monitoring

1, slow query

** Method 1: **slowlog Obtains slow query logs

127.0.0.1: {port} > slowlog get 5

    1. (integer) 47
  1. (integer) 1533810300

  2. (integer) 175833

    1. “DEL”
  3. “spring:session:expirations:1533810300000”

    1. (integer) 46
  4. (integer) 1533810300

  5. (integer) 117400

    1. “SMEMBERS”

** Method 2: ** More comprehensive slow queries can be monitored using the CacheCloud tool.

Path: “App List “- click on the relevant app name – click on the” Slow Query “Tab.

Click “Slow Query” to focus on the number of slow queries and related commands.

2. Monitor the CPU core usage bound to Redis instances

Because Redis is single-threaded, the focus is on monitoring the CPU core utilization of Redis instance bindings.

Generally, the CPU usage is about 10%. If the CPU usage is higher than 20%, consider whether RDB persistence is used.

3. Redis sharding load balancing

The current Redis-cluster architecture mode, consisting of three masters and three slaves, pays attention to the traffic balancing of each sharded requests in redis-cluster.

To obtain the value, run the redis-cli -p{port} -h{host} –stat command

Generally, an alarm is generated when the value exceeds 12W.

4. Focus on big keys

Through the tools provided by Redis, Redis – CLI periodically scans the corresponding Redis big Key for optimization.

The command is as follows: redis-cli -h 127.0.0.1 -p {port} –bigkeys or redis-memory-for-key -s {IP} -p {port} XXX_KEY

Generally, a key greater than 10K is a large key, which requires special attention. You are advised to optimize the key from the service level.

5. Monitor the memory usage of Redis

The Info memory command is used to avoid performance problems in high-concurrency scenarios when the allocated MaxMemory is used up.

Pay attention to the value of the usED_memory_human configuration item. If the increment is too high, evaluate it.

Seven,

In combination with specific service features, a reasonable evaluation of the memory capacity required by Redis, selection of data types, and setting of single key size can better serve services and provide high performance guarantee for services.

By Jessica Chen