How does Redis query a key from massive data?

How does Redis query a key from massive data?

Use of keys

Syntax:: keys PATTERNUsed to find all the keys that match the given pattern PATTERN

keys * # 查询 redis 中所有的 key

keys h?llo  # ?: 通配单个字符, 可以是 hello hallo ..., 不包含 hllo.

keys h*llo  # * 通配任意多个字符, hllo hello heello heallo ... 

keys h[ae]llo  # []: 通配括号内的某一个字符,可以查询出 hello hallo, 不可以查出 hllo.

keys h[^e]llo  # 匹配 e 之前的字母, 可以是 hallo ... hdllo ,不包含 hello.

keys h[a-b]llo # - 相当于 or, 匹配 a 或 b, 可以是 hallo hbllo; 可以添加更多的条件,比如: keys h[a-b-c-d]llo 

#上面的语法还可以进行相应的组合,如
keys h[a-b]*llo  # 匹配 ha(任意多个字符)llo 和 hb(任意多个字符)llo

Reasons for disabled keys in the official environment

The time complexity of keys is : O(N), where N is the number of keys in the database, assuming that the key names in the database and the length of a given pattern are limited. Although its complexity is O(N), the duration is very short. It can scan 1 million data in 40ms on an entry-level computer.

However, if it is under high concurrency conditions, there will be problems when using keys 因为 Redis 是一个单线程的数据库,每次执行命令都会对数据库进行加锁,并且 keys 命令没有分页功能,每次都会遍历整个数据库. If an operation is executed in 20ms, if it is a million-level concurrency, then Redis will temporarily lock each time a command is executed, which will cause a large number of requests to be Clogging causes other services to be unavailable, which in turn causes high CPU usage, and finally causes server downtime.

Problems with keys:

  1. Without the paging function, all databases will be traversed at one time, and all the key values ​​that meet the conditions will be queried; but the results of the query may be very useful and resource-intensive.

  2. Although the query speed is fast, as the amount of data grows, the query time will become longer.

Use of SCAN

grammar:SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

SCAN is a cursor-based iterator. This means that every time the command is called, the server will return the corresponding query data and a new cursor, and the user needs to use this cursor as the cursor parameter in the next call.

When the cursor is set to 0, the iteration will start, and when the cursor returned by the server is 0, the iteration will end.

Parameter description :

cursor: cursor position, integer value; starting from 0 and ending at 0; the result of the query may be 0, but the cursor is not 0. As long as the cursor is not 0, it means that the traversal has not ended.
match pattern: regular matching field (optional)
count: limit the number of single scan limit hint (equivalent to a small increment), the default is 10. It is not the maximum number of query results returned. For example, a count of 10000 means that 1w records are scanned each time, but there may be only 10 eligible. (Optional)

Precautions:

  1. The cursor is a hash value, which is out of order. A traversal starts from 0 and ends at 0, which means returning to the starting point again.
  2. There is no need to use the same COUNT value for each iteration. As long as the cursor obtained last time is passed in the next traversal, the last COUNT value will be used in the next traversal.
  3. The results returned by scan may have duplicate data, which requires the client to de-duplicate
127.0.0.1:6379> scan 0 match 1* count 15
 1) "17"
 2)  1) "key:12"
     2) "key:18"
     3) "key:14"
     4) "key:14"
     5) "key:16"
     6) "key:17"
     7) "key:15"
     8) "key:10"
     9) "key:13"
    10) "key:17"
    11) "key:1"  # 扫描 15 个元素,但是只有 11 个元素符合
127.0.0.1:6379> scan 17  # count 会使用上一次的 15
 1) "0"    # 游标值为 0,意味着遍历结束
 2) 1) "key:15"
    2) "key:118"
    3) "key:10"
    4) "key:112"
    5) "key:119"
    6) "key:13"
    7) "key:16"
    8) "key:19"    
    9) "key:111"

Blog address: How does Redis query a key from massive data?

Guess you like

Origin blog.csdn.net/peng2hui1314/article/details/105050416
Recommended