美文网首页
Redis-全局命令及键管理

Redis-全局命令及键管理

作者: 取个帅帅的昵称咯 | 来源:发表于2019-10-27 14:14 被阅读0次

    笔记来自:《redis开发与维护》第二章 API的理解和使用
    主要内容:全局命令、键管理、遍历键、数据库管理

    全局命令

    操作 命令
    查看所有键 keys *
    键总数 dbsize
    检查键是否存在 exists key
    删除建 del key [key ...]
    键过期 expire key seconds
    键的数据结构类型 type key
    1. 查看所有键 -- keys *
    H:\Redis>redis-cli.exe -h 127.0.0.1 -p 6379
    127.0.0.1:6379> get hell
    (nil)
    127.0.0.1:6379> get hello
    "world"
    127.0.0.1:6379> set java jedis
    OK
    127.0.0.1:6379> set python redis-py
    OK
    127.0.0.1:6379> keys *
    1) "python"
    2) "java"
    3) "hello"
    
    2. 键总数 -- dbsize
    127.0.0.1:6379> rpush mylist a b c d e f g
    (integer) 7
    127.0.0.1:6379> dbsize
    (integer) 4
    
    3. 检查键是否存在 -- exists key

    存在,返回1,不存,返回0

    127.0.0.1:6379> exists java
    (integer) 1
    127.0.0.1:6379> exists no_exits_key
    (integer) 0
    
    4. 删除键 -- del key [key ...]

    删除成功后,返回删除个数

    127.0.0.1:6379> keys *
    1) "python"
    2) "mylist"
    3) "java"
    4) "hello"
    127.0.0.1:6379> del python java
    (integer) 2
    127.0.0.1:6379> keys *
    1) "mylist"
    2) "hello"
    
    5. 键过期 -- expire key seconds
    127.0.0.1:6379> expire mylist 10
    (integer) 1
    127.0.0.1:6379> ttl mylist
    (integer) 3
    127.0.0.1:6379> ttl mylist
    (integer) -2
    127.0.0.1:6379> exists mylist
    (integer) 0
    

    ttl 命令返回键剩余的过期时间,有三种返回值:

    • 大于等于0的整数:键剩余的过期时间
    • -1: 键设置过期时间
    • -2: 键不存在
    6. 键的数据结构类型 -- type key
    127.0.0.1:6379> set a b
    OK
    127.0.0.1:6379> rpush mylist  a b c d e f g
    (integer) 7
    127.0.0.1:6379> type mylist
    list
    127.0.0.1:6379> type a
    string
    

    2. 数据结构和内部编码

    redis每种数据结构都有两种以上自己底层的内部编码实现
    查询内部编码命令:object encoding
    127.0.0.1:6379> object encoding hello
    "embstr"
    127.0.0.1:6379> rpush mylist a b c d e f g
    (integer) 7
    127.0.0.1:6379> object encoding mylist
    "quicklist"
    
    优点:
    1. 改进内部编码,对外部的数据结构命令没影响
    2. 多种内部编码实现可以在不同场景下各自发挥

    3.单线程架构;

    redis 使用单线程架构I/O多路复用模型来实现高性能的内存数据库服务。

    引出 单线程模型

    开启3个redis-cli客户端同时执行命令,每个客户端都会执行3个步骤:发送命令、执行命令、返回结果三个过程

    所有命令到服务端会进入一个队列,然后被执行

    为什么单线程还能这么快
    存内存访问,redis将所有数据存放内存中
    非阻塞I/O,
    避免切换和竞争产生的消耗

    键管理

    一、单个键管理

    1. 键重命名 -- rename key newkey
    127.0.0.1:6379> get a
    "1"
    127.0.0.1:6379> rename a keya
    OK
    127.0.0.1:6379> get keya
    "1"
    127.0.0.1:6379> get a
    (nil)
    
    

    情况1: 如果b存在,则b键的值也会被覆盖

    127.0.0.1:6379> rename keya b
    OK
    127.0.0.1:6379> get b
    "1"
    127.0.0.1:6379> get keya
    (nil)
    
    

    情况2: 重命名不存键 b ,键返回错误

    127.0.0.1:6379> get b
    (nil)
    127.0.0.1:6379> get keya
    "1"
    127.0.0.1:6379> renamenx b keya
    (error) ERR no such key
    

    注意:

    1. 重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞的可能性

    2. rename和renamenx 的key 和 value 一样,redis 3.2 和之前的版本返回结果不同

      redis3.2版本返回ok,之前的会报错
      127.0.0.1:6379> rename keya keya
      OK
      127.0.0.1:6379> get keya
      "1"
      
    2.随机返回一个键 -- randomkey
    127.0.0.1:6379> dbsize
    (integer) 36
    127.0.0.1:6379> randomkey
    "user:1_2:tags"
    127.0.0.1:6379> randomkey
    "mylist"
    
    3.键过期 -- expire key seconds/expireat key timestamp

    ttl 返回 -1 键没有设置过期时间

    返回-2 键不存

    127.0.0.1:6379> expire d 10
    (integer) 1
    127.0.0.1:6379> ttl d
    (integer) 7
    127.0.0.1:6379> ttl d
    (integer) 3
    127.0.0.1:6379> ttl d
    (integer) 0
    127.0.0.1:6379> ttl d
    (integer) -2
    127.0.0.1:6379> get d
    (nil)
    

    expireat key timestamp 键在秒级时间错过期

    2019-02-13 23:43:30 时间戳 1550072610

    127.0.0.1:6379> expireat c 1550072610
    (integer) 1
    127.0.0.1:6379> ttl c
    (integer) 23
    127.0.0.1:6379> ttl c
    (integer) 21
    127.0.0.1:6379> ttl c
    (integer) -2
    127.0.0.1:6379> get c
    (nil)
    

    注意:

    1. expire key不存在,返回0
    127.0.0.1:6379> expire no_exist_key 10
    (integer) 0
    127.0.0.1:6379> get no_exist_key
    (nil)
    
    1. 过期时间负值,键立即被删除
    127.0.0.1:6379> expire keya -5
    (integer) 1
    127.0.0.1:6379> get keya
    (nil)
    
    1. persist 命名可以将过期时间清除
    127.0.0.1:6379> expire keya 30
    (integer) 1
    127.0.0.1:6379> ttl keya
    (integer) 25
    127.0.0.1:6379> persist keya
    (integer) 1
    127.0.0.1:6379> ttl keya
    (integer) -1
    
    1. set 命令会将设置的过期时间清除掉
    127.0.0.1:6379> set hi world
    OK
    127.0.0.1:6379> expire hi 30
    (integer) 1
    127.0.0.1:6379> ttl hi
    (integer) 24
    127.0.0.1:6379> set hi 10
    OK
    127.0.0.1:6379
    
    1. redis 不支持二级数据结构的过期时间设置,比如哈希、列表内元素的过期设置
    2. setex命令 为set + expire 组合,具有原子性,同时减少一次网络时间
    4. 迁移键 -- move\dump + restore\migrate

    三个命令比较

    命令 作用域 原子性 支持多个建
    move redis示例内部
    dump + restore redis示例之间
    migrate (推荐) redis示例之间
    (1)nove key db

    指定的键从源数据库迁移到目标数据库中,但多数据库功能不建议在生产环境中使用,所以这个命令知道就可以

    (2)dump + restore
    dump key
    restore key ttl value
    

    实现redis实例之间迁移功能,分2步骤:

    1. 在源redis上dump命令,将键值序列化,格式:RDB格式
    2. 在目标redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,ttl=0表示没有过期时间

    示例:

    1. redis-6380 新添key6380 , redis-6379 并不存该key
    127.0.0.1:6380> set key6380 hi6380
    OK
    
    127.0.0.1:6379> get key6380
    (nil)
    
    1. redis-6380 执行dump命令,将key6380的值进行序列化
    127.0.0.1:6380> dump key6380
    "\x00\x06hi6380\a\x00\x88%\xa4k\xa2\xc7\x97n"
    
    1. redis-6379执行restore命令,将key6380的值进行反序列化,保存到内存中
    127.0.0.1:6379> restore key6380 0 "\x00\x06hi6380\a\x00\x88%\xa4k\xa2\xc7\x97n"
    OK
    127.0.0.1:6379> get key6380
    "hi6380"
    

    注意:

    1. 整个过程不是原子性的,是通过客户端分步完成的
    2. 开启两个客户端,所以dump的结果不是在源redis和目标redis之间进行传输
    (3)migrate

    migrate host port key|"" destination-db timeout [COPY] [REPLACE] [KEYS key]

    参数说明:

    • host : 目标redis IP地址

    • port :目标redis 端口

    • key|"" :迁移的键,“”代表 多个迁移键

    • destination-db :目标redis的数据库索引,默认是0

    • timeout :超时时间

    • [COPY] :添加的话,不会删除源redis键

    • [REPLACE]:如果目标redis存在迁移键,则会迁移覆盖数据

    • [KEYS key]:迁移多个键

    用于redis实例之间进行数据迁移,

    dump、restore、del 三个命令组合,简化操作流程

    3点不太相同:

    1. 整个过程是原子执行,只需在源redis上migrate命令
    2. migrate命令的数据直接在源redis目标redis上完成
    3. 目标redis完成restore后会发送ok给源redis, 源redis接受后会根据migrate对应的选项决定是否在源redis删对应的键

    示例:

    1. 情况 源redis有 键key6379 ,目标redis没有
    127.0.0.1:6379> migrate 127.0.0.1 6380 key6379 0 2000 copy replace
    OK
    
    1. 源redis和目标redis都有键key6379, 如果migrate 没加replace参数,则会报错
    127.0.0.1:6379> migrate 127.0.0.1 6380 key6379 0 1000
    (error) ERR Target instance replied with error: BUSYKEY Target key name already exists.
    
    127.0.0.1:6379>  migrate 127.0.0.1 6380 key6379 0 1000 replace
    OK
    
    1. 源redis没有迁移键key6381,则返回nokey
    127.0.0.1:6379> migrate 127.0.0.1 6380 key6381 0 1000
    NOKEY
    

    遍历键

    1. 全量遍历键 -- keys pattern

    pattern 通配符:

    • “*”:任意字符
    • ?:一个字符
    • [] : 部分字符,[1,3] 代表匹配1,3
    • \x : 用来做转义

    示例:

    1. 查找user开头的键
    127.0.0.1:6379> keys user*
     1) "user:2:tags"
     2) "user:ranking:1"
     3) "user:ranking:2"
     4) "user:1:follow"
    ...
    
    1. 查找含tag的键
    127.0.0.1:6379> keys *tags*
    1) "user:2:tags"
    2) "user:3:tags"
    3) "user:1_2:tags"
    4) "user:1:tags"
    

    如果redis包含大量的键,keys命令可能会造成redis阻塞,所以一般不要在生产环境中使用keys命令,以下三种情况使用:

    1. 在一个 不对外提供服务的redis从节点上执行
    2. 如果确认键值总数较少,可以执行该命令
    3. 使用scan渐进式遍历所有键,有效阻止阻塞

    2.渐进式遍历 -- scan cursor [MATCH pattern] [COUNT count]

    scan命令 采取渐进式遍历方式解决keys的阻塞问题

    时间复杂度为O(1),reids存储键值对实际是用hashtable数据结构

    scan的使用方式如下:

    scan cursor [MATCH pattern] [COUNT count]
    

    参数:

    • cursor 必填参数 ,一个游标,第一次遍历时从0开始,每次遍历完返回当前游标值直到游标值为0, 表示遍历结束
    • [MATCH pattern] 可选参数,作用:做模式匹配,跟keys相似
    • [COUNT count] 可选参数,表示每次遍历的键个数,默认值为0

    示例:

    1. 遍历但是redis6379所有键
    127.0.0.1:6379> scan 6
    1) "41"
    2)  1) "user:2:follow"
        2) "article:2"
        3) "user:1_2:union"
        4) "user:3:tags"
        5) "hashkey"
        6) "user:ranking:1_union_2"
        7) "listkey"
        8) "user:ranking:1_inter_2"
        9) "user:ranking:1"
       10) "setkey"
       11) "user:ranking:2"
    127.0.0.1:6379> scan 41
    1) "27"
    2)  1) "myset"
        2) "user:ranking"
        3) "article:3"
        4) "tag1:users"
        5) "hashkey1"
        6) "user:1_2:tags"
        7) "lishkey"
        8) "list:test3"
        9) "testkey"
       10) "user:1"
    127.0.0.1:6379> scan 27
    1) "0"
    2) 1) "user:1:tags"
       2) "article:1"
       3) "user:ranking:20190210"
    

    如果scan过程中如有有键变化(增加、删除、修改),那么遍历可能会出问题:新的键没遍历到,遍历出了重复的键等情况


    数据库管理

    1.切换数据库 -- select index

    redis只是用数字作为多个数据库的实现,redis默认中是16个数据库

    databases 16
    

    0-15号数据库之间是没有任何联系,甚至可以存在相同的键

    127.0.0.1:6379> get hello
    "word"
    127.0.0.1:6379> select 15 # 15号切换数据库
    OK
    127.0.0.1:6379[15]> get hello
    (nil)
    

    如果使用多个数据库功能,可以一台机器上部署多个redis实例,然后用端口来划分,因为现在服务器是多个cpu的,保证了业务不受到影响,合理使用cpu资源

    2.清楚数据库--flushdb/flushall

    两者区别:flushdb只清除当前数据,flushall会清除所有数据库

    127.0.0.1:6379[15]> set hello world15
    OK
    127.0.0.1:6379[15]> keys hello
    1) "hello"
    127.0.0.1:6379[15]> flushdb
    OK
    127.0.0.1:6379[15]> keys
    (error) ERR wrong number of arguments for 'keys' command
    
    # 切到0号数据库,还是有数据
    127.0.0.1:6379[15]> select 0
    OK
    127.0.0.1:6379> get hello
    "word"
    

    flushall 清除所有数据库

    127.0.0.1:6379> flushall
    OK
    127.0.0.1:6379> keys *
    (empty list or set)
    

    flushdb/flushall会将所有数据清除,一旦误操作后果不堪设想

    如果数据库键值数量比较多,存在阻塞redis可能性,一定要小谨慎使用

    --END--
    创作不易,觉得不错的话,欢迎关注、点赞👍或掌赏!

    相关文章

      网友评论

          本文标题:Redis-全局命令及键管理

          本文链接:https://www.haomeiwen.com/subject/eswpvctx.html