缓存学习(六):Redis的数据结构及基本命令

目录

0.key

1.string

2.list

3.set

4.hash

5.sorted set(zset)

6.streams

7.衍生类型

7.1 bitmaps

7.2.geo


Redis 5之前一共有六个主要数据结构:key、string、list、set、hash、sorted-set(zset),还有由string衍生出来的bitmaps、由zset衍生出来的geo。key类型实际就是byte数组,因此可以将任何二进制序列作为key使用,虽然key最大可以为512MB,不过最好还是尽量小一点,一般约定redis的key形式如:user:0001:name,代表id为0001的用户的姓名,这种命名方式兼顾可读性和性能。

Redis 5新增了stream类型。

0.key

下面是一些通用操作(或者说是对于key类型的操作):

  • keys pattern:显示匹配到的key,keys *就是显示所有key
  • exists key ...:检查key是否存在
  • expire key seconds:设置key在seconds秒后过期,pexpire是expire的毫秒版本
  • expireat key timestamp:设置key在到达timestamp时过期,pexpireat是expireat的毫秒版本
  • ttl key:查询key的过期时间,如返回-1则代表未设置过期时间,-2则代表键不存在,pttl是ttl的毫秒版本
  • persist key:移除key上设置的过期时间
  • del key:删除一个键值对
  • type key:查询元素类型
  • object subcommand [args...]:执行一些子命令,如:
    • refcount key:返回引用计数
    • encoding key:查询内部编码
    • idletime key:返回数据有多久没被访问过
    • freq key:返回数据访问频率计数
    • help:返回帮助信息
  • info:显示服务器信息
  • ping:测试连通性,成功则返回pong
  • config set config_name value 、config rewrite:前者用来修改配置,后者用于确认修改
  • move key db:移动key到另一个数据库
  • randomkey:随机返回一个对象的key
  • rename key newkey:重命名key
  • renamenx key newkey:重命名key,newkey必须不存在
  • dump key:将值序列化
  • restore key ttl serialized-value option:将序列化的值自动反序列化,然后插入数据库,option有以下可选值:
    • replace:如果key存在则替换
    • absttl:如果使用该选项,ttl必须是timestamp,相当于从expire变成了expireat
    • idletime seconds:参见object
    • freq frequency:参见object
  • migrate host port key option 或 migrate host port "" timeout option: 从远程服务器迁移数据到本机,option有:
    • copy:仅复制数据,而不是移动数据
    • replace:当本机有同名数据时,进行覆盖
    • keys key ...:适用于第二种形式,指定要迁移的key
  • touch key ...:更新指定key的访问时间
  • sort key option:对list、set、zset进行排序,option如下:
    • by pattern:使用外部键作为排序依据,例如list中有三个值 1 2 3,若pattern为weight_*,则会根据weight_1、weight_2、weight_3的值来排序,而不是根据字面值排序。pattern可以是不存在的键,这样就相当于没排序。
    • limit offset count:限制返回值数目
    • get pattern [get pattern...]:不返回排序数据本身,而是返回匹配的外部键的值,例如pattern为object_*,则返回object_1、object_2、object_3的值,而非字面值,get #就是返回被排序的数据
    • asc|desc:升序还是降序排序
    • alpha:对字符串按字典序排序
    • store destination:将排序结果输出
  • scan cursor [match pattern] [count count]:渐进式便利,返回下一个cursor值和本次遍历的键,与之作用相似的还有sscan、zscan、hscan,不做赘述,下面是个例子:
127.0.0.1:6379> scan 0
1) "15"
2)  1) "key3"
    2) "key2"
    3) "key6"
    4) "key9"
    5) "key4"
    6) "key1"
    7) "key10"
    8) "key7"
    9) "key8"
   10) "key5"
127.0.0.1:6379> scan 15
1) "0"
2) (empty list or set)

可以看到,第一次执行scan 0后,返回的新cursor是15,表示这一批最多遍历了15个数据,下一次执行scan需要从15开始,不过因为数据不够,所以执行scan 15后,cursor又回到了0。

  • wait num_of_replicas timeout:阻塞客户端直到上一次写入操作的结果传播到了num_of_replicas个副本处,或者超时
  • unlink key ...:相当于del,只不过会忽略不存在的键

此外还有一些Redis管理命令:

  • auth password:设置密码
  • echo message:显示给定消息,没什么具体作用
  • ping [message]:ping服务器,如果设置了message,ping成功后会返回这个message
  • quit:关闭客户端,断开连接
  • select db:更换数据库,例如 select 0就是切换到db0
  • swapdb db_1 db_2:交换两个数据库

以上命令只是一部分,Redis的所有命令可以查看官方文档:https://redis.io/commands

1.string

string可以用来表示3种值:字符串、正数、浮点数,可以自动进行转换,它支持的操作如下:

  • set key value option:用于设置键值对,key代表键,value代表值,option有以下可选项:
    • ex seconds:设置过期时间,单位秒
    • px milliseconds:设置毫秒级过期时间
    • nx:只有待设置的key不存在才会执行
    • xx:只有待设置的key存在才会执行
  • get key:获取值
  • mset key value [key value...]:同时设置多个键值对(至少一个)
  • mget key [key...]:同时获取多个值
  • getset key value:将key对应的值设置为value,并返回之前的值
  • setex key seconds value:相当于 set key value ex seconds
  • setnc key value:相当于 set key value nx
  • incr/decr key:自增/自减,只能用于整数
  • incrby/decrby key number:使key对应的值增加/减少number,仅用于整数
  • incrbyfloat key number:作用同上,不过仅用于浮点数
  • append key value:向字符串尾部追加值
  • strlen key:查询长度
  • setrange key offset value:替换字符串offset位置的值,offset从0开始计数,即第一个字符的offset为0
  • getrange key start end:获得字符串下标从start到end范围内的子字符串

对于set、get,如果要设置的键非常多,最好使用mset、mget替代,因为n次set/get需要n次网络I/O和n次读写,而批量操作n个元素则只需要1次网络I/O和n次读写,分布式环境下,网络I/O是主要的延迟来源,减少网络I/O次数可以显著提升性能。

此外,对于数值,如果使用了append等操作,就会永远转换为字符串,再也无法使用数字类型的操作。

string一共有三种内部编码:int、embstr、raw,第一个可以存储8字节长整型数据,后面两个用于存储字符串,embstr可以处理39字节以下的数据,raw可存储39字节以上的数据。其中,字符串类型实际存储在sdshdr结构体中(定义于sds.h头文件),以sdshdr8为例:

struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

buf数组存储了字符串的内容,实际长度会大于存储的内容的长度,以便在append时不必重新申请内存。string刚初始化时,sizeof(buf)=len+1(还要存放一个'/0'),在字符串操作完成后,sizeof(buf)=2*len+1(len<1MB)或2*len+1MB(len>=1MB)。

string的主要应用有:

  • 缓存数据:这个不需要多解释
  • 分布式计数器:利用incr/decr实现
  • 分布式锁:利用setnx、setex等实现
  • 状态存储:通过保存session等信息,将服务无状态化

2.list

Redis的list具有双端进出、有序的特点,可最多存放2^{^{32}}-1个元素,其操作如下:

  • lpush/rpush key value [value...]:从左端/右端向一个list插入数据,list不存在则新建
  • lpushx/rpushx  key value [value...]:从左端/右端向一个存在的list插入数据 
  • linsert key before/after pivot value:在pivot前/后插入新值
  • lrange key start end:返回列表中下标从start到end的元素,从左向右则下标范围是0~N-1(N代表列表元素数),从右向左则是-1~-N
  • lindex key index:获得指定下标的元素
  • llen key:获得列表的长度
  • lpop/rpop key:删除并返回列表中最左端的元素
  • lrem key count value:从列表中删除count个值为value的元素,如果count>0就是从左向右删除,count<0就是从右向左删除,count=0则全部删除
  • ltrim key start end:仅保留列表中start到end范围内的元素,其他的全部删除
  • lset key index value:修改下标为index的元素的值
  • blpop/brpop key [key...] timeout:阻塞式地从左端/右端弹出给定的列表的元素,阻塞时间最多为timeout秒,如果timeout为0,则无限阻塞
  • rpoplpush source destintion:从source尾部弹出一个数据,并从头部存入destination中
  • brpoplpush source destination timeout:上一个命令的阻塞版本

list的内部编码有ziplist、linkedlist和quicklist三种,ziplist的结构如下:

     ...  

zlbytes代表整个ziplist的长度,zltail指向最后一个元素,zllen代表元素个数,zlend的作用类似于'\0',标记ziplist结束。entry则是实际保存元素的结构,源码如下(位于ziplist.c):

typedef struct zlentry {
    unsigned int prevrawlensize; /* Bytes used to encode the previous entry len*/
    unsigned int prevrawlen;     /* Previous entry len. */
    unsigned int lensize;        /* Bytes used to encode this entry type/len.
                                    For example strings have a 1, 2 or 5 bytes
                                    header. Integers always use a single byte.*/
    unsigned int len;            /* Bytes used to represent the actual entry.
                                    For strings this is just the string length
                                    while for integers it is 1, 2, 3, 4, 8 or
                                    0 (for 4 bit immediate) depending on the
                                    number range. */
    unsigned int headersize;     /* prevrawlensize + lensize. */
    unsigned char encoding;      /* Set to ZIP_STR_* or ZIP_INT_* depending on
                                    the entry encoding. However for 4 bits
                                    immediate integers this can assume a range
                                    of values and must be range-checked. */
    unsigned char *p;            /* Pointer to the very start of the entry, that
                                    is, this points to prev-entry-len field. */
} zlentry;

这里可以划分为两部分:prevrawlensize和prerawlen是对前驱entry的描述,剩下的属性是对本entry的描述,p指针指向实际存储的数据。linkedlist编码的list结构体和listNode结构体源码如下(位于adlist.h头文件):

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct list {
    listNode *head;
    listNode *tail;
    void *(*dup)(void *ptr);
    void (*free)(void *ptr);
    int (*match)(void *ptr, void *key);
    unsigned long len;
} list;

quicklist是Redis 3.2之后提供的编码,相当于把ziplist当作linkedlist的listnode,可以结合两者的优点:

typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* total count of all entries in all ziplists */
    unsigned long len;          /* number of quicklistNodes */
    int fill : 16;              /* fill factor for individual nodes */
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
} quicklist;

list的一个应用就是消息队列,例如生产者使用lpush生产消息,多个消费者使用brpop消费消息。

3.set

不允许重复元素的数据结构,也可以存储2^{^{32}}-1个元素,但是无法通过下标获取元素,集合操作分为集合内操作和集合间操作。

首先是集合内的操作:

  • sadd key value [value...]:向一个集合内插入多个值
  • srem key value [value...]:从一个集合中删除给定值
  • scard key:计算集合元素数量
  • sismember key value:判断value是否在key对应的集合中
  • srandmember key [count]:从集合中随机返回count个元素(不写count就返回1个)
  • spop key [count]:从集合中随机删除并返回count个元素(不写count就返回1个)
  • smembers key:返回集合所有元素

然后是集合间操作:

  • sinter key ...:求多个集合的交集
  • sunion key...:求多个集合的并集
  • sdiff key...:求多个集合的差集
  • sinterstore/sunionstore/sdiffstore destination key...:求交/并/差集,然后把结果保存到指定集合中

set的内部编码有intset(位于intset.h)和hashtable(位于dict.h)两种。

4.hash

可以理解为嵌套的HashMap,其value的类型为string,所以它的操作基本就是string的操作加上一个h:

  • hset key subkey subvalue:向哈希插入一个对,成功返回1,失败返回0,相应地,也有hsetex和hsetnx
  • hget key subkey:从哈希中取出subkey对应的值,不存在则返回nil
  • hdel key subkey:从哈希中删除一个键值对
  • hlen key:计算哈希中有多少个键值对
  • hmget key subkey...:批量获取值
  • hmset key subkey subvalue ...:批量插入键值对
  • hexists key subkey:判断subkey是否存在
  • hkeys key:获取哈希中所有subkey
  • hvals key:获取哈希中所有subvalue
  • hgetall key:获取哈希中所有键值对
  • hincrby/hincrbyfloat key subkey number:修改数值
  • hstrlen key subkey:计算某个subvalue的长度

hash的内部编码有两个:ziplist和hashtable,在dict.h中,可以看到,hashtable为三层结构:dict - dictht - dictEntry:

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;

typedef struct dictht {
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

dict实际就是个二维数组,通过对插入的subkey取模,就能得到桶号,然后把数据包装为dictEntry存入。这里ht之所以是个数组,是为了提供伸缩,hashtable的伸缩实际就是创建一个新hashtable,然后把桶逐步迁移,h[0]代表原来的hashtable,h[1]就是新创建的hashtable,如果迁移过程中进行访问,会先访问h[0],如果要访问的桶已经迁移到h[1],则再去h[1]访问。

ziplist类似于list的实现,区别在于,list中只存放值,而hash中则是交替存放subkey和subvalue,即:

... - subkey1 -subvalue1 -subkey2 -subvalue2 -...

5.sorted set(zset)

zset有一个新概念:评分,将评分作为元素排序的依据,也可以理解为插入的是 score-string 对,不过score可以相同

  • zadd key [nx|xx] [ch] [incr] score member [score member ...]:插入数据,nx、xx、incr不多解释,ch代表要修改的数据个数
  • zcard key:显示某个zset下有多少个键值对
  • zscore key member:返回某个成员的评分,成员不存在返回nil
  • zrank/zrevrank key member:从低到高/从高到低计算排名
  • zrem key member ...:删除成员
  • zincrby key number member:修改评分
  • zrange/zrevrange key start end [withscores]:升序/降序返回指定排名范围内的数据,如果带上withscores选项,则同时返回分数
  • zrangebyscore/zrevrangebyscore key min max [withscores] [limit offset count]:返回指定分数范围内的数据,如果要返回所有数据,可以将min max设定为 -inf +inf,代表无限大小,此外,min max还支持开闭区间,limit选项可设置起始位置和返回值数量,如下是一个双开区间的例子:
127.0.0.1:6379> zadd test 1 "one" 2 "two" 3 "three" 4 "four" 5 "five"
(integer) 5
127.0.0.1:6379> zrangebyscore test (1 (4
1) "two"
2) "three"
  • zrangebylex/zrevrangebylex key min max [limit offset count]:返回所有key在指定范围内的元素,支持数值和字典序排序
  • zcount key min max:返回分数在指定范围内的元素数量
  • zremrangebyrank key start end、zremrangebyscore key min max、zremrangebylex key min max:按照范围删除数据
  • zpopmin/zpopmax key [count]:弹出评分最小/大的count个元素
  • bzpomin/bzpopmax key ... timeout:zpopmin/zpopmax的阻塞版

zset和set一行,也支持集合间操作:

  • zinterstore/zunionstore destination keynum key ... [weights weight...] [aggregate sum|min|max]:求交集/并集。weights用来给参与计算的zset一个权重,在计算时,每个zset内的元素的评分都将乘上这个权重;aggregate:用于统计成员分值的总和、最小值、最大值

zset虽然也是set,不过内部编码和set完全不同,它有两种内部编码:ziplist、skiplist。这里主要介绍skiplist,首先上源码(位于server.h):

typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

typedef struct zset {
    dict *dict;
    zskiplist *zsl;
} zset;

每个skiplist节点,除了有string类型的元素值、双精度浮点型的score外,还有一个zskiplistLevel类型的数组,代表同高度的元素,内部包含一个forward指针,指向同高度元素,和一个无符号长整型值span,代表两个节点间的距离。这种设计在zrange和zremrangebyrank操作中可以有效提高效率。

从整个zset的结构看,它将hashtable和skiplist结合使用,也可以提升操作效率。

6.streams

streams是Redis 5新增的类型,看名字也能猜到,它的主要用处类似Kafka等MQ,可用于日志系统、消息队列等,而且也引入了Kafka的Consumer Group概念。此处是官方介绍:https://redis.io/topics/streams-intro

streams支持的命令如下:

  • xadd key id field string [field string ...]:向流中添加新的条目,返回条目的id。key是stream对应的键;id是条目的id,有两种形式:1)timestamp+seq_num,例如 1556085743647-0,代表的是1556085743647这1毫秒中第1个id  2)* 代表自动生成id;field和string就是条目内容,即一个键值对。下面是一个例子:
127.0.0.1:6379> xadd mystream * name zhangsan age 18 sexual male
"1556086502267-0"
  • xlen key:获取流中条目数量
  • xdel key id...:从流中删除指定的条目
  • xrange/xrevrange key start end [count count]:获取id在指定范围内的条目,count选项可以控制返回值数量。这里start end可以不是完整的id,而仅使用时间戳,也可以使用 - 代表最小id,使用 + 代表最大id,下面是一个例子:
127.0.0.1:6379> xrange mystream - +
1) 1) "1556086502267-0"
   2) 1) "name"
      2) "zhangsan"
      3) "age"
      4) "18"
      5) "sexual"
      6) "male"
  • xread [count count] [block miiliseconds] streams key ... id ...:可以从一或多个流中读取条目,同样支持不完整id,id可以设为“$”,表示仅获取新条目,如果使用了block选项,则会持续监听流直到超时,并获取新加入的条目,以下是一个例子:
127.0.0.1:6379> xread count 2 streams mystream 0-0
1) 1) "mystream"
   2) 1) 1) "1556086502267-0"
         2) 1) "name"
            2) "zhangsan"
            3) "age"
            4) "18"
            5) "sexual"
            6) "male"
      2) 1) "1556090957152-0"
         2) 1) "name"
            2) "lisi"
            3) "age"
            4) "19"
            5) "sexual"
            6) "female"
127.0.0.1:6379> xread count 2 block 1000 streams mystream $
(nil)
(1.07s)
127.0.0.1:6379> xread count 2 streams mystream $
(nil)
  • xgroup [create key groupname id] [setid key groupname id] [destroy key groupname] [delconsumer key groupname consumername]:用于管理Consumer Group,该命令由四个子命令组成:
    • create:创建一个新的Consumer Group,id是读取起点,即从该条目开始读取,可以用“$”指代流中当前的最后一个条目的id(此时只读取新加入的条目),用0指代第一个条目(此时读取所有已传输的条目和新加入的条目)
    • setid:修改指定Consumer Group下一个条目的id,id格式同上
    • destory:删除指定Consumer Group
    • deleteconsumer:从Consumer Group中删除指定消费者
  • xinfo [consumers key groupname] [groups key] [stream key] [help]:获取指定Consumer Group或流的信息,consumers可以查询一个消费者组中有哪些消费者,group可查询一个流上有多少消费者组
  • xtrim key maxlen [~] count:用来控制流的大小,会淘汰旧数据。例如mystream这个流原本有5条数据,以下命令可以仅保留其中最新的2条数据:
127.0.0.1:6379> xtrim mystream maxlen 2
(integer) 3
127.0.0.1:6379> xinfo stream mystream
 1) "length"
 2) (integer) 2
...

maxlen和count之间的“~”表示约数,即命令执行后,流的实际大小会比指定的大小大上一些,一般会多几十条

  • xreadgroup group groupkey consumer [count count] [block milliseconds] [noack] streams key ... id ...:可以理解为xread命令的扩展,支持了Consumer Group,id部分可以用“>”代指所有未接收的条目
  • xpending key group [start end count] [consumer]:用于检查指定消费者组在指定流中的待处理消息,以下是一个例子:
127.0.0.1:6379> xgroup create mystream testgroup 0-0
OK
//执行7次 xadd 命令
127.0.0.1:6379> xpending mystream testgroup
1) (integer) 7
2) "1556109904690-0"
3) "1556109910400-0"
4) 1) 1) "testconsumer"
      2) "7"

返回值有四部分,第一部分是待处理消息总数,第二部分和第三部分是未处理消息的开始和结束id,第四部分是当前所有的consumer及它们各自的未处理消息数。该命令有一个应用,可以用于配合xclaim命令,将离线consumer未处理的消息转交给其他consumer处理。

  • xclaim key group consumer min-idle-time id... [idle milliseconds] [time timestamp] [retrycount count] [force] [justid]:该命令可变更流中消息的所有权。min-idle-time可根据xpending来决定,以下是使用示例:
127.0.0.1:6379> xpending mystream testgroup - + 2
1) 1) "1556109904690-0"
   2) "testconsumer"
   3) (integer) 988495
   4) (integer) 1
2) 1) "1556109906511-0"
   2) "testconsumer"
   3) (integer) 988495
   4) (integer) 1
127.0.0.1:6379> xreadgroup group testgroup testconsumer2 count 2 streams mystream >
(nil)
127.0.0.1:6379> xclaim mystream testgroup testconsumer2 988495 1556109904690-0
1) 1) "1556109904690-0"
   2) 1) "name"
      2) "jerry"
      3) "age"
      4) "15"
      5) "sexual"
      6) "male"
127.0.0.1:6379> xpending mystream testgroup
1) (integer) 7
2) "1556109904690-0"
3) "1556109910400-0"
4) 1) 1) "testconsumer"
      2) "6"
   2) 1) "testconsumer2"
      2) "1"

xpending key group start end count的返回值构成如下: id、所属consumer、空闲时间(根据这个设置min-idle-time)、消息传递次数,示例中将第一条消息转交给了testconsumer2,然后可以看到,消息总数不变,还是7,但是在第四部分出现了testconsumer2,它拥有一条消息。

  • xack key group id ...:从消费者组中移除一条消息,继续沿用上面的例子:
127.0.0.1:6379> xack mystream testgroup 1556109904690-0
(integer) 1
127.0.0.1:6379> xpending mystream testgroup
1) (integer) 6
2) "1556109906511-0"
3) "1556109910400-0"
4) 1) 1) "testconsumer"
      2) "6"

可以看到,对testconsumer2的消息执行xack后,消息总数变成了6条 

7.衍生类型

7.1 bitmaps

bitmaps是由字符串衍生出来的,不过Redis官方没有将其当作一个独立类型。实际就是将每个字符当作一位进行操作,专属操作如下:

  • setbit key offset [0|1]:实际就是将二进制串的第offset位设置为0或1
  • getbit key offset:获取二进制串的第offset位的值
  • bitcount key [start] [end]:统计二进制串在范围内有多少个1
  • bitop operation destkey key ...:执行bitmap之间的运算,然后把结果保存到destkey中,operation就是常见的 and or xor not 四种
  • bitpos key targetbit [start] [end]:计算指定范围内第一个值为targetbit的位置
  • bitfield key [get type offset] [set type offset value] [incrby type offset increment] [overflow wrap|sat|fail]:bitfield可以将一个string当作bitmap处理,然后获取/设置/增加指定位置的值,overflow选项用来控制溢出,三个选项的作用:
    • wrap:对于有符号整数,如果发生溢出,则取负值,例如127再加1,就会变成-128
    • sat:下溢时设置为整数最小值,上溢时设置为整数最大值,例如127加1,还是127
    • fail:返回nil并告知调用者

7.2.geo

geo实际就是zset,所以可以使用zset的命令,例如zrem就可以用于删除geo中存储的地理信息。geo类型的专属命令如下:

  • geoadd key longtitude latitude member [longtitude latitude member ...]:添加地理信息,可以理解为把经纬度合一起当作元素的评分
  • geopos key member:获取经纬度
  • geohash key member ...:返回每一个member的geohash字符串,可以到geohash.org网站进行解码
  • geodist key member1 member2 [unit]:计算两个点之间的距离,默认单位为米(m),其他可选单位有:千米(km)、英里(mi)、英尺(ft)。由于该命令将地球算作一个正球体,因此计算时可能会有误差
  • georadius key longtitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [asc|desc] [store key] [storedist key]:返回geo集合中,距离给定点一定范围内的点。
    • withcoord表示结果包含经纬度
    • withdist表示结果包含到中心点的距离
    • withhash表示结果包含geohash
    • count表示返回结果最多有多少个
    • asc、desc表示结果按升序/降序排列
    • store key表示将结果(geo)存入指定键
    • storedist key表示将结果(距离)存入指定键
  • georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [asc|desc] [store key] [storedist key]:和georadius作用一致

你可能感兴趣的:(Redis,缓存)