redis数据类型
redis是基于内存的key-value键值对内存数据库,提供了丰富的数据类型,数据类型指的是value的数据类型,key的数据类型都是字符串,value的数据类型有:
字符串(String)、列表(List)、哈希表(Hash)、集合(Set)、有序集合(Sorted Set)、
地理空间(Geospatial)、基数统计(HyperLogLog)、位图(Bitmap)、位域(Bitfield)和流(Stream);
一 字符串
String类型是redis最基本的数据类型,是二进制安全的,可以包含任意数据,String类型最多是512M;
set key value:设置指定key的值,set命令有ex、px、exat、pxat、nx、xx、keepttl、get这几个可选参数
ex seconds:以秒为单位设置过期时间;
px milliseconds:以毫秒为单位设置过期时间;
exat timestamp:设置以秒为单位的unix时间戳所对应的时间为过期时间;
pxat milliseconds-timestamp:设置以毫秒为单位的unix时间戳所对应的时间为过期时间;
nx:键不存在的时候设置键值对,设置成功返回OK,设置不成功返回nil;
xx:键存在的时候设置键值对,设置成功返回OK,设置不成功返回nil;
keepttl:保留key之前设置好的生命周期;
get:返回指定键原本的值,若键不存在时返回nil;
设置成功则返回OK,返回nil为未执行set命令,使用get参数则返回该键原来的值,或键不存在时返回nil;
get key:获取指定key的值;
127.0.0.1:6379> set key1 1 ex 60
OK
127.0.0.1:6379> ttl key1
(integer) 56
127.0.0.1:6379> set key2 1
OK
127.0.0.1:6379> ttl key2
(integer) -1
127.0.0.1:6379> set key2 1 nx
(nil)
127.0.0.1:6379> set key3 1 nx
OK
127.0.0.1:6379> set key3 2 xx
OK
127.0.0.1:6379> set key4 1 xx
(nil)
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
127.0.0.1:6379> set key5 1 ex 60
OK
127.0.0.1:6379> ttl key5
(integer) 52
127.0.0.1:6379> set key5 2 keepttl
OK
127.0.0.1:6379> ttl key5
(integer) 28
127.0.0.1:6379> set key3 3 get
"2"
127.0.0.1:6379> get key3
"3"
127.0.0.1:6379>
mset key1 value1 key2 value2:同时设置一个或多个键值对;
mget key1 key2:同时获取一个或多个给定key的值;
127.0.0.1:6379> mset key1 1 key2 2 key3 3
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"
127.0.0.1:6379> mget key1 key2 key3
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> mget key1 key2
1) "1"
2) "2"
127.0.0.1:6379> mget key1 key2 key4
1) "1"
2) "2"
3) (nil)
127.0.0.1:6379>
setnx key value:只有在key不存在时,设置key的值,设置成功返回1,设置失败返回0;
setex key seconds value:将值value关联到key,并将key的过期时间设为seconds,以秒为单位;
psetex key milliseconds value:将值value关联到key,并将key的过期时间设为milliseconds,以毫秒为单位;
127.0.0.1:6379> setnx key1 1
(integer) 1
127.0.0.1:6379> setnx key1 2
(integer) 0
127.0.0.1:6379> get key1
"1"
127.0.0.1:6379> setex key2 60 1
OK
127.0.0.1:6379> ttl key2
(integer) 55
127.0.0.1:6379>
msetnx key1 value1 key2 value2:同时设置一个或多个键值对,当且仅当所有给定key都不存在才会设置成功返回1,否则返回0;
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> msetnx key1 1 key2 1 key3 1
(integer) 0
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> msetnx key10 1 key2 1 key3 1
(integer) 1
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"
4) "key10"
127.0.0.1:6379>
incr key:将key中储存的数字值加一,并返回,一定是数字才能进行加一操作;
incrby key increment:将key所存储的值加上给定的增量值,并返回;
incrbyfloat key increment:将key所存储的值加上给定的浮点增量值,并返回;
decr key:将key中储存的数字值减一,并返回;
decrby key decrement:将key所储存的值减去给定的减量值,并返回;
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> incr key1
(integer) 2
127.0.0.1:6379> incrby key1 3
(integer) 5
127.0.0.1:6379> incrbyfloat key1 3.1
"8.09999999999999964"
127.0.0.1:6379> set key2 10
OK
127.0.0.1:6379> decr key2
(integer) 9
127.0.0.1:6379> decrby key2 3
(integer) 6
127.0.0.1:6379>
setrange key offset value:用value参数覆写给定key所存储的字符串值,从偏移量offset开始;
getrange key start end:获取指定key中值的子字符串,指定区间范围的值,类似between...and的关系;
127.0.0.1:6379> set key1 abcdefghijklmn
OK
127.0.0.1:6379> getrange key1 0 3
"abcd"
127.0.0.1:6379> setrange key1 1 aaa
(integer) 14
127.0.0.1:6379> getrange key1 0 -1
"aaaaefghijklmn"
127.0.0.1:6379>
getset key value:将给定key的值设为value,并返回key的旧值;
getbit key offset:对key所存储的字符串值,获取指定偏移量上的位(bit);
append key value:如果key已经存在并且是一个字符串,append命令将value追加到key原来值的末尾;
strlen key:返回key所存储的字符串值的长度;
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> getset key1 2
"1"
127.0.0.1:6379> append key1 hello
(integer) 6
127.0.0.1:6379> get key1
"2hello"
127.0.0.1:6379> strlen key1
(integer) 6
127.0.0.1:6379>
二 列表
List底层是个双端链表,字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左边),或者尾部(右边);
List最多可以包含2^32-1个元素,4294967295,每个列表超过40亿个元素,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差;
List主要功能有push/pop等,一般用在栈、队列、消息队列等场景,left、right都可以插入添加;
如果键不存在,创建新的链表,如果键已存在,新增内容,如果值全移除,对应的键也就消失了;
lpush key value1 value2:将一个或多个值插入到列表头部
rpush key value1 value2:将一个或多个值插入到列表尾部
lrange key start stop:获取列表指定范围内的元素,start和stop是列表下表位置
127.0.0.1:6379> lpush key1 a b c d e f g
(integer) 7
127.0.0.1:6379> rpush key2 h i j k l m n
(integer) 7
127.0.0.1:6379> lrange key1 0 -1
1) "g"
2) "f"
3) "e"
4) "d"
5) "c"
6) "b"
7) "a"
127.0.0.1:6379> lrange key2 0 -1
1) "h"
2) "i"
3) "j"
4) "k"
5) "l"
6) "m"
7) "n"
127.0.0.1:6379>
lpop key [count]:移除并获取列表的前count个元素,count默认值是1
rpop key [count]:移除并获取列表的后count个元素,count默认值是1
127.0.0.1:6379> lpush key1 a b c d e f g
(integer) 7
127.0.0.1:6379> lpop key1
"g"
127.0.0.1:6379> lrange key1 0 -1
1) "f"
2) "e"
3) "d"
4) "c"
5) "b"
6) "a"
127.0.0.1:6379> rpop key1 2
1) "a"
2) "b"
127.0.0.1:6379> lrange key1 0 -1
1) "f"
2) "e"
3) "d"
4) "c"
127.0.0.1:6379>
lindex key index:按照索引下标获取列表中的元素,从上到下
llen key:获取列表的长度
127.0.0.1:6379> rpush key1 a b c d e f g
(integer) 7
127.0.0.1:6379> lindex key1 0
"a"
127.0.0.1:6379> lindex key1 6
"g"
127.0.0.1:6379> lindex key1 7
(nil)
127.0.0.1:6379> llen key1
(integer) 7
127.0.0.1:6379>
lrem key count value:删除count个值为value的元素
127.0.0.1:6379> rpush key1 a a a b b b c c c d d d
(integer) 12
127.0.0.1:6379> lrem key1 2 a
(integer) 2
127.0.0.1:6379> lrange key1 0 -1
1) "a"
2) "b"
3) "b"
4) "b"
5) "c"
6) "c"
7) "c"
8) "d"
9) "d"
10) "d"
127.0.0.1:6379> lrem key1 4 d
(integer) 3
127.0.0.1:6379> lrange key1 0 -1
1) "a"
2) "b"
3) "b"
4) "b"
5) "c"
6) "c"
7) "c"
127.0.0.1:6379>
ltrim key start_index stop_index:截取列表指定范围的值后,再重新赋值给key
127.0.0.1:6379> rpush key1 1 2 3 4 5 6 7
(integer) 7
127.0.0.1:6379> ltrim key1 2 6
OK
127.0.0.1:6379> lrange key1 0 -1
1) "3"
2) "4"
3) "5"
4) "6"
5) "7"
127.0.0.1:6379>
rpoplpush source_list destination_list:移除源列表的最后一个元素,并将该元素添加到另一个列表中返回
lset key index value:通过列表指定索引位置设置值
linsert key before/after pivot已有值 value新值:在列表的元素前或后插入新元素
127.0.0.1:6379> rpush key1 a b c d e f g
(integer) 7
127.0.0.1:6379> rpush key2 1 2 3 4 5 6 7
(integer) 7
127.0.0.1:6379> rpoplpush key1 key2
"g"
127.0.0.1:6379> lrange key1 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
127.0.0.1:6379> lrange key2 0 -1
1) "g"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
8) "7"
127.0.0.1:6379> lset key1 2 hello
OK
127.0.0.1:6379> lrange key1 0 -1
1) "a"
2) "b"
3) "hello"
4) "d"
5) "e"
6) "f"
127.0.0.1:6379> linsert key1 before hello hi
(integer) 7
127.0.0.1:6379> linsert key1 after hello redis
(integer) 8
127.0.0.1:6379> lrange key1 0 -1
1) "a"
2) "b"
3) "hi"
4) "hello"
5) "redis"
6) "d"
7) "e"
8) "f"
127.0.0.1:6379>
三 哈希表
hash是一个String类型的field(字段)和value(值)的映射表,每个hash可以存储2^32-1个键值对,常用命令:
hset key field value:将哈希表key中的字段field的值设为value,如果key不存在则创建新的key,如果key存在则追加key的字段;
hget key field:获取存储在哈希表key中指定字段field的值;
hmset key field1 value1 field2 value2:同时将多个field-value(域-值)设置到哈希表key中;
hmget key field1 field2:获取哈希表key中所有给定字段的值;
hgetall key:获取在哈希表中指定key的所有字段和值;
hkeys key:获取所有哈希表中key的字段;
hvals key:获取所有哈希表中key的值;
127.0.0.1:6379> hset key1 name alice sex female
(integer) 2
127.0.0.1:6379> hget key1 name
"alice"
127.0.0.1:6379> hmset key2 name bob sex male hobby alice
OK
127.0.0.1:6379> hmget key2 name sex hobby
1) "bob"
2) "male"
3) "alice"
127.0.0.1:6379> hgetall key2
1) "name"
2) "bob"
3) "sex"
4) "male"
5) "hobby"
6) "alice"
127.0.0.1:6379> hkeys key2
1) "name"
2) "sex"
3) "hobby"
127.0.0.1:6379> hvals key2
1) "bob"
2) "male"
3) "alice"
127.0.0.1:6379>
hlen key:获取哈希表key中字段的数量;
hexists key field:查看哈希表key中,指定的字段是否存在;
hdel key field1 field2:删除哈希表key中的一个或多个字段;
127.0.0.1:6379> hmset key1 name alice age 12 score 100
OK
127.0.0.1:6379> hlen key1
(integer) 3
127.0.0.1:6379> hexists key1 name
(integer) 1
127.0.0.1:6379> hexists key1 name1
(integer) 0
127.0.0.1:6379> hdel key1 name
(integer) 1
127.0.0.1:6379> hexists key1 name
(integer) 0
127.0.0.1:6379> hgetall key1
1) "age"
2) "12"
3) "score"
4) "100"
127.0.0.1:6379>
hincrby key field increment:将哈希表key中的field字段的整数值加上增量increment;
hincrbyfloat key field increment:将哈希表key中的field字段的浮点值加上增量increment;
127.0.0.1:6379> hmset key1 name alice age 12 score 80.1
OK
127.0.0.1:6379> hgetall key1
1) "name"
2) "alice"
3) "age"
4) "12"
5) "score"
6) "80.1"
127.0.0.1:6379> hincrby key1 age 12
(integer) 24
127.0.0.1:6379> hgetall key1
1) "name"
2) "alice"
3) "age"
4) "24"
5) "score"
6) "80.1"
127.0.0.1:6379> hincrbyfloat key1 score 1.5
"81.59999999999999432"
127.0.0.1:6379> hgetall key1
1) "name"
2) "alice"
3) "age"
4) "24"
5) "score"
6) "81.59999999999999432"
127.0.0.1:6379>
hsetnx key field value:只有哈希表key的field字段不存在,设置哈希表字段的值;
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> hsetnx key1 name alice
(integer) 1
127.0.0.1:6379> hsetnx key1 age 12
(integer) 1
127.0.0.1:6379> hsetnx key1 age 13
(integer) 0
127.0.0.1:6379> hgetall key1
1) "name"
2) "alice"
3) "age"
4) "12"
127.0.0.1:6379>
四 集合
Set是String类型的、无序的和唯一的元素集合,编码可以是intset或者hashtable;
Set集合中最大的成员数是2^32-1个;
sadd key member1 member2:向集合添加一个或多个成员;
smembers key:返回集合中的所有成员;
scard key:获取集合中的成员数;
sismember key member:判断member元素是否是集合key的成员;
srem key member1 member2:移除集合中一个或多个成员;
127.0.0.1:6379> sadd key1 a b c d e f g
(integer) 7
127.0.0.1:6379> smembers key1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
127.0.0.1:6379> scard key1
(integer) 7
127.0.0.1:6379> sismember key1 a
(integer) 1
127.0.0.1:6379> sismember key1 h
(integer) 0
127.0.0.1:6379> srem key1 e f g
(integer) 3
127.0.0.1:6379> smembers key1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379>
srandmember key [count]:随机返回集合中一个或多个成员
spop key [count]:随机移除并返回集合中一个或多个成员;
smove source destination member:将source集合中的member元素移动到destination集合中;
127.0.0.1:6379> sadd key1 a b c d e f g
(integer) 7
127.0.0.1:6379> sadd key2 1 2 3 4
(integer) 4
127.0.0.1:6379> smembers key1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
127.0.0.1:6379> srandmember key1 2
1) "c"
2) "f"
127.0.0.1:6379> smembers key1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
127.0.0.1:6379> spop key1
"f"
127.0.0.1:6379> spop key1 2
1) "a"
2) "e"
127.0.0.1:6379> smembers key1
1) "b"
2) "c"
3) "d"
4) "g"
127.0.0.1:6379> smove key1 key2 d
(integer) 1
127.0.0.1:6379> smembers key1
1) "b"
2) "c"
3) "g"
127.0.0.1:6379> smembers key2
1) "1"
2) "2"
3) "3"
4) "4"
5) "d"
127.0.0.1:6379>
sdiff key1 key2:返回给定所有集合的差集;
sunion key1 key2:返回给定所有集合的并集;
sinter key1 key2:返回给定所有集合的交集;
sintercard numkeys key1 key2 [LIMIT limit]:此命令类似于sinter,但是不返回所有给定集合的交集,只返回结果的基数,当提供可选的LIMIT参数(默认为0,表示无限制)时,如果交集基数在计算中途达到限制,算法将退出并产生限制作为基数;
127.0.0.1:6379> sadd key1 a b c 1 2 3
(integer) 6
127.0.0.1:6379> sadd key2 b c d 2 4 5
(integer) 6
127.0.0.1:6379> sdiff key1 key2
1) "a"
2) "1"
3) "3"
127.0.0.1:6379> sdiff key2 key1
1) "d"
2) "4"
3) "5"
127.0.0.1:6379> sunion key1 key2
1) "a"
2) "b"
3) "c"
4) "1"
5) "2"
6) "3"
7) "d"
8) "4"
9) "5"
127.0.0.1:6379> sinter key1 key2
1) "b"
2) "c"
3) "2"
127.0.0.1:6379> sintercard 2 key1 key2
(integer) 3
127.0.0.1:6379>
五 有序集合
zset,sorted set有序集合,也是String类型和唯一性的元素,zset中成员是唯一的,但是分数(score)却可以重复;
zset中每个元素都会关联一个double类型的分数,redis正式通过分数来为集合中的成员进行从大到小的排序;
zset是通过哈希表实现的,所以添加、删除和查找的复杂度都是O(1),集合中最大的成员数是2^32-1个;
zadd key score1 member1 score2 member2:向有序集合中添加一个或多个成员,或者更新已存在成员的分数;
zrange key start stop [withscores]:通过索引区间返回有序集合指定区间内的成员,withscores参数表示展示成员的分数,分数从低到高排序;
zrevrange key start stop [withscores]:通过索引区间返回有序集合指定区间内的成员,withscores参数表示展示成员的分数,分数从高到底排序;
zrangebyscore key min max [withscores] [limit offset count]:通过分数区间返回有序集合指定区间内的成员,withscores参数表示展示成员的分数,limit展示显示的个数,分数从低到高排序;
zrevrangebyscore key min max [withscores] [limit offset count]:通过分数区间返回有序集合指定区间内的成员,withscores参数表示展示成员的分数,limit展示显示的个数,分数从高到底排序;
127.0.0.1:6379> zadd key1 100 a 70 b 80 c 90 d 60 e
(integer) 5
127.0.0.1:6379> zrange key1 0 -1
1) "e"
2) "b"
3) "c"
4) "d"
5) "a"
127.0.0.1:6379> zrange key1 0 -1 withscores
1) "e"
2) "60"
3) "b"
4) "70"
5) "c"
6) "80"
7) "d"
8) "90"
9) "a"
10) "100"
127.0.0.1:6379> zrevrange key1 0 -1
1) "a"
2) "d"
3) "c"
4) "b"
5) "e"
127.0.0.1:6379> zrevrange key1 0 -1 withscores
1) "a"
2) "100"
3) "d"
4) "90"
5) "c"
6) "80"
7) "b"
8) "70"
9) "e"
10) "60"
127.0.0.1:6379> zrangebyscore key1 60 95
1) "e"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> zrangebyscore key1 (60 95
1) "b"
2) "c"
3) "d"
127.0.0.1:6379> zrangebyscore key1 60 90
1) "e"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> zrangebyscore key1 60 (90
1) "e"
2) "b"
3) "c"
127.0.0.1:6379> zrevrangebyscore key1 60 90 withscores
(empty array)
127.0.0.1:6379> zrevrangebyscore key1 90 60 withscores
1) "d"
2) "90"
3) "c"
4) "80"
5) "b"
6) "70"
7) "e"
8) "60"
127.0.0.1:6379> zrevrangebyscore key1 90 60 withscores limit 1 2
1) "c"
2) "80"
3) "b"
4) "70"
127.0.0.1:6379>
zscore key member:获取有序集合中成员的分数;
zcard key:获取有序集合的成员数;
zcount key min max:计算在有序集合中指定分数区间的成员数;
zrem key member1 member2:移除有序集合中的一个或多个成员;
127.0.0.1:6379> zadd key1 60 a 70 b 80 c 90 d 100 e
(integer) 5
127.0.0.1:6379> zscore key1 a
"60"
127.0.0.1:6379> zcard key1
(integer) 5
127.0.0.1:6379> zcount key1 60 75
(integer) 2
127.0.0.1:6379> zcount key1 (60 75
(integer) 1
127.0.0.1:6379> zrange key1 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
127.0.0.1:6379> zrem key1 a b
(integer) 2
127.0.0.1:6379> zrange key1 0 -1
1) "c"
2) "d"
3) "e"
127.0.0.1:6379>
zmpop numkeys key1 key2 min|max [COUNT count]:从键名列表中的第一个非空排序集中弹出一个或多个元素,min是从小到大逐个移除, max是从大到小逐个移除;
127.0.0.1:6379> zadd key1 60 a 70 b 80 c 90 d 100 e
(integer) 5
127.0.0.1:6379> zadd key2 80 h 90 i 100 j 110 k 120 m
(integer) 5
127.0.0.1:6379> zmpop 2 key1 key2 max count 2
1) "key1"
2) 1) 1) "e"
2) "100"
2) 1) "d"
2) "90"
127.0.0.1:6379> zrange key1 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> zmpop 2 key2 key1 min count 2
1) "key2"
2) 1) 1) "h"
2) "80"
2) 1) "i"
2) "90"
127.0.0.1:6379> zrange key2 0 -1
1) "j"
2) "k"
3) "m"
127.0.0.1:6379>
zincrby key increment member:有序集合中对key中的指定成员的分数加上增量increment;
127.0.0.1:6379> zadd key1 90 a 100 b
(integer) 2
127.0.0.1:6379> zrange key1 0 -1
1) "a"
2) "b"
127.0.0.1:6379> zrange key1 0 -1 withscores
1) "a"
2) "90"
3) "b"
4) "100"
127.0.0.1:6379> zincrby key1 7 a
"97"
127.0.0.1:6379> zrange key1 0 -1 withscores
1) "a"
2) "97"
3) "b"
4) "100"
127.0.0.1:6379>
zrank key member:获取有序集合中指定成员的索引,按照成员分数从小到大排序;
zrevrank key member:获取有序集合中指定成员的索引,按照成员分数从大到小排序;
127.0.0.1:6379> zadd key1 60 a 70 b 80 c 90 d 100 e
(integer) 5
127.0.0.1:6379> zrank key1 b
(integer) 1
127.0.0.1:6379> zrank key1 b withscore
1) (integer) 1
2) "70"
127.0.0.1:6379> zrevrank key1 b
(integer) 3
127.0.0.1:6379> zrevrank key1 b withscore
1) (integer) 3
2) "70"
127.0.0.1:6379>
六 地理空间
地球上的地理位置是使用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],只要确定地球上一个点的经纬度就可以在地球的位置,例如滴滴打车,最直观的操作就是实时记录更新各个车的位置;
Geospatial主要用来存储地理位置信息,并对存储的信息进行操作,包括:
添加地理位置坐标;
获取地理位置坐标;
计算两个位置之间的距离;
根据用户给定的经纬度坐标来获取指定范围内的地理位置集合;
Geospatial的核心思想就是将球体转换为平面,区块转换为一点,将二位的坐标转换为一维的点块,最后将一维的点块转换为二进制再通过base32编码;
geoadd key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]:将多个经纬度和位置名称添加到指定的key中;
geopos key [member [member ...]:从指定的key里面返回一个或多个给定位置元素的经纬度;
geohash key [member [member ...]:从指定的key里面返回一个或多个给定位置元素的geohash表示;
geodist key member1 member2 [M | KM | FT | MI]:返回指定的key里面两个给定位置之间的距离;
georadius key longitude latitude radius M | KM | FT | MI [withcoord] [withdist] [withhash]:以指定的key的经纬度为中心,返回与中心位置距离不超过最大距离的所有位置元素;
georadiusbymember key member radius M | KM | FT | MI [withcoord] [withdist] [withhash]:以指定的key的成员位置名字为中心,返回与中心位置距离不超过最大距离的所有位置元素;
127.0.0.1:6379> geoadd key1
116.289573 40.066731 A_park 116.261402 40.03536 B_park
116.27865 39.998669 C_park 116.30912 40.014144 D_park
(integer) 4
127.0.0.1:6379> geopos key1 A_park
1) 1) "116.28957241773605347"
2) "40.06673151481107453"
127.0.0.1:6379> geopos key1 A_park
1) 1) "116.28957241773605347"
2) "40.06673151481107453"
127.0.0.1:6379> geopos key1 A_park B_park
1) 1) "116.28957241773605347"
2) "40.06673151481107453"
2) 1) "116.26140385866165161"
2) "40.03535927102193881"
127.0.0.1:6379> geohash key1 A_park B_park
1) "wx4eyjzmxk0"
2) "wx4ev84yz50"
127.0.0.1:6379>
127.0.0.1:6379> geodist key1 A_park B_park KM
"4.2341"
127.0.0.1:6379> georadius key1 116.297622 40.032709 4 KM
1) "D_park"
2) "A_park"
3) "B_park"
127.0.0.1:6379> georadius key1 116.297622 40.032709 4 KM withcoord
1) 1) "D_park"
2) 1) "116.30912035703659058"
2) "40.01414365491827141"
2) 1) "A_park"
2) 1) "116.28957241773605347"
2) "40.06673151481107453"
3) 1) "B_park"
2) 1) "116.26140385866165161"
2) "40.03535927102193881"
127.0.0.1:6379> georadius key1 116.297622 40.032709 4 KM withcoord withdist
1) 1) "D_park"
2) "2.2854"
3) 1) "116.30912035703659058"
2) "40.01414365491827141"
2) 1) "A_park"
2) "3.8458"
3) 1) "116.28957241773605347"
2) "40.06673151481107453"
3) 1) "B_park"
2) "3.0985"
3) 1) "116.26140385866165161"
2) "40.03535927102193881"
127.0.0.1:6379> georadius key1 116.297622 40.032709 4 KM withcoord withdist withhash
1) 1) "D_park"
2) "2.2854"
3) (integer) 4069880779492970
4) 1) "116.30912035703659058"
2) "40.01414365491827141"
2) 1) "A_park"
2) "3.8458"
3) (integer) 4069883716202383
4) 1) "116.28957241773605347"
2) "40.06673151481107453"
3) 1) "B_park"
2) "3.0985"
3) (integer) 4069883261008836
4) 1) "116.26140385866165161"
2) "40.03535927102193881"
127.0.0.1:6379> georadiusbymember key1 A_park 5 KM withcoord
1) 1) "B_park"
2) 1) "116.26140385866165161"
2) "40.03535927102193881"
2) 1) "A_park"
2) 1) "116.28957241773605347"
2) "40.06673151481107453"
127.0.0.1:6379>
七 基数统计
HyperLogLog是用来做基数统计的算法,去重复统计功能的基础估计算法,是一种数据集去重复后的元素个数;
HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算得到的基数所需的空间总是固定且是很小的;
在Redis里面,每个HyperLogLog键只需要花费12 KB内存,就可以计算接近2^64个不同元素的基 数,这和计算基数时元素越多耗费内存就越多的集合形成鲜明对比;
HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,因此HyperLogLog不能像集合那样,返回输入的各个元素;
pfadd key element[element ...]:添加指定元素到HyperLogLog中;
pfcount key[key ...]:返回给定HyperLogLog的基数估算值;
pfmerge destkey sourcekey [sourcekey ...]:将多个HyperLogLog合并为一个HyperLogLog;
127.0.0.1:6379> pfadd key1 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
(integer) 1
127.0.0.1:6379> pfcount key1
(integer) 5
127.0.0.1:6379> pfadd key2 a b b c c c d d d d
(integer) 1
127.0.0.1:6379> pfcount key1 key2
(integer) 9
127.0.0.1:6379> pfcount key2
(integer) 4
127.0.0.1:6379> pfmerge key3 key1 key2
OK
127.0.0.1:6379> pfcount key3
(integer) 9
127.0.0.1:6379>
八 位图
Bitmap是由0和1状态表现的二进制位的bit数组,用String类型作为底层数据结构实现的一种统计二值状态的数据类型;
Bitmap的本质是数组,是基于String数据类型的按位的操作,该数组由多个二进制位组成,每个二进制位都对应一个偏移量(索引);
Bitmap支持的最大位数是2^32位,可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息;
Bitmap数据结构可以用于状态统计;
setbit key offset value:给指定key的值的第offset索引位置赋值0或1,偏移量(索引)是从0开始的;
getbit key offset:获取指定key的第offset索引位置的值;
strlen key:统计字节数占用多少,不是字符串长度而是占据几个字节,超过8位后自己按照8位一组一byte再扩容;
bitcount key start end:返回指定key中[start, end]中为1的数量;
bitop AND|OR|XOR|NOTdestkey key [key ...]:对不同的二进制存储数据进行位运算,运算结果放在destkey中;
127.0.0.1:6379> setbit key1 0 1
(integer) 0
127.0.0.1:6379> setbit key1 1 1
(integer) 0
127.0.0.1:6379> setbit key1 2 1
(integer) 0
127.0.0.1:6379> setbit key1 3 1
(integer) 0
127.0.0.1:6379> setbit key1 4 1
(integer) 0
127.0.0.1:6379> setbit key2 3 1
(integer) 0
127.0.0.1:6379> setbit key2 4 1
(integer) 0
127.0.0.1:6379> setbit key2 5 1
(integer) 0
127.0.0.1:6379> setbit key2 6 1
(integer) 0
127.0.0.1:6379> setbit key2 7 1
(integer) 0
127.0.0.1:6379> getbit key1 2
(integer) 1
127.0.0.1:6379> getbit key2 5
(integer) 1
127.0.0.1:6379> strlen key1
(integer) 1
127.0.0.1:6379> bitcount key1 0 -1
(integer) 5
127.0.0.1:6379> bitop and key3 key1 key2
(integer) 1
127.0.0.1:6379> bitcount key3 0 -1
(integer) 2
127.0.0.1:6379> getbit key3 2
(integer) 0
127.0.0.1:6379> getbit key3 3
(integer) 1
127.0.0.1:6379> getbit key3 4
(integer) 1
127.0.0.1:6379> bitop or key4 key1 key2
(integer) 1
127.0.0.1:6379> bitcount key4 0 -1
(integer) 8
127.0.0.1:6379>
九 位域
Bitfield命令可以将一个redis字符串看作是一个由二进制位组成的数组,并对变长位宽和任意没有字节对齐的指定整型位域进行寻址访问和修改,可以对指定的整数进行自增和自减操作,可以配置上溢和下溢处理操作;
Bitfield命令可以在一次调用中同时对多个位范围进行操作,接受一系列待执行的操作作为参数,并返回一个数组,数组中的每个元素就是对应操作的执行结果;
Bitfield命令我们可以一次性对多个比特位域进行操作,进行位域修改和溢出控制;
bitfield key
[get encoding offset]
[set encoding offset value]
[incrby encoding offset increment]
[overflow [wrap | sat | fail]]
get encoding offset:返回指定的位域;
set encoding offset value:设置指定位域的值并返回它的原值;
incrby encoding offset increment:自增或自减(increment为负数),指定位域的值并返回它的新值;
overflow [wrap | sat | fail]:设置溢出行为来改变调用incrby指令的后序操作,默认是wrap;
当需要一个整型时,有符号整型需在位前加i,无符号整型需在位前加u,例如u8是一个8位的无符号整型,i16是一个16位的有符号整型;
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> bitfield key1 get i4 0
1) (integer) 6
127.0.0.1:6379> bitfield key1 get i8 0
1) (integer) 104
127.0.0.1:6379> bitfield key1 get i8 8
1) (integer) 101
127.0.0.1:6379> bitfield key1 set i8 8 104
1) (integer) 101
127.0.0.1:6379> get key1
"hhllo"
127.0.0.1:6379> bitfield key1 incrby i8 8 -3
1) (integer) 101
127.0.0.1:6379> get key1
"hello"
127.0.0.1:6379>
十 流
redis5.0之前有两种方案消息队列,List列表实现消息队列和Pub/Sub实现消息队列;
redis5.0之后新增了一个更加强大的数据结构Stream,可以实现消息队列;
Stream实现消息队列,支持消息的持久化、支持自动生成全局唯一id、支持ack确认消息的模式、支持消费者模式,让消息队列更加稳定可靠;
Stream的底层数据结构,一个消息链表,将所有加入的消息都串联起来,每个消息都有一个唯一id和对应的内容
Message Content:消息内容;
Consumer group:消费组,通过xgroup create命令创建,同一个消费组可以有多个消费者;
Last_delivered_id:游标,每个消费组会有个游标last_delivered_id,任意一个消费者读取了消息都会使游标last_delivered_id往前移动;
Consumer:消费者,消费组中的消费者;
Pending_ids:消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有ack(Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理;
队列相关指令:
xadd key [nomkstream] [maxlen|minid [=|~] threshold [limit count]] *|id field value [field value ...]:添加消息到Stream队列,如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列;
命令中的*号表示服务器自动生成 MessageID(类似mysql里面主键auto_increment),后面顺序跟着一堆业务key/value;
生成的消息id有两部分组成,毫秒值时间戳-该毫秒内生成的第几条消息;
信息条目指的是序列号,在相同的毫秒下序列号从0开始递增,序列号是64位长度,理论上在同一毫秒内生成的数据量无法到达这个级别,因此不用担心序列号会不够用;
millisecondsTime指的是Redis节点服务器的本地时间,如果存在当前的毫秒时间戳比以前已经存在的数据的时间戳小的话,那么系统将会采用以前相同的毫秒创建新的ID,也即redis在增加信息条目时会检查当前id与上一条目的id, 自动纠正错误的情况,一定要保证后面的id比前面大,一个流中信息条目的ID必须是单调增的,这是流的基础;
客户端显示传入规则,Redis对于ID有强制要求,格式必须是时间戳-自增Id这样的方式,且后续ID不能小于前一个ID;
Stream的消息内容,也就是图中的Message Content它的结构类似Hash结构,以key-value的形式存在;
xrange key start end [COUNT count]:获取消息列表(可指定范围,从小到大),忽略删除的消息,start表示开始值,-代表最小值,end表示结束值,+代表最大值,count表示最多获取多少个值;
xrevrange key end start [COUNT count]:获取消息列表(可指定范围,从大到小),忽略删除的消息,start表示开始值,-代表最小值,end表示结束值,+代表最大值,count表示最多获取多少个值;
xdel key id [id ...]:删除消息;
xlen key:获取Stream中的消息长度;
xtrim key maxlen|minid [=|~] threshold [limit count]:用于对Stream的长度进行截取,如果已经超长会进行截取,maxlen允许的最大长度,对流进行修剪限制长度,minid允许的最小id,比允许的最小id值小的将会被抛弃;
xread [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]:获取消息(阻塞/非阻塞),只会返回大于指定id的消息,COUNT表示最多读取多少条消息,BLOCK表示是否已阻塞的方式读取消息,默认不阻塞,如果milliseconds设置为0表示永久阻塞;
$代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil
0-0代表从最小的ID开始获取Stream中的消息,当不指定count,将会返回Stream中的所有消息,注意也可以使用0(00/000也都是可以的……)
127.0.0.1:6379> xadd key1 * k1 v1 m1 n1
"1739706302343-0"
127.0.0.1:6379> xadd key1 * k2 v2 m2 n2
"1739706312157-0"
127.0.0.1:6379> xadd key1 * k3 v3 m3 n3
"1739706319337-0"
127.0.0.1:6379> xadd key1 * k4 v4 m4 n4
"1739706327557-0"
127.0.0.1:6379> xrange key1 - +
1) 1) "1739706302343-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
2) 1) "1739706312157-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
3) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
4) 1) "1739706327557-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
127.0.0.1:6379> xrevrange key1 + -
1) 1) "1739706327557-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
2) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
3) 1) "1739706312157-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
4) 1) "1739706302343-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
127.0.0.1:6379> xdel key1 "1739706327557-0"
(integer) 1
127.0.0.1:6379> xlen key1
(integer) 3
127.0.0.1:6379> xadd key1 * k4 v4 m4 n4
"1739706435488-0"
127.0.0.1:6379> xadd key1 * k5 v5 m5 n5
"1739706442495-0"
127.0.0.1:6379> xrange key1 - +
1) 1) "1739706302343-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
2) 1) "1739706312157-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
3) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
4) 1) "1739706435488-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
5) 1) "1739706442495-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379> xtrim key1 maxlen 4
(integer) 1
127.0.0.1:6379> xrange key1 - +
1) 1) "1739706312157-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
2) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
3) 1) "1739706435488-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
4) 1) "1739706442495-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379> xtrim key1 minid "1739706319337-0"
(integer) 1
127.0.0.1:6379> xrange key1 - +
1) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
2) 1) "1739706435488-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
3) 1) "1739706442495-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379> xread count 2 streams key1 $
(nil)
127.0.0.1:6379> xread count 2 streams key1 0-0
1) 1) "key1"
2) 1) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
2) 1) "1739706435488-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
127.0.0.1:6379> xread count 2 streams key1 000
1) 1) "key1"
2) 1) 1) "1739706319337-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
2) 1) "1739706435488-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
127.0.0.1:6379>
消费组相关指令:
xgroup create key group id|$ [MKSTREAM] [ENTRIESREAD entries-read]:创建消费者组,创建消费者组的时候必须指定ID, ID为0表示从头开始消费,为$表示只消费新的消息,队尾新来的消息;
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] id [id ...]:读取消费者组中的消息,stream中的消息一旦被消费组里的一个消费者读取了,就不能在被该消费组内的其他消费者读取了,会读到nil值,但是不同消费组的消费者可以消费同一条消息,消费组的目的是让组内的多个消费者共同分担读取消息,所以通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的,>表示从第一条尚未被消费的消息开始读取;
127.0.0.1:6379> xadd key1 * k1 v1 m1 n1
"1739707152011-0"
127.0.0.1:6379> xadd key1 * k2 v2 m2 n2
"1739707158336-0"
127.0.0.1:6379> xadd key1 * k3 v3 m3 n3
"1739707164075-0"
127.0.0.1:6379> xadd key1 * k4 v4 m4 n4
"1739707169010-0"
127.0.0.1:6379> xadd key1 * k5 v5 m5 n5
"1739707178378-0"
127.0.0.1:6379> xrange key1 - +
1) 1) "1739707152011-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
2) 1) "1739707158336-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
3) 1) "1739707164075-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
4) 1) "1739707169010-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
5) 1) "1739707178378-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379> xgroup create key1 group1 $
OK
127.0.0.1:6379> xgroup create key1 group1 0
(error) BUSYGROUP Consumer Group name already exists
127.0.0.1:6379> xgroup create key1 group2 0
OK
127.0.0.1:6379> xreadgroup group group2 consumerA streams key1 >
1) 1) "key1"
2) 1) 1) "1739707152011-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
2) 1) "1739707158336-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
3) 1) "1739707164075-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
4) 1) "1739707169010-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
5) 1) "1739707178378-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379> xreadgroup group group2 consumerB streams key1 >
(nil)
127.0.0.1:6379> xgroup create key1 group3 0
OK
127.0.0.1:6379> xreadgroup group group3 consumerB streams key1 >
1) 1) "key1"
2) 1) 1) "1739707152011-0"
2) 1) "k1"
2) "v1"
3) "m1"
4) "n1"
2) 1) "1739707158336-0"
2) 1) "k2"
2) "v2"
3) "m2"
4) "n2"
3) 1) "1739707164075-0"
2) 1) "k3"
2) "v3"
3) "m3"
4) "n3"
4) 1) "1739707169010-0"
2) 1) "k4"
2) "v4"
3) "m4"
4) "n4"
5) 1) "1739707178378-0"
2) 1) "k5"
2) "v5"
3) "m5"
4) "n5"
127.0.0.1:6379>
xack key group id [id ...]:ack消息,消息被标记为已处理
xgroup setid key group id|$ [ENTRIESREAD entries-read]:设置消费者组最后递送消息的id;
xgroup delconsumer key group consumer:删除消费者组;
xpending key group [[IDLE min-idle-time] start end count [consumer]]:查询每个消费组内的所有消费者的已读取但未确认的消息;
XINFO CONSUMERS key group:打印consumer的详细信息;
XINFO GROUPS key:打印group的详细信息;
XINFO STREAM key [FULL [COUNT count]]:打印stream的详细信息;
四个特殊符号:
- +:最小和最大可能出现的id;
$:$表示只消费新的消息,当前流中最大的id,可用于将要到来的信息;
>:用于xreadgroup命令,表示迄今为止还没有发送给组中使用者的信息,会更新消费者组的最后id;
*:用于xadd命令中,让系统自动生成id;
十一 redis的key常用操作
在redis中,命令不区分大小写,而key区分大小写;
keys pattern:查找所有符合给定模式(pattern)的key,官网中Supported glob-style patterns:
h?llo matches hello, hallo and hxllo
h*llo matches hllo and heeeello
h[ae]llo matches hello and hallo, but not hillo
h[^e]llo matches hallo, hbllo, ... but not hello
h[a-b]llo matches hallo and hbllo
127.0.0.1:6379> mset hallo 1 hbllo 1 hcllo 1 hdllo 1 hello 1 heello 1 heeello 1
OK
127.0.0.1:6379> keys *
1) "heeello"
2) "hello"
3) "hbllo"
4) "heello"
5) "hcllo"
6) "hallo"
7) "hdllo"
127.0.0.1:6379> keys h?llo
1) "hello"
2) "hbllo"
3) "hcllo"
4) "hallo"
5) "hdllo"
127.0.0.1:6379> keys h*llo
1) "heeello"
2) "hello"
3) "hbllo"
4) "heello"
5) "hcllo"
6) "hallo"
7) "hdllo"
127.0.0.1:6379> keys h[ac]llo
1) "hcllo"
2) "hallo"
127.0.0.1:6379> keys h[^a]llo
1) "hello"
2) "hbllo"
3) "hcllo"
4) "hdllo"
127.0.0.1:6379> keys h[a-c]llo
1) "hbllo"
2) "hcllo"
3) "hallo"
127.0.0.1:6379>
type key:返回key所对应的值的类型
127.0.0.1:6379> set k1 1
OK
127.0.0.1:6379> set k2 aa
OK
127.0.0.1:6379> type k1
string
127.0.0.1:6379> type k2
string
127.0.0.1:6379> lpush k3 1
(integer) 1
127.0.0.1:6379> type k3
list
127.0.0.1:6379>
expire key seconds:给key设置过期时间,以秒为单位;
expireat key timestamp:给key设置过期时间的时间戳,以秒为单位;
pexpire key milliseconds:给key设置过期时间,以毫秒为单位;
pexpireat key milliseconds-timestamp:给key设置过期时间的时间戳,以毫秒为单位;
ttl key:以秒为单位,返回key的剩余生存时间;
pttl key:以毫秒为单位,返回key的剩余生存时间;
persist key:移除key的过期时间,key将持久保持;
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> ttl key1
(integer) -1
127.0.0.1:6379> expire key1 60
(integer) 1
127.0.0.1:6379> ttl key1
(integer) 56
127.0.0.1:6379> persist key1
(integer) 1
127.0.0.1:6379> ttl key1
(integer) -1
127.0.0.1:6379>
exists key:检查key是否存在;
del key:删除key;
127.0.0.1:6379> set key1 1
OK
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> exists key1
(integer) 1
127.0.0.1:6379> del key1
(integer) 1
127.0.0.1:6379> exists key1
(integer) 0
127.0.0.1:6379>
dbsize:查看当前数据库key的数量
127.0.0.1:6379> mset key1 1 key2 a
OK
127.0.0.1:6379> dbsize
(integer) 2
127.0.0.1:6379>
move key db:将当前数据库的key移动到给定的数据库db当中;
select dbindex:切换数据库[0-15],默认是0;
flushdb:清空当前库;
flushall:清空全部库;
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 2
OK
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379>