redis 常见命令

Redis所有的key(键)都是字符串。在谈基础数据结构时,我们讨论的是存储值的数据类型,主要包括常见的5种数据类型,分别是:String、List、Set、Zset、Hash

数据结构介绍

Redis 是一个 key-value 的数据库,key是一般的String,不过 value 却是多种多样的:

1658728198413

结构类型 结构存储的值 结构的读写能力
String字符串 可以是字符串、整数或浮点数 对整个字符串或字符串的一部分进行操作;对整数或浮点数进行自增或自减操作;
List列表 一个链表,链表上的每个节点都包含一个字符串 对链表的两端进行push和pop操作,读取单个或多个元素;根据值查找或删除元素;
Set集合 包含字符串的无序集合 字符串的集合,包含基础的方法有看是否存在添加、获取、删除;还包含计算交集、并集、差集等
Hash散列 包含键值对的无序散列表 包含方法有添加、获取、删除单个元素
Zset有序集合 和散列一样,用于存储键值对 字符串成员与浮点数分数之间的有序映射;元素的排列顺序由分数的大小决定;包含方法有添加、获取、删除单个元素以及根据分值范围或成员来获取元素

通用命令

  • KEYS pattern:查看复合模版的所有keys,不建议在生产坏境下使用

  • DEL key:删除一个指定的key

  • EXISTS key:判断key是否存在

  • EXPIRE key seconds:给一个key设置过期时间 单位是秒

  • TTL key:查看指定key的剩余有效时间 。-1 表示当前key没有设置有效时间 ,-2 表示当前key不存在

  • PERSIST key:持久化 指定key

  • TYPE key:查看指定key的类型

  • MOVE key num:移动指定key到指定数据库

  • RANDOMKEY:随即返回库中的一个key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> exists k1
(integer) 1
127.0.0.1:6379> exists k2
(integer) 0
127.0.0.1:6379> expire k1 10
(integer) 1
127.0.0.1:6379> ttl k1
(integer) 7
127.0.0.1:6379> persist k1
(integer) 1
127.0.0.1:6379> ttl k1
(integer) -1
127.0.0.1:6379> type k1
string

String 字符串命令

String类型是Redis基本类型,一个键最大能存储512MB且是二进制安全的。意思是 redis 的 String 类型可以存储任何数据,如数字,字符串,jpg图片或者序列化的对象。

原理

redis中的String是动态字符串,内部结构类似ArrayList。采用预分配冗余空间的方式减少内存的频繁分配。

内部为字符串分配的实际空间一般高于字符串长度,当字符串长度<1MB时,扩容方式是加倍 也就是原来的两倍。当字符串长度>1MB时,一次扩容1MB,直到最大512MB.

命令使用

命令 简述 使用
GET 获取存储在给定键中的值 GET key
MGET 获取多个存储在给定键中的值 MGET key1 key2
SET 设置存储在给定键中的值 SET key value
MSET 设置多个存储在给定键中的值 MSET key1 value1 key2 value2
SETNX 如果不存在即设置值 SETNX key value
SETEX 设置值的同时设置过期时间 SETNX key seconds value
DEL 删除存储在给定键中的值 DEL key
INCR 将键存储的值加1 INCR key
DECR 将键存储的值减1 DECR key
INCRBY 将键存储的值加上整数 INCRBY key amount
DECRBY 将键存储的值减去整数 DECRBY key amount
APEEND 字符串后添加内容 APEEND key value
STRLEN 获取字符串长度 STRLEN ke
GETRANGE 获取字符串指定索引范围的内容 GETRANGE key start end
SETRANGE 设置字符串指定偏移量开始处插入值 SETRANGE key offset value

命令执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
SET key value:设置key的值
127.0.0.1:6379> set id 42022220018718
OK

GET key:获取key的值
127.0.0.1:6379> get id
"42022220018718"

DEL key:删除指定key
127.0.0.1:6379> del id
(integer) 1

GETSET key value:修改key的值 并返回原来得到值
127.0.0.1:6379> getset id 420222200102058719
"420222200102058718"

setex key seconds value:给指定key值赋值的同时,设置该key的有效时间
127.0.0.1:6379> setex house 50 三室一厅
OK
127.0.0.1:6379> ttl house
(integer) 41

setnx house value:设置key值,如果key已存在,则不存储
127.0.0.1:6379> setnx name chen-zikang
(integer) 0
127.0.0.1:6379> setnx house 三室一厅
(integer) 1

mget key [key...]:同时获取多个key值
127.0.0.1:6379> mget name sex age
1) "chen-zi-kang"
2) "aman"
3) "18"

mset key value [key value...]:同时设置多个key值
127.0.0.1:6379> mset hieght 170cm weight 110
OK

msetnx key value [key value...]: 同时设置多个key值,如已经存在,则不存储 ,这是一个原子操作。
127.0.0.1:6379> msetnx hieght 170cm money 100000
(integer) 0

append key value:在该key值的后边加上value
127.0.0.1:6379> append name is-a-good-boy
(integer) 25

strlen key:返回这个key值得长度
127.0.0.1:6379> strlen name
(integer) 25

getrange key begin end: 获取该key值 索引从begin到end的字符串 包头包尾
127.0.0.1:6379> set name czk-is-handsame
OK
127.0.0.1:6379> getrange name 0 10
"czk-is-hand"

setrange key offset value : 修改offset位以后的 value值
127.0.0.1:6379> setrange name 10 man
(integer) 15
127.0.0.1:6379> get name
"czk-is-hanmanme"

实战场景

  • 缓存: 经典使用场景,把常用信息,字符串,图片或者视频等信息放到redis中,redis作为缓存层,mysql做持久化层,降低mysql的读写压力。
  • 计数器:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。
  • session:常见方案spring session + redis实现session共享,

List 链表命令

redis的列表是一个字符链表,内部结构类似LinkedList。left,right都可以添加。如果键不在,则创建新链表,如果已存在则新填内容。如果当前链表没有值,则该链表也会自动删除。redis的列表最多可存储2^32-1个元素(4294967295,每个列表可以存储40多亿个元素)

原理

底层是一个快速链表(quickList)的结构,在列表元素较少时,使用内存存储压缩列表ziplist。当元素数量较多时,改成 quickList,也就是将多个zipList串起来使用,以减少内存的碎片化。

命令使用

命令 简述 使用
RPUSH 将给定值推入到列表右端 RPUSH key value
LPUSH 将给定值推入到列表左端 LPUSH key value
RPOP 从列表的右端弹出一个值,并返回被弹出的值 RPOP key
LPOP 从列表的左端弹出一个值,并返回被弹出的值 LPOP key
LRANGE 获取列表在给定范围上的所有值 LRANGE key 0 -1
LINDEX 通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 LINDEX key index
LINSERT 在某一个旧元素值的前边或后边插入一个新的值 linsert key before/after old_value new_value
LLEN 过去链表长度 llen key
LTRIM 截取list从stater到end位置的值并保留 ltrim key start end
LREM 删除count个元素值为value的元素 lrem key count value
LSET 修改索引号为index的元素的值为value LSET key index value

命令执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
lpush key value : 从头部(左边)压进(新增)一个新元素
127.0.0.1:6379> lpush list1 v1 v2 v3 v4 v5
(integer) 5

rpush key value : 从尾部(右边)压进(新增)一个新元素
rpush list1 v6
(integer) 6

lpop key value : 从头部(左边)弹出(删除)一个元素并返回
127.0.0.1:6379> lpop list1
"v5"

rpop key value : 从尾部(右边)弹出(删除)一个元素并返回
127.0.0.1:6379> rpop list1
"v1"

lset key index value : 修改索引号为index的元素的值为value
127.0.0.1:6379> lset list1 4 v7
OK

lrem key count value : 删除count个元素值为value
127.0.0.1:6379> lrem list1 0 v0
(integer) 1

linsert key before/after old_value new_value : 在某一个旧元素值的前边或后边插入一个新的值
127.0.0.1:6379> linsert list1 before v7 v6
(integer) 6

lindex key index : 查询当前list中索引为index的值
127.0.0.1:6379> lindex list1 5
"v6"

lrange key start end : 遍历list的所有元素并显示
127.0.0.1:6379> lrange list1 0 -1
1) "v3"
2) "v4"
3) "v5"
4) "v6"
5) "v7"

ltrim key start end : 截取list从stater到end位置的值并保留
127.0.0.1:6379> ltrim list1 2 6
OK

llen key : 返回一个list的元素个数
127.0.0.1:6379> llen list1
(integer) 5著作权归https://pdai.tech所有。 链接:<https://pdai.tech/md/db/nosql-redis/db-redis-data-types.html>

使用列表的技巧

  • Stack(栈) : lpush+lpop
  • Queue(队列): lpush+rpop=
  • Capped Collection(有限集合): lpush+ltrim
  • Message Queue(消息队列): lpush+brpop

实战场景

  • 微博TimeLine: 有人发布微博,用lpush加入时间轴,展示新的列表信息。
  • 消息队列

Set 集合命令

redis的集合是String类型的无序不重复的元素集,同时提供交集、并集、差集等操作,集合中最大的成员数为2^32-1(40多亿)。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

原理

​ 类似HashSet,也是通过哈希表实现的,相当于所有的value都为空。通过计算 hash 的方式来快速排重,也是 set 能提供判断一个成员是否在集合内的原因。

命令使用

命令 简述 使用
SADD 向集合添加一个或多个成员 SADD key value
SPOP 随机弹出 count 个member SPOP key [count]
SREM 删除set集合中的member SREMkey member [member…]
SCARD 获取集合的成员数 SCARD key
SMEMBERS 返回集合中的所有成员 SMEMBERS key member
SISMEMBER 判断 member 元素是否是集合 key 的成员 SISMEMBER key member
SRANDMEMBER 随机返回count个成员 SRANDMEMBER key count
SMOVE 移动source中的成员member到destination中 SMOVE sourse destination member
SDIFF 返回key1与key2的差集 SDIFF key1 key2 [key3…]
SINTER 返回key1与key2的交集 SINTER key1 key2 [key3…]
SUNION 返回key1与key2的交集 SUNION key1 key2 [key3…]

命令执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
sadd key member [member...] : 添加set集合的member
127.0.0.1:6379> sadd set1 value1 value2 value3
(integer) 3

srem key member [member...] : 删除set集合中的member
127.0.0.1:6379> srem set1 value1
(integer) 1

spop key [count] : 随机弹出count个member
127.0.0.1:6379> spop set1 1
1) "menber2"

scard key : 获取set的成员个数
127.0.0.1:6379> scard set2
(integer) 2

smembers key : 获取set的所有成员
127.0.0.1:6379> smembers set2
1) "value3"
2) "member1"

sismember key member : 判断member是否是set中的成员
127.0.0.1:6379> sismember set1 member1
(integer) 1

srandmember key count : 随机返回count个成员
127.0.0.1:6379> srandmember set1 1
(integer) 1

smove sourse destination member : 移动source中的成员member到destination中
127.0.0.1:6379> smove set1 set2 member1
(integer) 1

sdiff key1 key2 [key3...] : 返回key1与key2的差集
127.0.0.1:6379> sdiff set2 set1
1) "value3"

sinter key1 key2 [key3...] : 返回key1与key2的交集
127.0.0.1:6379> sinter set1 set2
1) "member1"

sunion key1 key2 [key3...] : 返回key1与key2的交集
127.0.0.1:6379> sunion set2 set1
1) "value3"
2) "value1"
3) "menber3"
4) "member1"
5) "member2"

实战场景

  • 标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。
  • 点赞,或点踩,收藏等,可以放到set中实现

Hash散列命令

redis中的无序字典是一个String类型的field和value的映射表,内部结构类似HashMap,每个hash可以存储2^32-1个键值对(40多亿)

原理

​ 底层的实现结构,与HashMap一样,是“数组+链表”的二维结构,第一维hash的数据位置碰撞时,将碰撞元素用链表串接起来,不同的是,redis字典的值只能是字符串,而且两者的rehash方式不同。java的hashmap是一次全部rehash,耗时较高,redis为了提高性能,采用渐进式rehash策略。具体方式为,同时保留新旧两个hash结构,然后逐步搬迁,最后取代

命令使用

命令 简述 使用
HSET(HMSET,HSETNX) 添加键值对 HSET hash-key sub-key1 value1
HGET(HMGET) 获取指定散列键的值 HGET hash-key key1
HGETALL 获取散列中包含的所有键值对 HGETALL hash-key
HDEL 如果给定键存在于散列中,那么就移除这个键 HDEL hash-key sub-key1
HKEYS 获取散列中包含的所有键 HKEYS hash-key
HVALS 获取散列中包含的所有值 HVALS hash-key
HEXISTS 判断hash中是否存在field值 HEXISTS key field

命令执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
hset key field value : 给hash设置field和value
127.0.0.1:6379> hset hash1 k1 v1
(integer) 1

hget key field : 获取hash中健值为field的值
127.0.0.1:6379> hget hash1 k1
"v1"

hmset key field value [field value...] : 同时给hash设置多个field和value
127.0.0.1:6379> hmset hash1 k2 v2 k3 v3 k4 v4
OK

hmget key field [field...] : 同时获取hash中多个健值为field的值
127.0.0.1:6379> hmget hash1 k1 k2 k3 k4
1) "v1"
2) "v2"
3) "v3"
4) "v4"

hsetnx key field value : 判断hash中是否存在 该field值,不存在则添加
127.0.0.1:6379> hsetnx hash1 k5 v5
(integer) 1

hgetall key : 获取hash中所有的field和value的值
127.0.0.1:6379> hgetall hash1
1) "k3"
2) "v3"
3) "k4"
4) "v4"
5) "k5"
6) "v5"
7) "k1"
8) "3"
9) "k2"
10) "81.83635"

hkeys key : 获取hash中所有的field的值
127.0.0.1:6379> hkeys hash1
1) "k3"
2) "k4"
3) "k5"

hvals key : 获取hash中所有value的值
127.0.0.1:6379> hvals hash1
1) "v3"
2) "v4"
3) "v5"

hexists key field : 判断hash中是否存在field值
127.0.0.1:6379> hexists hash1 k1
(integer) 1

hlen key : 获取hash中键值对的个数
127.0.0.1:6379> hlen hash1
(integer) 5

hincrby key field increment : 设置hash中field属性自增,前提是整数,自增步长为increment
127.0.0.1:6379> hincrby hash1 k2 10
(integer) 10

hincrbyfloat key field increment : 设置hash中field属性自增 ,可以是小数,自增步长为increment
127.0.0.1:6379> hincrbyfloat hash1 k2 10.1
"40.1"

实战场景

  • 缓存: 能直观,相比string更节省空间,的维护缓存信息,如用户信息,视频信息等。

Zset有序集合命令

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数是可以重复的。

原理

压缩列表(ziplist): ziplist 是为了提高存储效率而设计的一种特殊编码的双向链表。它可以存储字符串或者整数,存储整数时是采用整数的二进制而不是字符串形式存储。它能在O(1)的时间复杂度下完成 list 两端的 push 和 pop 操作。但是因为每次操作都需要重新分配 ziplist 的内存,所以实际复杂度和 ziplist 的内存使用量相关

跳跃表(zSkiplist): 跳跃表的性能可以保证在查找,删除,添加等操作的时候在对数期望时间内完成,这个性能是可以和平衡树来相比较的,而且在实现方面比平衡树要优雅,这是采用跳跃表的主要原因。跳跃表的复杂度是O(log(n))。

命令使用

命令 简述 使用
ZADD 将一个带有给定分值的成员添加到有序集合里面 ZADD zset-key 178 member1
ZRANGE(zrevrange) 根据元素在有序集合中所处的位置,从有序集合中获取多个元素 ZRANGE zset-key 0-1 withccores
ZREM 如果给定元素成员存在于有序集合中,那么就移除这个元素 ZREM zset-key member1
zrangebyscore(zrevrangebyscore) 获取指定范围内分数的所有成员 (升序) withscores表示带上分数,limit表示分页 zrangebyscore key min max [withscores] [limit offset count]
zcard 获取zset成员个数 zcard key
zcount 获取zset在指定分数范围内的成员个数,“(”左括号表示闭区间 zcount key min max
zrank(zrevrank) 获取zset中成员member的排名(升序) zrank key member

命令执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
zadd key score member [score member...]:添加zset集合新的成员分数和成员。
127.0.0.1:6379> zadd k1 10 c1 20 c2 30 c3 40 c4 50 c5 60 c6 70 c7 80 c8 90 c9
(integer) 9

zrem key member [member...]:删除zset中的成员member
127.0.0.1:6379> zrem zset key1
(integer) 1

zrange key start stop [withscores]:遍历zset,获取所有成员 ,若加上withscores,则分数被同时返回
127.0.0.1:6379> zrange k1 0 -1
1) "c1"
2) "c2"
3) "c3"
4) "c4"
5) "c5"
6) "c6"
7) "c7"
8) "c8"
9) "c9"

zrangebyscore key min max [withscores] [limit offset count] : 获取指定范围内分数的所有成员 (升序) withscores表示带上分数,limit表示分页
127.0.0.1:6379> zrevrangebyscore k1 50 (10
1) "c5"
2) "c4"
3) "c3"
4) "c2"

zcard key:获取zset成员个数
127.0.0.1:6379>zcard k1
(integer)8
zcount key min max :获取zset在指定分数范围内的成员个数,“(”左括号表示闭区间
127.0.0.1:6379> zcount k1 0 (60
(integer) 5

zrank key member : 获取zset中成员member的排名(升序)
127.0.0.1:6379> zvrank k1 c9
(integer) 8

zrevrank key member:获取zset中成员member的排名(降序)
127.0.0.1:6379> zrevrank k1 c9
(integer) 0

zrevrange key [withscores]: 获取zset中所有的成员(降序)
127.0.0.1:6379> zrevrange k1 0 -1
1) "c9"
2) "c8"
3) "c7"
4) "c6"
5) "c5"
6) "c4"
7) "c3"
8) "c2"
9) "c1"

zrevrangebyscore key max min [withscores] [limit offset count] :获取指定范围内分数的所有成员 (降序) withscores表示带上分数,limit表示分页

实战场景

  • 排行榜:有序集合经典使用场景。例如小说视频等网站需要对用户上传的小说视频做排行榜,榜单可以按照用户关注数,更新时间,字数等打分,做排行。

HyperLogLogs(基数统计)

什么是基数?

举个例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那么基数(不重复的元素)= 1, 2, 4, 6, 7, 9; (允许容错,即可以接受一定误差)

HyperLogLogs 基数统计用来解决什么问题?

这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数、页面实时UV、在线用户数,共同好友数等。

它的优势体现在哪?

一个大型的网站,每天 IP 比如有 100 万,粗算一个 IP 消耗 15 字节,那么 100 万个 IP 就是 15M。而 HyperLogLog 在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值,不管存储的内容是什么,它一个基于基数估算的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。而且这个估算的基数并不一定准确,是一个带有 0.81% 标准错误的近似值(对于可以接受一定容错的业务场景,比如IP数统计,UV等,是可以忽略不计的)。

相关命令使用

1
2
3
4
5
6
7
8
9
10
11
12
127.0.0.1:6379> pfadd key1 a b c d e f g h i	# 创建第一组元素
(integer) 1
127.0.0.1:6379> pfcount key1 # 统计元素的基数数量
(integer) 9
127.0.0.1:6379> pfadd key2 c j k l m e g a # 创建第二组元素
(integer) 1
127.0.0.1:6379> pfcount key2
(integer) 8
127.0.0.1:6379> pfmerge key3 key1 key2 # 合并两组:key1 key2 -> key3 并集
OK
127.0.0.1:6379> pfcount key3
(integer) 13

Bitmap (位存储)

Bitmap 即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。

用来解决什么问题?

比如:统计用户信息,活跃,不活跃! 登录,未登录! 打卡,不打卡! 两个状态的,都可以使用 Bitmaps

如果存储一年的打卡状态需要多少内存呢? 365 天 = 365 bit 1字节 = 8bit 46 个字节左右!

相关命令使用

使用bitmap 来记录 周一到周日的打卡! 周一:1 周二:0 周三:0 周四:1 ……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(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 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0

查看某一天是否有打卡!

1
2
3
4
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 5
(integer) 0

统计操作,统计 打卡的天数!

1
2
127.0.0.1:6379> bitcount sign # 统计这周的打卡记录,就可以看到是否有全勤!
(integer) 3

geospatial (地理位置)

geoadd

添加地理位置

1
2
3
4
127.0.0.1:6379> geoadd china:city 118.76 32.04 manjing 112.55 37.86 taiyuan 123.43 41.80 shenyang
(integer) 3
127.0.0.1:6379> geoadd china:city 144.05 22.52 shengzhen 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 3

规则

两级无法直接添加,我们一般会下载城市数据(这个网址可以查询 GEO: http://www.jsons.cn/lngcode)!

  • 有效的经度从-180度到180度。
  • 有效的纬度从-85.05112878度到85.05112878度。
1
2
3
# 当坐标位置超出上述指定范围时,该命令将会返回一个错误。
127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin
(error) ERR invalid longitude,latitude pair 39.900000,116.400000

geopos

获取指定的成员的经度和纬度

1
2
3
4
5
127.0.0.1:6379> geopos china:city taiyuan manjing
1) 1) "112.54999905824661255"
1) "37.86000073876942196"
2) 1) "118.75999957323074341"
1) "32.03999960287850968"

获得当前定位, 一定是一个坐标值!

geodist

如果不存在, 返回空

单位如下

  • m
  • km
  • mi 英里
  • ft 英尺
1
2
3
4
127.0.0.1:6379> geodist china:city taiyuan shenyang m
"1026439.1070"
127.0.0.1:6379> geodist china:city taiyuan shenyang km
"1026.4391"

georadius

附近的人 ==> 获得所有附近的人的地址, 定位, 通过半径来查询

获得指定数量的人

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
127.0.0.1:6379> georadius china:city 110 30 1000 km			以 100,30 这个坐标为中心, 寻找半径为1000km的城市
1) "xian"
2) "hangzhou"
3) "manjing"
4) "taiyuan"
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist
1) 1) "xian"
2) "483.8340"
127.0.0.1:6379> georadius china:city 110 30 1000 km withcoord withdist count 2
1) 1) "xian"
2) "483.8340"
3) 1) "108.96000176668167114"
2) "34.25999964418929977"
2) 1) "manjing"
2) "864.9816"
3) 1) "118.75999957323074341"
2) "32.03999960287850968"

参数 key 经度 纬度 半径 单位 [显示结果的经度和纬度] [显示结果的距离] [显示的结果的数量]

georadiusbymember

显示与指定成员一定半径范围内的其他成员

1
2
3
4
5
6
7
8
9
10
11
12
13
127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km
1) "manjing"
2) "taiyuan"
3) "xian"
127.0.0.1:6379> georadiusbymember china:city taiyuan 1000 km withcoord withdist count 2
1) 1) "taiyuan"
2) "0.0000"
3) 1) "112.54999905824661255"
2) "37.86000073876942196"
2) 1) "xian"
2) "514.2264"
3) 1) "108.96000176668167114"
2) "34.25999964418929977"

geohash(较少使用)

该命令返回11个字符的hash字符串

1
2
3
127.0.0.1:6379> geohash china:city taiyuan shenyang
1) "ww8p3hhqmp0"
2) "wxrvb9qyxk0"

底层

geo底层的实现原理实际上就是Zset, 我们可以通过Zset命令来操作geo

1
2
127.0.0.1:6379> type china:city
zset

查看全部元素 删除指定的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
127.0.0.1:6379> zrange china:city 0 -1 withscores
1) "xian"
2) "4040115445396757"
3) "hangzhou"
4) "4054133997236782"
5) "manjing"
6) "4066006694128997"
7) "taiyuan"
8) "4068216047500484"
9) "shenyang"
1) "4072519231994779"
2) "shengzhen"
3) "4154606886655324"
127.0.0.1:6379> zrem china:city manjing
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "xian"
2) "hangzhou"
3) "taiyuan"
4) "shenyang"
5) "shengzhen"