Redis入门

Redis入门

概述

Redis 是什么?

Redis (Remote Dictionary Server) 远程字典服务!

image-20200926203935390

环境安装

Windows安装

  1. 下载安装包:https://github.com/dmajkic/redis/releases
  2. 下载完毕得到压缩包:image-20200926204951670
  3. 解压到指定路径下:image-20200926205232440
  4. 运行服务image-20200926205355538
  5. 使用客户端连接image-20200926205501697

Linux 安装(推荐)

  1. 下载安装包:http://download.redis.io/releases/redis-6.0.6.tar.gz

  2. 上传到服务器并解压:

    tar -zxvf redis-6.0.6.tar.gz #解压安装文件
    cd redis-6.0.6 #进入解压后文件夹
    make #解释makefile
    cd src #进入src文件夹
    make install #安装
    
  3. 启动服务

    cd /usr/redis-server/bin #进入默认目录
    ./redis-server redis.conf #以redis.conf配置启动服务
    
  4. 检查服务是否启动

    ps -ef | grep redis
    root       1181      1  0 10:11 ?        00:00:16 ./redis-server 0.0.0.0:6379
    root       1400   1317  0 13:44 pts/3    00:00:00 ./redis-cli
    root       1422   1358  0 14:15 pts/0    00:00:00 grep --color=auto redis
    
  5. 使用客户端

    ./redis-cli  #执行客户端程序
    127.0.0.1:6379> auth 123456 #登录密码
    OK
    127.0.0.1:6379> 
    

性能测试

使用Redis自带的测试工具 redis-benchmark

  1. 指令参数:image-20200926213850217

  2. 测试使用:

    # 测试 100并发客户端 100000请求
    redis-benchmark -h localhost -p 6379 -c 100 -n 100000
    ====== PING_INLINE ====== #ping指令测试
     100000 requests completed in 2.35 seconds #2.35秒内完成100000次请求
      100 parallel clients #100个并发客户端
      3 bytes payload #每次写入3字节大小
      keep alive: 1 #单机测试
    
    15.66% <= 1 milliseconds
    83.97% <= 2 milliseconds
    95.53% <= 3 milliseconds
    98.07% <= 4 milliseconds
    98.79% <= 5 milliseconds
    99.17% <= 6 milliseconds
    99.26% <= 7 milliseconds
    99.36% <= 8 milliseconds
    99.49% <= 9 milliseconds
    99.54% <= 10 milliseconds
    99.63% <= 11 milliseconds
    99.65% <= 12 milliseconds
    99.70% <= 13 milliseconds
    99.72% <= 14 milliseconds
    99.75% <= 15 milliseconds
    99.85% <= 16 milliseconds
    99.87% <= 17 milliseconds
    99.88% <= 18 milliseconds
    99.91% <= 20 milliseconds
    99.94% <= 21 milliseconds
    99.96% <= 22 milliseconds
    99.97% <= 30 milliseconds
    99.98% <= 31 milliseconds
    100.00% <= 31 milliseconds #31毫秒内完成
    42517.01 requests per second #每秒请求42517.01次
    
    

了解一些常用指令

数据库切换

127.0.0.1:6379> select 5 #切换到5号数据库
OK
127.0.0.1:6379[5]> select 8 #切换到8号数据库
OK
127.0.0.1:6379[8]> select 0 #切换到0号数据库,默认使用的就是0号数据库
OK

查看所有的key

127.0.0.1:6379> keys * #查看所有的key  key数据量少的情况下可以使用
 1) "n10"
 2) "n9"
 3) "n4"
 4) "n11"
 5) "name"
 6) "n6"
 7) "n2"
 8) "n7"
 9) "n12"
10) "n3"
11) "n13"
12) "n5"
13) "n1"
14) "n8"

判断key是否存在

127.0.0.1:6379> exists name #判断name这个key是否存在
(integer) 1

设置到期时间

127.0.0.1:6379> expire name 10 #设定name10秒到期
(integer) 1
127.0.0.1:6379> ttl name #查看剩余到期时间
(integer) 3
127.0.0.1:6379> exists name #到期后,key清除
(integer) 0

查看key类型

127.0.0.1:6379> type n1 #查看指定key的类型
string

清除指令(慎用)

127.0.0.1:6379> flushdb #清除当前数据库
OK
127.0.0.1:6379> flushall #清除所有数据库
OK

基本数据类型

String(字符串)

###################基础用法########################
127.0.0.1:6379> set key hello #设置值
OK
127.0.0.1:6379> get key #获取值
"hello"
127.0.0.1:6379> exists key #判断指定key是否存在
(integer) 1
127.0.0.1:6379> keys * #获取所有key  注意:如果key的数量很大,会造成redis阻塞
1) "key"
127.0.0.1:6379> append key " world" #追加值
(integer) 11
127.0.0.1:6379> get key #获取追加后的值
"hello world"
127.0.0.1:6379> strlen key #获取值的长度
(integer) 11

###################自增自减########################
127.0.0.1:6379> set age 10 #设置age为010
OK
127.0.0.1:6379> incr age #自增1
(integer) 11
127.0.0.1:6379> incrby age 10 #自增10
(integer) 21
127.0.0.1:6379> decr age #自减1
(integer) 20
127.0.0.1:6379> decrby age 10 #自减10
(integer) 10

###################范围获取########################
127.0.0.1:6379> getrange key 0 3 #获取范围内的值
"hell"
127.0.0.1:6379> getrange key 0 -1 #获取所有的值
"hello world"

###################替换########################
127.0.0.1:6379> get key #获取原始值
"hello world"
127.0.0.1:6379> setrange key 10 d!! #替换新值
(integer) 13
127.0.0.1:6379> get key #获取新值
"hello world!!"

###################设置到期时长########################
127.0.0.1:6379> get age #获取原始值
"10"
127.0.0.1:6379> setex age 5 #设置5秒到期
(integer) 1
127.0.0.1:6379> ttl age #查看剩余时长
(integer) 2
127.0.0.1:6379> get age #key到期,无法获取
(nil)

###################不存在则创建########################
127.0.0.1:6379> setnx name jack #设置name
(integer) 1
127.0.0.1:6379> get name #获取name
"jack"
127.0.0.1:6379> setnx name james #再次设置name,此次设置未成功
(integer) 0
127.0.0.1:6379> get name #查看还是旧值
"jack"

###################批量设值########################
127.0.0.1:6379> mset name jack age 25 sex man height 185 #批量设置多个key
OK
127.0.0.1:6379> get name #获取name
"jack"
127.0.0.1:6379> get age #获取age
"25"
127.0.0.1:6379> get sex #获取sex
"man"
127.0.0.1:6379> get height #获取height
"185"

###################getset########################
127.0.0.1:6379> get age #获取age
"25"
127.0.0.1:6379> getset age 30 #先get旧值后set新值
"25"
127.0.0.1:6379> get age #获取age
"30"

List(列表)

###################压入值########################
127.0.0.1:6379> lpush list one #左侧插入one
(integer) 1
127.0.0.1:6379> lpush list two #左侧插入two
(integer) 2
127.0.0.1:6379> lpush list three #左侧插入three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取所有元素
1) "three"
2) "two"
3) "one"

###################弹出值########################
127.0.0.1:6379> rpop list #右侧弹出
"one"
127.0.0.1:6379> lrange list 0 -1 #获取所有元素
1) "three"
2) "two"

###################根据下标获取值########################
127.0.0.1:6379> lindex list 0 #获取下标为0 的值
"three"

###################获取列表长度########################
127.0.0.1:6379> llen list #长度为2
(integer) 2

###################移除指定值########################
127.0.0.1:6379> lrange list 0 -1 #获取list的元素
1) "three"
2) "two"
127.0.0.1:6379> lpush list three #左侧添加新元素
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取list的元素
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 2 three #左侧移除2个three元素
(integer) 2
127.0.0.1:6379> lrange list 0 -1 #获取list的元素
1) "two"

###################rpoplpush########################
127.0.0.1:6379> lrange list 0 -1 #获取list中的元素
1) "two"
127.0.0.1:6379> rpoplpush list newlist #执行rpoplpus指令
"two"
127.0.0.1:6379> lrange list 0 -1 #获取list中的元素
(empty list or set)
127.0.0.1:6379> lrange newlist 0 -1 #获取newlist中的元素
1) "two"

###################根据下标设置值########################
127.0.0.1:6379> lrange newlist 0 -1 #获取newlist中的元素
1) "two"
127.0.0.1:6379> lset newlist 0 one #set之newlist中index为0的元素
OK
127.0.0.1:6379> lrange newlist 0 -1 #获取newlist中的元素
1) "one"

###################在某个元素之前或者之后添加元素########################
127.0.0.1:6379> lrange newlist 0 -1 #获取newlist中的元素
1) "one"
127.0.0.1:6379> linsert newlist before one two #在one元素之前添加元素two
(integer) 2
127.0.0.1:6379> lrange newlist 0 -1 #获取newlist中的元素
1) "two"
2) "one"

总结:List(列表) 是可以在两端压入和弹出元素,根据index修改和移除元素,在指定元素之前和之后添加元素

Set(集合)

注意:类似数学中的概念,Set中不能有重复元素

###################添加元素########################
127.0.0.1:6379> sadd set one two three four five sax #添加元素
127.0.0.1:6379> smembers set #遍历所有元素
1) "two"
2) "one"
3) "four"
4) "sax"
5) "three"
6) "five"

###################删除元素########################
127.0.0.1:6379> smembers set #获取set中原有元素
1) "two"
2) "one"
3) "four"
4) "sax"
5) "three"
6) "five"
127.0.0.1:6379> srem set one #移除指定元素
(integer) 1
127.0.0.1:6379> smembers set #获取set中原有元素
1) "four"
2) "two"
3) "sax"
4) "three"
5) "five"

###################判断是否包含指定元素########################
127.0.0.1:6379> smembers set #获取set中所有元素
1) "four"
2) "two"
3) "sax"
4) "three"
5) "five"
127.0.0.1:6379> sismember set one #判断是否包含one元素
(integer) 0

###################统计元素个数########################
127.0.0.1:6379> scard set 
(integer) 5

###################随机获取(不删除)########################
127.0.0.1:6379> SRANDMEMBER set 1 #随机获取一个元素
1) "five"
127.0.0.1:6379> SRANDMEMBER set 2 #随机获取两个元素
1) "four"
2) "sax"

###################随机获取(删除)########################
127.0.0.1:6379> SMEMBERS set #遍历set中所有元素
1) "four"
2) "two"
3) "sax"
4) "three"
5) "five"
127.0.0.1:6379> spop set 1 #随机弹出一个元素
1) "sax"
127.0.0.1:6379> spop set 2 #随机弹出两个元素
1) "two"
2) "three"
127.0.0.1:6379> SMEMBERS set #遍历set中所有元素
1) "four"
2) "five"

###################将集合中指定元素移动到另一个集合中########################
127.0.0.1:6379> sadd class:1 jack james #添加元素到class:1
(integer) 2
127.0.0.1:6379> sadd class:2 peter mark #添加元素到class:2
(integer) 2
127.0.0.1:6379> smembers class:1 #遍历class:1中元素
1) "jack"
2) "james"
127.0.0.1:6379> SMEMBERS class:2 #遍历class:2中元素
1) "peter"
2) "mark"
127.0.0.1:6379> SMOVE class:1 class:2 jack #将class:1中的jack移动到class:2中
(integer) 1
127.0.0.1:6379> SMEMBERS class:1 #遍历class:1中元素
1) "james"
127.0.0.1:6379> SMEMBERS class:2 #遍历class:2中元素
1) "jack"
2) "peter"
3) "mark"

###################交集、并集、差集########################
127.0.0.1:6379> sadd one 1 2 3 4 #添加1 2 3 4 到one集合中
(integer) 4
127.0.0.1:6379> sadd two 3 4 5 6 #添加3 4 5 6 到two集合中
(integer) 4
127.0.0.1:6379> sdiff one two #获取one和two的差集
1) "1"
2) "2"
127.0.0.1:6379> SINTER one two #获取one和two的交集
1) "3"
2) "4"
127.0.0.1:6379> SUNION one two #获取one和two的并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

Hash(哈希)

可以认为 key-map结构

###################添加元素、获取元素、删除元素、########################
127.0.0.1:6379> hset user name zhangsan age 10 height 175 #设置多个属性值
(integer) 3
127.0.0.1:6379> hget user name #获取name属性值
"zhangsan"
127.0.0.1:6379> hdel user name #删除name属性值
(integer) 1
127.0.0.1:6379> hget user name #再次获取name属性值,发现已删除
(nil)
127.0.0.1:6379> hmget user name age height #批量获取多个属性值
1) (nil)
2) "10"
3) "175"
127.0.0.1:6379> hgetall user #获取所有属性值
1) "age"
2) "10"
3) "height"
4) "175"

###################获取hash表中属性个数########################
127.0.0.1:6379> hlen user #获取hash表的长度
(integer) 2

###################判断hash表中是否包含指定元素########################
127.0.0.1:6379> hexists user name #判断hash表中是否有name
(integer) 0

###################获取所有key或values########################
127.0.0.1:6379> hkeys user #获取hash包中所有的key
1) "age"
2) "height"
127.0.0.1:6379> hvals user #获取hash表中所有的value
1) "10"
2) "175"

###################指定增量########################
127.0.0.1:6379> HINCRBY user age 5 #年龄增加5
(integer) 15
127.0.0.1:6379> HINCRBY user age -5 #年龄减小5
(integer) 10
127.0.0.1:6379> hsetnx user name zhangsan #hash表中不存在就创建
(integer) 1
127.0.0.1:6379> hsetnx user name zhangsan #hash表中存在不创建
(integer) 0

Zset(有序集合)

在Set集合的基础上加了一个score属性

###################添加元素########################
127.0.0.1:6379> zadd zset 1 zhangsan #添加单个元素
(integer) 1
127.0.0.1:6379> zadd zset 2 lisi 3 wangwu #添加多个元素
(integer) 2

###################遍历元素########################
127.0.0.1:6379> zrange zset 0 -1 #遍历所有元素
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> ZRANGEBYSCORE zset -inf +inf #从小到大排序
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> ZRANGEBYSCORE zset -inf +inf withscores #从小到大排序并包含scores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
5) "wangwu"
6) "3"
127.0.0.1:6379> ZRANGEBYSCORE zset -inf 2 withscores #在指定范围内从小到大排序并包含scores
1) "zhangsan"
2) "1"
3) "lisi"
4) "2"
127.0.0.1:6379> ZREVRANGE zset 0 -1 #从大到小排序
1) "wangwu"
2) "lisi"
3) "zhangsan"

###################移除元素########################
127.0.0.1:6379> zrange zset 0 -1 #遍历所有元素
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> zrem zset lisi #移除lisi元素
(integer) 1
127.0.0.1:6379> zrange zset 0 -1 #再次遍历元素,发现lisi元素已删除
1) "zhangsan"
2) "wangwu"

###################统计元素个数########################
127.0.0.1:6379> zcount zset 0 5 #统计指定范围内集合元素个数
(integer) 2

特殊数据类型

Geospatial(地理位置)

###################添加坐标########################
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing #添加单个坐标
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 114.05 22.52 shenzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian #添加多个坐标
(integer) 2

###################遍历元素########################
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"

###################删除元素########################
127.0.0.1:6379> zrem china:city xian #删除指定元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1 #遍历后发现已经删除指定元素
1) "chongqing"
2) "shenzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"

###################获取位置坐标####################
127.0.0.1:6379> GEOPOS china:city beijing #获取北京的坐标信息
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
   
###################获取两地之间的距离################
127.0.0.1:6379> GEODIST china:city beijing chongqing km #获取北京到重庆之间的距离,单位为km
"1464.0708"

###################获取指定半径范围内的元素##########
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km #以110经度、30纬度为坐标半径1000km的范围内包含的元素
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist #以110经度、30纬度为坐标半径1000km的范围内包含的元素并显示实际距离
1) 1) "chongqing"
   2) "341.9374"
2) 1) "xian"
   2) "483.8340"
3) 1) "shenzhen"
   2) "924.6408"
4) 1) "hangzhou"
   2) "977.5143"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 2 #以110经度、30纬度为坐标半径1000km的范围内包含的元素并显示实际距离,统计显示最近的两个元素
1) 1) "chongqing"
   2) "341.9374"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) "483.8340"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"   

Hyperloglog(基数统计)

什么是基数:不重复的元素个数。

###############添加元素##############
127.0.0.1:6379> pfadd p1 a b c #p1中添加a b c 三个元素
(integer) 1
127.0.0.1:6379> pfadd p2 b c e #p2中添加b c d 三个元素
(integer) 1
127.0.0.1:6379> pfcount p1 #统计p1的元素个数
(integer) 3
127.0.0.1:6379> pfcount p2 #统计p2的元素个数
(integer) 3

###############获取基数##############
127.0.0.1:6379> PFMERGE p3 p1 p2 #获取p1、p2的并集
OK
127.0.0.1:6379> PFCOUNT p3 #获取p3的个数
(integer) 4

Bitmap(位图)

通过操作二级制位来记录数据状态,因为是二进制数只能保存 0和1两种状态。

###############添加元素##############
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0

###############获取元素##############
127.0.0.1:6379> getbit sign 5
(integer) 1

###############统计元素##############
127.0.0.1:6379> bitcount sign
(integer) 4

Redis命令查询

事物

事务:一组指令的集合 事务的执行就是事务中的指令依次执行的过程

单条指令可以保证原子性,但是事务无法保证原子性

###############执行事务##############
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379> set name james #指令的执行就是一个入队的过程
QUEUED
127.0.0.1:6379> set age 25
QUEUED
127.0.0.1:6379> exec #执行事务
1) OK
2) OK

###############放弃事务##############
127.0.0.1:6379> multi #开启事务
OK
127.0.0.1:6379> set name jack #入队
QUEUED
127.0.0.1:6379> set age 34
QUEUED
127.0.0.1:6379> DISCARD #取消事务
OK

###############编译性异常,所有指令都不会执行成功##############
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379> set name king
QUEUED
127.0.0.1:6379> set age 34
QUEUED
127.0.0.1:6379> getset heith #异常指令
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> exec #此时事务取消
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name #说明前面的指令也没有执行成功
(nil)

###############运行时异常,异常发生处前面的指令会执行成功##############
127.0.0.1:6379> MULTI #开启事务
OK
127.0.0.1:6379> set name king
QUEUED
127.0.0.1:6379> incr name #执行异常执行,此为运行时异常
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range
127.0.0.1:6379> get name #说明set指令执行成功
"king"
127.0.0.1:6379> 

###############通过watch机制实现乐观锁##############
127.0.0.1:6379> set money 100 
OK
127.0.0.1:6379> watch money #进行监听  此时如果monwy进行了变更,事务无法正常进行
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> DECRBY money 20
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"90"

发布订阅

发布订阅:包含发布者、订阅者、消息队列

###############订阅者订阅频道##############
127.0.0.1:6379> SUBSCRIBE channel #订阅channel频道
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel"
3) (integer) 1

###############发送者发送消息##############
127.0.0.1:6379> PUBLISH channel "hello world" #从channel中获取消息
(integer) 1

###############查看订阅数##############
127.0.0.1:6379> PUBSUB numsub channel
1) "channel"
2) (integer) 1

###############客户端取消订阅##############
127.0.0.1:6379> UNSUBSCRIBE channel
1) "unsubscribe"
2) "channel"
3) (integer) 0

###############订阅以ch开头的频道##############
127.0.0.1:6379> PSUBSCRIBE ch*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "ch*"
3) (integer) 1

###############取消订阅以ch开头的频道##############
127.0.0.1:6379> PUNSUBSCRIBE ch*
1) "punsubscribe"
2) "ch*"
3) (integer) 0

简单场景下可以使用Redis的订阅发布功能,复杂场景推荐使用专业的消息中间件

Redis慢查询

慢查询:与MySQL中的慢查询类似,Redis会将所有指令放入到一个队列中,单线程按顺序执行,如果某一个指令执行时间过久,就会造成阻塞。我们需要对这些指令进行记录

image-20200928131048855

慢查询开启方式

###############通过指令开启慢查询功能##############
127.0.0.1:6379> config set slowlog-log-slower-than 10000 #指令执行时间超过10毫秒,进行记录
OK
127.0.0.1:6379> config rewrite # 将指令配置永久写入配置文件
OK

###############通过修改配置文件redis.config开启慢查询功能##############
slowlog-log-slower-than 10000 #指令执行时间超过10毫秒,进行记录
slowlog-log-slower-than 0 #记录所有指令
slowlog-log-slower-than -1 #不记录

###############指定慢查询队列的长度##############
127.0.0.1:6379> config set slowlog-max-len 256 #指定慢查询队列的长度,该队列为先入先出队列
OK
127.0.0.1:6379> config rewrite #写入配置文件
OK

慢查询查询方式

###############查看慢查询记录##############
127.0.0.1:6379> slowlog get #查看慢查询记录
(empty list or set)

了解RESP协议

RESP(REdis Serialization Protocol):RESP协议是Redis客户端和服务端的通信协议,底层采用TCP的方式进行传输,具有容易实现、解析快、人类可读等特点。

###############客户端指令##############
127.0.0.1:6379> set name jack #通过客户端设定指定值
OK

###############对应RESP协议内容##############
*3 # 表示后面有几组数据  set name jack  3组
$3 # 表示set的长度
set 
$4 # 表示name的长度
name
$4 # 表示jack的长度
jack

Key的遍历

key的遍历:Redis提供了两种方式来进行key的遍历,分别应用不同的场景。

​ 1、全量遍历 :keys * 的方式主要用于key数量少的场景,我们知道Redis中的指令是在队列中依次执行,如果key值较多,执行该指令则会造成阻塞,影响其他指令执行。

​ 2、递进式遍历:可理解为分页式的遍历,每次返回下一页的起始下标,通过该下标可以获取下一页的key。

###############初始化数据##############
127.0.0.1:6379> mset n1 1 n2 2 n3 3 n4 4 n5 5 n6 6 n7 7 n8 8 n9 9 n10 10 n11 11 n12 12 n13 13
OK

###############全量遍历##############
127.0.0.1:6379> keys n* #可以进行模糊匹配
 1) "n10"
 2) "n9"
 3) "n4"
 4) "n11"
 5) "name"
 6) "n6"
 7) "n2"
 8) "n7"
 9) "n12"
10) "n3"
11) "n13"
12) "n5"
13) "n1"
14) "n8"

###############递进式遍历##############
127.0.0.1:6379> scan 0 match n*  #  从下标0开始 匹配规则为n* 
1) "12"
2) 1) "n10"
   2) "n12"
   3) "n3"
   4) "n11"
   5) "name"
   6) "n6"
127.0.0.1:6379> scan 12 match n* #  从下标12开始 匹配规则为n* 
1) "14"
2) 1) "n1"
   2) "n4"
   3) "n13"
   4) "n5"
   5) "n2"
   6) "n7"
127.0.0.1:6379> scan 14 match n* #  从下标14开始 匹配规则为n* 
1) "0"
2) 1) "n9"
   2) "n8"

二者最大的区别就在于递进式遍历不会阻塞线程

posted @ 2020-09-27 20:39  程序猿不是猴  阅读(61)  评论(0)    收藏  举报