精华内容
下载资源
问答
  • 前戏在laravel项目中发现了一个隐藏较深的问题,关于操作redis的increment方法:$key = 'exchange_'.$num;\Cache::increment($key, 1);该方法作用是将$key的值 +1 ,因为在增加之前没有作任何判断,当key不存在时, 内部...

    前戏

    在laravel项目中发现了一个隐藏较深的问题,关于操作redis的increment方法:

    $key = 'exchange_'.$num;

    \Cache::increment($key, 1);

    该方法作用是将$key的值 +1 ,因为在增加之前没有作任何判断,当key不存在时, 内部会初始化这个key出来, 而因为这个key是没有传入过期时间的,导致这些key的过期时间是永久有效,即TTL= -1;

    解决办法是在increment之前先判断是否存在这个key,存在则增加值,不存在则新建key即可

    正文

    问题来了: 由上面产生出来的一堆永久有效的key,如何删除呢?

    有人想到: 用keys 'exchange_*'搜索出来可以吗?

    不可以!KEYS操作在线上是禁止使用的!

    我们知道,Redis是单线程的,如果量很大的话,keys是遍历key的,会导致阻塞,这样其他的客户端就没法连接了!那如何查找?

    使用redis的scan命令 + linux的xargs

    SCAN 命令

    官网对于KEYS命令有一个提示: KEYS 的速度非常快,例如,Redis在一个有1百万个key的数据库里面执行一次查询需要的时间是40毫秒 。但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 KEYS, 你最好还是用 Redis 的集合结构 SETS 来代替。

    但由于KEYS命令一次性返回所有匹配的key,所以,当redis中的key非常多时,对于内存的消耗和redis服务器都是一个隐患,

    对于Redis 2.8以上版本给我们提供了一个更好的遍历key的命令 SCAN 该命令的基本格式:

    SCAN cursor [MATCH pattern] [COUNT count]

    SCAN 每次执行都只会返回少量元素,所以可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令带来的可能会阻塞服务器的问题。

    SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程

    当SCAN命令的游标参数(即cursor)被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。

    COUNT选项

    对于增量式迭代命令不保证每次迭代所返回的元素数量,我们可以使用COUNT选项, 对命令的行为进行一定程度上的调整。COUNT 选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。使用COUNT 选项对于对增量式迭代命令相当于一种提示, 大多数情况下这种提示都比较有效的控制了返回值的数量。

    注意:COUNT选项并不能严格控制返回的key数量,只能说是一个大致的约束。并非每次迭代都要使用相同的 COUNT 值,用户可以在每次迭代中按自己的需要随意改变 COUNT 值, 只要记得将上次迭代返回的游标用到下次迭代里面就可以了。

    MATCH 选项

    类似于KEYS 命令,增量式迭代命令通过给定 MATCH 参数的方式实现了通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。

    MATCH 选项对元素的模式匹配工作是在命令从数据集中取出元素后和向客户端返回元素前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。

    Xargs命令

    xargs指令可以从标准输入读取数据,并利用这些数据“组建”并“执行”指令。它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题。

    语法

    xargs [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null]

    [-d delimiter] [--delimiter delimiter] [-I replace-str]

    [-i[replace-str]] [--replace[=replace-str]] [-l[max-lines]]

    [-L max-lines] [--max-lines[=max-lines]] [-n max-args]

    [--max-args=max-args] [-s max-chars]

    [--max-chars=maxchars] [-P max-procs] [--max-procs=max-procs]

    [--process-slot-var=name] [--interactive] [--verbose] [--exit]

    [--no-run-if-empty] [--arg-file=file] [--show-limits] [--version]

    [--help] [command [initial-arguments]]

    详解

    xargs 从标准输入中读取使用“空格”或“空行”分隔的“数据块”,并以读入的“数据块”作为参数执行命令(默认情况下执行的是 /bin/echo 命令)。需要注意的是,作为参数,从标准输入中读入的“数据块”会跟随在 初始参数(initial-arguments)之后。如果你从标准输入读入的“数据块”中有些空格并非“数据块”的分隔,而是作为“数据块”的一部分出现;你需要把这个些带有空格的“数据块”整体放到单引号或双引号中,当然你也可以在那些“数据块”内部的空格前用反斜杠()进行转义。另外,标准输入中多余的空行会被忽略。

    如果不使用 -n 和 -L 选项,并且没有遇到换行符的情况下,被 xargs 创建的命令的长度是“贪婪”的,直到达到系统限制的长度。而 Command 指令被调用的次数正好是标准输入中“数据块”的行数。通常情况下,命令被调用的次数是小于“数据块”的数量的;这样会在一定程度上提高命令的执行效率。有些指令可以并行执行,请参考 -P 选项。

    在 Unix 系统中,文件名中是可以包含空格和换行符的,如果不对这种“特殊情况”做处理通常是会出问题的;这种在文件名中的空格和换行会被 xargs 当成“数据块”的分隔符处理。在这种情况下可以使用 -0 选项来解决问题。当使用这个-0选项时,你需要确保“数据块”之间使用null字符作为分隔符。例如:当由GNU 的 find 命令提供xargs的“标准输”时,就需要为其(find)提供 -print0 选项来达到目的。

    如果有任何一次 Command 指令的调用以 255 的状态码退出,则xargs会立即停止,并会放弃此后的所有输入。错误信息会输出到“标准错误流”。

    参数说明

    0, --null

    当 xargs 使用此选项时,null字符会被作为“数据块”的分隔符,而引号(单引用和双引号)都不在具有特殊含义(所有的字符都代表他们自己);文件结束符(EOF)也将失效。通常情况下,当“数据块”中包含空格、引号、反斜杠时适合使用此选项,GNU 中的 find 命令 使用 -print0选项时就是这种情况。

    -a file, --arg-file=file

    从文件中读取“数据块”,而非标准输入。如果你使用此选项,除非“标准输入”已经被重定向到 /dev/null,否则,执行命令时不会影响“标准输入”中的数据。

    --delimiter=delim, -d delim

    xargs 命令会以此选项指定的“特定字符”作为“数据块”的分隔符。这个“特定字符”可能是一个“普通字符”,也可能是一个C语言风格的转义字符(如:n,反斜杠后进一个十六进制或八进制数的转义字符);这些转义字符会被 printf 函数处理后再给此选项使用。此选项不支持多字节字符(也即是仅支持ASCII字符集中的字符)。使用此选项后,标准输入中的引号和反斜杠都不再是特殊字符,他们仅代表自身的字面意思。另,-d 选项还会使 文件结束符(EOF)失效,此时xargs 对待文件结束符与其他参数是完全一样的。当“数据块”中包含换行符时你也可以使用此选项来处理;虽然使用 --null 选项是更好的选择。

    -E eof-str

    设置“文件结束符”,xargs 在处理标准输入时,如果遇到“文件结束符”,则其后的所有输入都将被忽略。如果 -E 和 -e 选项都没有被使用,则表示在标准输入中没有字符会被当成“文件结束符”处理。

    -e [eof-str], --eof[=eof-str]

    此选项和 -E 选项的功能是一样一样的。请使用 -E 选项,因为他是符合 POSIX 标准的,而此选项不是。如果使用此选项时 eof-str 被省略了或 -E 和 -e 选项都没有被使用,则表示在标准输入中没有字符会被当成“文件结束符”处理。

    -I replace-str

    用从标准输入中得到“数据块”替换 initial-arguments 中出现的 replace-str。使用此选项后,空格(无论是否在引号中)不会作为“数据块”的分隔符,只有换行会被作为“数据块”的分隔符。使用此选项,同时意味着使用了 -x 和 -L 1 选项。

    -i [replace-str], --replace[=replace-str]

    此选项与 -I 选项的功能是一样的。如果 replace-str 没有被指定,则使用默认值{},此时的功能与 -I {}是一样的。这个选项已经不推荐使用,请使用 -I 选项。

    -L max-lines

    每个命令行最多允许有 max-lines 个非空的输入行。末尾的空白会使一个输入行在逻辑上延伸到下一行。

    使用此选项,同时意味着使用了 -x 选项。

    -l [max-lines], --max-lines[=max-lines]

    此选项和 -L 选项的功能是一样的;不同的是此选项中的 max-lines 参数是可选的。如果 max-lines 没有被指定,则使用默认值 1 。此选项 -l 不已经不赞成被使用,请使用符合 POSIX 标准的 -L 选项代替。

    -n max-args, --max-args=max-args

    每个命令最多允许有 max-args 个参数。如果参数个数达不到 max-args 个,但参数的尺寸超过了限制(请参考 -s选项);此是 xargs 程序将会退出。

    -P max-procs, --max-procs=max-procs

    同时运行 max-procs 个进程,max-procs的默认值是1。如果 max-procs被指定为0,xargs 将会尽可能的运行多个进程。请联同-n或-L选项一起使用,否则可能只会执行一个进程。在 xargs 运行期间,你可以向他发送 SIGUSR1信号量要求增加进程,或发送SIGUSR2信号量要求减少进程。但是你无法把进程数据减少到0,因为最小值是1。xargs 不会中止命令的执行,当要求减少进程时,他会等待,只到有进程执行完成,只是在执行完成的进程想要启动其他进程时会被阻止。

    -p, --interactive

    交互式的运行命令,每个命令运行前都会在终端询问用户是否要执行。只有在用户响应询问时输入y或Y时才会去运行命令。打开此选项的同时,意味着-t选项也被打开了。

    --process-slot-var=name

    在每个子进程中分别设置环境变量name的值为不同的值。如果在某个进程中设置的值与已经存在的进程设置的值重复了,就会退出这个进程。可以用此来做负载均衡。

    -r, --no-run-if-empty

    如果标准输入中没有任何非空的字符,则不运行命令;默认情况下即使标准输入没有非空字符,命令也会被运行一次。这个选项是 GNU 扩展的。

    -s max-chars, --max-chars=max-chars

    一个命令最多包含 max-chars 个字符,包括 命令本身、initial-arguments 和标识字符结束的 nulls 字符。这个最大值是依赖于操作系统的。

    --show-limits

    显示操作系统对命令行长度的限制、xargs对缓冲区大小的选择和-s选项。将输入从/DEV/NULL(也许指定-如果没有空运行),如果你不想让XARGS做任何事情。

    -t, --verbose

    在执行命令之前输出此命令的“标准错误流”。

    -x, --exit

    如果超过 -s 选项指定尺寸,就退出程序。请参考 -s 选项。

    --help

    输出 xargs 命令的帮助信息,然后退出。

    --version

    输出 xargs 命令的版本号,然后退出。

    最终批量删除redis的key语句如下 :

    redis-cli -h host -p 6379 -a pwd -n 15 --scan --pattern 'exchange*' | xargs -0 -n 5000 redis-cli -h host -a pwd -p 6379 -n 15 DEL

    redis-cli参数:

    -h 你的redis服务器地址

    -p 端口 默认6379

    -a 密码

    -n 选择redis对应的db

    xargs参数:

    -n 按每n个为一组输出参数,如果redis的Key数量大的话可以增加此参数,否则会报错 argument list too long

    -0 当key还有引号等特殊字符,加此参数可以屏蔽,使特殊字符失效,不加会报错:

    xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

    by KingFer

    展开全文
  • 在laravel项目中发现了一个隐藏较深的问题,关于操作redis的increment方法: $key = 'exchange_'.$num; \Cache::increment($key, 1); 该方法作用是将$key的值 +1 ,因为在增加之前没有作任何判断,当key不存在时, 内部...
        

    前戏

    在laravel项目中发现了一个隐藏较深的问题,关于操作redis的increment方法:

    $key = 'exchange_'.$num;
    \Cache::increment($key, 1);
    

    该方法作用是将$key的值 +1 ,因为在增加之前没有作任何判断,当key不存在时, 内部会初始化这个key出来, 而因为这个key是没有传入过期时间的,导致这些key的过期时间是永久有效,即TTL= -1;

    解决办法是在increment之前先判断是否存在这个key,存在则增加值,不存在则新建key即可


    正文

    问题来了: 由上面产生出来的一堆永久有效的key,如何删除呢?
    有人想到: 用keys 'exchange_*'搜索出来可以吗?

    不可以!KEYS操作在线上是禁止使用的

    我们知道,Redis是单线程的,如果量很大的话,keys是遍历key的,会导致阻塞,这样其他的客户端就没法连接了!那如何查找?

    使用redis的scan命令 + linux的xargs

    SCAN 命令

    官网对于KEYS命令有一个提示: KEYS 的速度非常快,例如,Redis在一个有1百万个key的数据库里面执行一次查询需要的时间是40毫秒 。但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 KEYS, 你最好还是用 Redis 的集合结构 SETS 来代替。

    但由于KEYS命令一次性返回所有匹配的key,所以,当redis中的key非常多时,对于内存的消耗和redis服务器都是一个隐患,
    对于Redis 2.8以上版本给我们提供了一个更好的遍历key的命令 SCAN 该命令的基本格式:

    SCAN cursor [MATCH pattern] [COUNT count]
    

    SCAN 每次执行都只会返回少量元素,所以可以用于生产环境,而不会出现像 KEYS 或者 SMEMBERS 命令带来的可能会阻塞服务器的问题。
    SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程

    当SCAN命令的游标参数(即cursor)被设置为 0 时, 服务器将开始一次新的迭代, 而当服务器向用户返回值为 0 的游标时, 表示迭代已结束。

    COUNT选项

    对于增量式迭代命令不保证每次迭代所返回的元素数量,我们可以使用COUNT选项, 对命令的行为进行一定程度上的调整。COUNT 选项的作用就是让用户告知迭代命令, 在每次迭代中应该从数据集里返回多少元素。使用COUNT 选项对于对增量式迭代命令相当于一种提示, 大多数情况下这种提示都比较有效的控制了返回值的数量。

    注意:COUNT选项并不能严格控制返回的key数量,只能说是一个大致的约束。并非每次迭代都要使用相同的 COUNT 值,用户可以在每次迭代中按自己的需要随意改变 COUNT 值, 只要记得将上次迭代返回的游标用到下次迭代里面就可以了。

    MATCH 选项

    类似于KEYS 命令,增量式迭代命令通过给定 MATCH 参数的方式实现了通过提供一个 glob 风格的模式参数, 让命令只返回和给定模式相匹配的元素。

    MATCH 选项对元素的模式匹配工作是在命令从数据集中取出元素后和向客户端返回元素前的这段时间内进行的, 所以如果被迭代的数据集中只有少量元素和模式相匹配, 那么迭代命令或许会在多次执行中都不返回任何元素。


    Xargs命令

    xargs指令可以从标准输入读取数据,并利用这些数据“组建”并“执行”指令。它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题。

    语法

     xargs  [-0prtx]  [-E  eof-str]  [-e[eof-str]]  [--eof[=eof-str]]  [--null] 
      [-d  delimiter]  [--delimiter  delimiter]  [-I  replace-str]  
      [-i[replace-str]] [--replace[=replace-str]] [-l[max-lines]] 
      [-L max-lines] [--max-lines[=max-lines]] [-n max-args] 
      [--max-args=max-args]  [-s  max-chars] 
      [--max-chars=maxchars]  [-P  max-procs]  [--max-procs=max-procs] 
      [--process-slot-var=name]  [--interactive]  [--verbose]  [--exit]  
      [--no-run-if-empty]  [--arg-file=file] [--show-limits] [--version] 
      [--help] [command [initial-arguments]]
    

    详解

    xargs 从标准输入中读取使用“空格”或“空行”分隔的“数据块”,并以读入的“数据块”作为参数执行命令(默认情况下执行的是 /bin/echo 命令)。需要注意的是,作为参数,从标准输入中读入的“数据块”会跟随在 初始参数(initial-arguments)之后。如果你从标准输入读入的“数据块”中有些空格并非“数据块”的分隔,而是作为“数据块”的一部分出现;你需要把这个些带有空格的“数据块”整体放到单引号或双引号中,当然你也可以在那些“数据块”内部的空格前用反斜杠()进行转义。另外,标准输入中多余的空行会被忽略。

    如果不使用 -n 和 -L 选项,并且没有遇到换行符的情况下,被 xargs 创建的命令的长度是“贪婪”的,直到达到系统限制的长度。而 Command 指令被调用的次数正好是标准输入中“数据块”的行数。通常情况下,命令被调用的次数是小于“数据块”的数量的;这样会在一定程度上提高命令的执行效率。有些指令可以并行执行,请参考 -P 选项。

    在 Unix 系统中,文件名中是可以包含空格和换行符的,如果不对这种“特殊情况”做处理通常是会出问题的;这种在文件名中的空格和换行会被 xargs 当成“数据块”的分隔符处理。在这种情况下可以使用 -0 选项来解决问题。当使用这个-0选项时,你需要确保“数据块”之间使用null字符作为分隔符。例如:当由GNU 的 find 命令提供xargs的“标准输”时,就需要为其(find)提供 -print0 选项来达到目的。

    如果有任何一次 Command 指令的调用以 255 的状态码退出,则xargs会立即停止,并会放弃此后的所有输入。错误信息会输出到“标准错误流”。

    参数说明

    0, --null
    当 xargs 使用此选项时,null字符会被作为“数据块”的分隔符,而引号(单引用和双引号)都不在具有特殊含义(所有的字符都代表他们自己);文件结束符(EOF)也将失效。通常情况下,当“数据块”中包含空格、引号、反斜杠时适合使用此选项,GNU 中的 find 命令 使用 -print0选项时就是这种情况。

    -a file, --arg-file=file
    从文件中读取“数据块”,而非标准输入。如果你使用此选项,除非“标准输入”已经被重定向到 /dev/null,否则,执行命令时不会影响“标准输入”中的数据。

    --delimiter=delim, -d delim
    xargs 命令会以此选项指定的“特定字符”作为“数据块”的分隔符。这个“特定字符”可能是一个“普通字符”,也可能是一个C语言风格的转义字符(如:n,反斜杠后进一个十六进制或八进制数的转义字符);这些转义字符会被 printf 函数处理后再给此选项使用。此选项不支持多字节字符(也即是仅支持ASCII字符集中的字符)。使用此选项后,标准输入中的引号和反斜杠都不再是特殊字符,他们仅代表自身的字面意思。另,-d 选项还会使 文件结束符(EOF)失效,此时xargs 对待文件结束符与其他参数是完全一样的。当“数据块”中包含换行符时你也可以使用此选项来处理;虽然使用 --null 选项是更好的选择。

    -E eof-str
    设置“文件结束符”,xargs 在处理标准输入时,如果遇到“文件结束符”,则其后的所有输入都将被忽略。如果 -E 和 -e 选项都没有被使用,则表示在标准输入中没有字符会被当成“文件结束符”处理。

    -e [eof-str], --eof[=eof-str]
    此选项和 -E 选项的功能是一样一样的。请使用 -E 选项,因为他是符合 POSIX 标准的,而此选项不是。如果使用此选项时 eof-str 被省略了或 -E 和 -e 选项都没有被使用,则表示在标准输入中没有字符会被当成“文件结束符”处理。

    -I replace-str
    用从标准输入中得到“数据块”替换 initial-arguments 中出现的 replace-str。使用此选项后,空格(无论是否在引号中)不会作为“数据块”的分隔符,只有换行会被作为“数据块”的分隔符。使用此选项,同时意味着使用了 -x 和 -L 1 选项。

    -i [replace-str], --replace[=replace-str]
    此选项与 -I 选项的功能是一样的。如果 replace-str 没有被指定,则使用默认值{},此时的功能与 -I {}是一样的。这个选项已经不推荐使用,请使用 -I 选项。

    -L max-lines
    每个命令行最多允许有 max-lines 个非空的输入行。末尾的空白会使一个输入行在逻辑上延伸到下一行。
    使用此选项,同时意味着使用了 -x 选项。

    -l [max-lines], --max-lines[=max-lines]
    此选项和 -L 选项的功能是一样的;不同的是此选项中的 max-lines 参数是可选的。如果 max-lines 没有被指定,则使用默认值 1 。此选项 -l 不已经不赞成被使用,请使用符合 POSIX 标准的 -L 选项代替。

    -n max-args, --max-args=max-args
    每个命令最多允许有 max-args 个参数。如果参数个数达不到 max-args 个,但参数的尺寸超过了限制(请参考 -s选项);此是 xargs 程序将会退出。

    -P max-procs, --max-procs=max-procs
    同时运行 max-procs 个进程,max-procs的默认值是1。如果 max-procs被指定为0,xargs 将会尽可能的运行多个进程。请联同-n或-L选项一起使用,否则可能只会执行一个进程。在 xargs 运行期间,你可以向他发送 SIGUSR1信号量要求增加进程,或发送SIGUSR2信号量要求减少进程。但是你无法把进程数据减少到0,因为最小值是1。xargs 不会中止命令的执行,当要求减少进程时,他会等待,只到有进程执行完成,只是在执行完成的进程想要启动其他进程时会被阻止。

    -p, --interactive
    交互式的运行命令,每个命令运行前都会在终端询问用户是否要执行。只有在用户响应询问时输入y或Y时才会去运行命令。打开此选项的同时,意味着-t选项也被打开了。

    --process-slot-var=name
    在每个子进程中分别设置环境变量name的值为不同的值。如果在某个进程中设置的值与已经存在的进程设置的值重复了,就会退出这个进程。可以用此来做负载均衡。

    -r, --no-run-if-empty
    如果标准输入中没有任何非空的字符,则不运行命令;默认情况下即使标准输入没有非空字符,命令也会被运行一次。这个选项是 GNU 扩展的。

    -s max-chars, --max-chars=max-chars
    一个命令最多包含 max-chars 个字符,包括 命令本身、initial-arguments 和标识字符结束的 nulls 字符。这个最大值是依赖于操作系统的。

    --show-limits
    显示操作系统对命令行长度的限制、xargs对缓冲区大小的选择和-s选项。将输入从/DEV/NULL(也许指定-如果没有空运行),如果你不想让XARGS做任何事情。

    -t, --verbose
    在执行命令之前输出此命令的“标准错误流”。

    -x, --exit
    如果超过 -s 选项指定尺寸,就退出程序。请参考 -s 选项。

    --help
    输出 xargs 命令的帮助信息,然后退出。

    --version
    输出 xargs 命令的版本号,然后退出。


    最终批量删除redis的key语句如下 :

    redis-cli -h host -p 6379 -a pwd -n 15 --scan --pattern 'exchange*' | xargs -0 -n 5000 redis-cli -h host -a pwd -p 6379 -n 15 DEL
    

    redis-cli参数:
    -h 你的redis服务器地址
    -p 端口 默认6379
    -a 密码
    -n 选择redis对应的db

    xargs参数:
    -n 按每n个为一组输出参数,如果redis的Key数量大的话可以增加此参数,否则会报错 argument list too long
    -0 当key还有引号等特殊字符,加此参数可以屏蔽,使特殊字符失效,不加会报错:
    xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

    by KingFer

    展开全文
  • 如何批量删除redis的key

    千次阅读 2015-05-04 16:22:13
    如何批量删除redis的key看似比较简单,但有些值得注意的地方: 在linux环境: shell>redis-cli -a password keys "tmatch*"|xargs redis-cli -a password del 在windows环境: shell>redis-cli.exe -a ...

    如何批量删除redis中的key看似比较简单,但有些值得注意的地方:

    在linux环境:

    shell>redis-cli -a password keys "tmatch*"|xargs redis-cli -a password del


    在windows环境:

    shell>redis-cli.exe -a password keys "[0-9]*"|xargs \fullpathto\redis-cli.exe -a password del


    值得注意的点:第一,在redis设置了password的时候,所有关于redis的操作需要输入密码。第二,在windows系统中xargs后面的redis-cli.exe的路径必须是绝对路径。第三,redis批量删除支持正则表达式,可以利用正则表达式简化操作。


    展开全文
  • 优雅地删除 Redis bigkey

    2020-05-23 18:18:19
    文章目录redis bigkey的定义直接删除Key的风险如何优雅地删除各类大KeyHash KeySet KeyList KeySorted set key redis bigkey的定义 关于Redis大键(Key),我们从[空间复杂性]和访问它[时间复杂度]两个方面来定义...

    redis bigkey的定义

    关于Redis大键(Key),我们从[空间复杂性]和访问它的[时间复杂度]两个方面来定义大键。
    前者主要表示Redis键的占用内存大小;后者表示Redis集合数据类型(set/hash/list/sorted set)键,所含有的元素个数。以下两个示例:

    • 1个大小200MB的String键(String Object最大512MB);内存空间角度占用较大
    • 1个包含100000000(1kw)个字段的Hash键,对应访问模式(如hgetall)时间复杂度高

    因为内存空间复杂性处理耗时都非常小,测试 del 200MB String键耗时约1毫秒,
    而删除一个含有1kw个字段的Hash键,却会阻塞Redis进程数十秒。所以本文只从时间复杂度分析大的集合类键。删除这种大键的风险,以及怎么优雅地删除。

    在Redis集群中,应用程序尽量避免使用大键;直接影响容易导致集群的容量和请求出现”倾斜问题“,具体分析见文章:redis-cluster-imbalance。但在实际生产过程中,总会有业务使用不合理,出现这类大键;当DBA发现后推进业务优化改造,然后删除这个大键;如果直接删除它,DEL命令可能阻塞Redis进程数十秒,对应用程序和Redis集群可用性造成严重的影响。

    直接删除大Key的风险

    DEL命令在删除单个集合类型的Key时,命令的时间复杂度是O(M),其中M是集合类型Key包含的元素个数。

    DEL key
    Time complexity: O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).

    生产环境中遇到过多次因业务删除大Key,导致Redis阻塞,出现故障切换和应用程序雪崩的故障。
    测试删除集合类型大Key耗时,一般每秒可清理100w~数百w个元素; 如果数千w个元素的大Key时,会导致Redis阻塞上10秒
    可能导致集群判断Redis已经故障,出现故障切换;或应用程序出现雪崩的情况。

    说明:Redis是单线程处理。
    单个耗时过大命令,导致阻塞其他命令,容易引起应用程序雪崩或Redis集群发生故障切换。
    所以避免在生产环境中使用耗时过大命令。

    Redis删除大的集合键的耗时, 测试估算,可参考;和硬件环境、Redis版本和负载等因素有关

    Key类型	    Item数量	    耗时
    Hash	    ~100万	    ~1000ms
    List	    ~100万	    ~1000ms
    Set	        ~100万	    ~1000ms
    Sorted Set	~100万	    ~1000ms
    

    当我们发现集群中有大key时,要删除时,如何优雅地删除大Key?

    如何优雅地删除各类大Key

    从Redis2.8版本开始支持SCAN命令,通过m次时间复杂度为O(1)的方式,遍历包含n个元素的大key.
    这样避免单个O(n)的大命令,导致Redis阻塞。 这里删除大key操作的思想也是如此。

    Hash Key

    通过hscan命令,每次获取500个字段,再用hdel命令,每次删除1个字段。
    Python代码:

    def del_large_hash():
      r = redis.StrictRedis(host='redis-host1', port=6379)
        large_hash_key ="xxx" #要删除的大hash键名
        cursor = '0'
        while cursor != 0:
            cursor, data = r.hscan(large_hash_key, cursor=cursor, count=500)
            for item in data.items():
                    r.hdel(large_hash_key, item[0])
    

    Set Key

    删除大set键,使用sscan命令,每次扫描集合中500个元素,再用srem命令每次删除一个键
    Python代码:

    def del_large_set():
      r = redis.StrictRedis(host='redis-host1', port=6379)
      large_set_key = 'xxx'   # 要删除的大set的键名
      cursor = '0'
      while cursor != 0:
        cursor, data = r.sscan(large_set_key, cursor=cursor, count=500)
        for item in data:
          r.srem(large_size_key, item)
    

    List Key

    删除大的List键,未使用scan命令; 通过ltrim命令每次删除少量元素。
    Python代码:

    def del_large_list():
      r = redis.StrictRedis(host='redis-host1', port=6379)
      large_list_key = 'xxx'  #要删除的大list的键名
      while r.llen(large_list_key)>0:
          r.ltrim(large_list_key, 0, -101) #每次只删除最右100个元素
    

    Sorted set key

    删除大的有序集合键,和List类似,使用sortedset自带的zremrangebyrank命令,每次删除top 100个元素。
    Python代码:

    def del_large_sortedset():
      r = redis.StrictRedis(host='large_sortedset_key', port=6379)
      large_sortedset_key='xxx'
      while r.zcard(large_sortedset_key)>0:
        r.zremrangebyrank(large_sortedset_key,0,99)#时间复杂度更低 , 每次删除O(log(N)+100)
    

    Redis Lazy Free
    应该从3.4版本开始,Redis会支持lazy delete free的方式,删除大键的过程不会阻塞正常请求。

    转自:
    https://toutiao.io/posts/50yn2h/preview

    展开全文
  • 如何删除Redis所有key 如何删除Redis所有内容 我要删除所有key。,然后给我一个空白数据库。 有没有办法在Redis客户端中做到这一点? 使用redis-cli: FLUSHDB–从连接当前数据库中删除所有密钥...
  • 默认情况下,Redis的key是永久的,除非手动将其删除。但是,在某些业务场景下,你需要让某些key在一定时间后自动失效,或者被删除。这里我们简单说说如何设置key的expire时间,以及如何管理key的expire设置。说明...
  • 背景因为更换IDC的原因,...那么问题来了,如何快速删除1.2亿的key呢?如何获取指定的 key大家都知道由于Redis的单线程服务模式,命令keys *会阻塞正常的业务请求,所以肯定不行。在这里我们利用Redis 提供的SCAN功能...
  • 删除单个集合类型的Key时,命令的时间复杂度是O(M),其中M是集合类型Key包含的元素个数。 DEL keyTime complexity: O(N) where N is the number of keys that will be removed. When a key to remove holds...
  • 问题出现 一个平坦无奇工作日,领导到我工位和我说,“有一个 redis 慢操作,你这几天有时间帮忙解决一下。...redis 慢操作已经有了,如果没有,我们可以自己去 redis 服务器查看历史慢日.
  • 说道问题,先说一个场景吧,便于大家理解。在很久之前,PM打来电话说问答用户反馈说...说道这里,或许又会有朋友说这是一个 XXX坑了, 也不能尽然这么描述,这个问题是确实存在的,咱们来梳理下Redis的删除机制。re...
  • 借助 Linux xargs 指令来完成 ...2 //如果redis-cli没有设置成系统变量,需要指定redis-cli完整路径 1 //带密码 2 redis-cli -a password keys "*" | xargs redis-cli -a password...
  • Redis如何淘汰过期keys: set name wx 3600惰性删除概念:当一些客户端尝试访问它时,key会被发现并主动过期放任键过期不管,但是每次从键空间中获取键时,都检查取得键是否过期,如果过期话,就删除该键...
  • 问题出现一个平淡无奇工作日,领导到我工位和我说,“有一个 redis 慢操作,你这几天有时间帮忙解决一下。”“好。”,管他什么问题,既然让我做,我自然觉得自己能搞定。然后我收到一封 redis 慢操作 excel...
  • 问题出现一个平坦无奇工作日,领导到我工位和我说,“有一个 redis 慢操作,你这几天有时间帮忙解决一下。”“好。”,管他什么问题,既然让我做,我自然觉得自己能搞定。然后我收到一封 redis 慢操作 excel...
  • 前言还在用keys命令模糊匹配删除数据吗?...可能你一通搜索后会得到下边的答案redis-cli --raw keys "ops-coffee-*" | xargs redis-cli del直接在linux下通过redis的keys命令匹配到所有的key,然后调用系统命令xarg...
  • 问题出现一个平坦无奇工作日,领导到我工位和我说,“有一个 redis 慢操作,你这几天有时间帮忙解决一下。”“好。”,管他什么问题,既然让我做,我自然觉得自己能搞定。然后我收到一封 redis 慢操作 excel...
  • 主要给大家介绍了关于Redis如何优雅的删除特定前缀key的相关资料,文中通过示例代码介绍非常详细,对大家学习或者使用Redis具有一定参考学习价值,需要朋友们下面来一起学习学习吧
  • 作者:个推数据库工程师 嘉木个推作为国内第三方推送市场早期进入者,专注于为开发者提供高效稳定推送服务,经过9年积累和发展,服务了包括新浪、滴滴在内数十...本文将对大key的发现、解决大key删除造成...
  • 问题出现一个平坦无奇工作日,领导到我工位和我说,“有一个 redis 慢操作,你这几天有时间帮忙解决一下。”“好。”,管他什么问题,既然让我做,我自然觉得自己能搞定。然后我收到一封 redis 慢操作 excel...
  • 生产上由于业务设计原因,有一些500M的Hash Key,现在已经没有用了,需要删除,如果直接删除会造成Redis的卡顿影响线上正常的业务。那么处理有两个方案: 在一个夜深人静的时刻,流量低点进行操作(运维真是苦逼啊!...
  • 一、在Redis中,假如我们设置了100w个key,这些key设置了只能存活2个小时,那么在2个小时后,redis如何删除这些key的?答案:定期删除 and 惰性删除。那什么是定期删除?什么惰性删除?靠这两种策略就可以删除...
  • keys在测试环境使用redis的时候,经常会要批量删除key,我们但是redis并没有提供批量删除的命令,但是我们可以在命令行下,使用keys遍历键实现//批量删除以video开头的keyredis-clikeysvideo*|xargsredis-clidel//以...

空空如也

空空如也

1 2 3 4 5 ... 18
收藏数 351
精华内容 140
关键字:

如何删除redis的key

redis 订阅