Redis(REmote DIctionary Serve)是个开源的,内存中的数据结构存储系统,可用于当作数据库、缓存、信息中间件。

Redis特点:安全实用

  • 每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET)操作。因为它将数据保存在内存中仅使用磁盘进行持久化
  • 安全 所有操作都是原子性的。确保了数据操作的一致性。
  • 实用 Redis提供了丰富的数据结构类型(String、Hash、List、Set、SortedSet、HyperLogLog、GEO)。你可以利用这些数据结构做缓存、消息队列(Redis本地支持发布/订阅)、应用程序的短暂数据、共享session

安装

Mac OS

1
$ brew install redis

客户端 /usr/local/bin/redis-server/usr/local/bin/redis-cli

配置文件 /usr/local/etc/redis.conf

Linux

下载&安装

1
2
3
4
5
6
7
8
9
wget http://download.redis.io/releases/redis-4.0.9.tar.gz # 下载包
tar -xf redis-4.0.9.tar.gz # 解压
cd redis-4.0.9
make PREFIX=/application/redis-4.0.9/ install # 将redis安装到 /application/redis-4.0.9/
ln -s /application/redis-4.0.9/ /application/redis/ # 创建 redis目录软连接
ln -s /application/redis/bin/redis-server /usr/bin/redis-server # redis-server redis服务端
ln -s /application/redis/bin/redis-cli /usr/bin/redis-cli # redis-cli redis客户端
cp ./redis.conf /application/redis/conf/6379.conf # 创建 redis配置文件
cp utils/redis_init_script /etc/rc.d/init.d/redis # 添加进系统自启动

修改redis配置文件

vim /application/redis/conf/6379.conf修改内容如下:

  • daemonize no 改为daemonize yes // 后台运行
  • pidfile /var/run/redis.pid 改为pidfile /var/run/redis_6379.pid
  • 注释掉绑定的主机,否则客户端无法连接 #bind 127.0.0.1 // 支持远程访问
  • protected-mode yes 改为 protected-mode no

将redis加入服务

vim /etc/rc.d/init.d/redis修改内容如下:

  • 在监本第一行后面添加一行内容为:#chkconfig: 2345 80 90
  • EXEC改为/usr/bin/redis-server
  • CLIEXEC改为/usr/bin/redis-cli
  • CONF改为/application/redis/conf/6379.conf
  • 更改Redis开启的命令,以后台运行的方式执行 $EXEC $CONF &

注册redis

chkconfig --add redis

vi /etc/profile 添加export PATH=$PATH:/application/redis/bin

source /etc/profile

启动redis

service redis start

配置

Redis的配置文件默认地址是:/usr/local/etc/redis.conf 在上面安装方案中将配置文件放入:/application/redis/conf/6379.conf

有两种方式修改Redis配置项:1. 直接修改配置文件。 2. 进入redis-cli,通过命令行修改redis配置项。

命令行

进入redis-cli命令行通过CONFIG GET key获取配置项信息,通过CONFIG SET key value设置配置项值。

1
2
3
$ redis 127.0.0.1:6379> CONFIG GET loglevel # 获取日志等级
$ redis 127.0.0.1:6379> CONFIG GET # 查看所有配置项
$ redis 127.0.0.1:6379> CONFIG SET loglevel "notice" # 设置日志等级

并不是所有的配置项都可以通过CONFIG GET/SET配置,而且CONFIG GET/SET配置方法并不会影响配置文件,如果你希望将修改的配置写入配置文件那就需要使用命令:CONFIG REWRITE

配置文件

基础配置

  1. 指定内存空间

    如果你需要指定内存大小,可以通过下面的格式:

1
2
3
4
5
6
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes

​ 内存单位是不区分大小写的,1GB 1Gb 1gB表示同一个大小空间。

  1. 后台运行 daemonize

    默认情况下Redis不是后台运行的,如果需要在后台运行需要将daemonize设为yes

1
daemonize yes
  1. pid

    当Redis 开启后台运行,redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址。当运行多个redis 服务时,需要指定不同的pid文件和端口。

  2. 指定接受主机IP bind

    Redis 默认只接受本机的客户端连接 bind 127.0.0.1。如果将它注释掉它将接受所有客户端请求。

  3. 指定端口 port

    Redis 默认端口是:6379。port 6379

  4. 客户端连接时的超时时间 timeout

    设置客户端最长的空闲时间,如果超过这个时间客户端没有操作服务端会自动断开该连接。timeout 10 单位是秒。当设置为0时是表示关闭该功能。

  5. 日志等级 loglevel

    Redis 日志等级分为四个等级:debug(适合开发环境,客户端操作信息都会输出日志)、verbose、notice(适合生产环境)、warning(异常信息)。

  6. 配置log文件地址 logfile

    Redis 默认日志输出地址是 stdout表示终端输出,如果Redis是后台运行它默认日志输出地址是:/dev/null

    通过logfile /var/log/redis/redis.log你可以指定Redis 日志输出地址。

  7. 设置数据库连接数 databases

    Redis 默认连接数据库是0,可以通过select <dbid>指定连接的数据库,数据连接范围应该是:0 - databasesdatabases 16

  8. 同时连接的客户数 maxclients

    设置同时连接客户端的数量:maxclients 128。当超过这个连接时,服务端会拒绝连接,客户端会接受到报错。

SLOW LOG

  1. **超时连接日志记录 slowlog-log-slower-than **

    设定最大的查询命令执行时间,当超过这个时间的命令会被记录日志中。

  2. 声明超时日志最大长度 slowlog-max-len

    该命令不会限制日志大小,只是声明日志最大长度。

Snapshotting

  1. save

    将数据保存到磁盘中。格式:save <seconds> <changes>

    在指定时间seconds内有changes次写操作,则将数据保存到磁盘上。

    1
    2
    3
    save 900 1
    save 300 10
    save 60 10000
  2. dbfilename

    定义保存到磁盘上文件名字:dbfilename fileName

  3. dir

    数据保存在磁盘上的目录:dir ./

APPEND ONLY MODE

Redis 默认是异步转存数据从内存到磁盘。在大多数时候这个模式没有问题,但在Redis进程挂掉或断电情况下会导致几分钟内写入数据的丢失。

Append only 提供了一种持久模式,Redis会在#appendonly.aof 文件中添加每一个写操作,这个文件会在Redis启动时被读取来在内存中重新构建数据集。

1
2
3
4
5
6
appendonly on # 开启AOF模式
appendfilename "appendonly.aof" # AOF模式保存的文件名
appendfsync everysec # 保存数据策略
# no /不使用fsync,系统自己将缓存数据刷新至硬盘中,这是最快的方案。
# always /每次写入操作后更新日志,最慢但是最安全的方式。
# everysec /一秒中执行一次fsync,折中方案

Key 键

Redis是极简的key-value模式的数据库。key是value在数据库中的唯一标识符,通过key你可以快速查找到对应的值。

Redis提供一些方法用于处理key:

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
redis> SET name huangz # 设置一直key为name值为huangz数据
redis> EXISTS name # 判断key为name是否存在
(integer) 1 # name key存在
redis> DEL name # 删除key name
(integer) 1 # 删除成功
redis> EXISTS name
(integer) 0 # name key不存在

redis> SET cache_page "www.google.com" # 设置 cache_page
OK
redis> EXPIRE cache_page 30 # 设置过期时间为 30 秒 格式:EXPIRE key seconds 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
(integer) 1
redis> TTL cache_page # 查看剩余生存时间 TTL key
(integer) 23

redis> SET cache www.google.com
OK
redis> EXPIREAT cache 1355292000 # 这个 key 将在 2012.12.12 过期 EXPIREAT于EXPIRE类似只是时间参数是 UNIX 时间戳(unix timestamp)
(integer) 1

redis> MSET one 1 two 2 three 3 four 4 # 一次设置 4 个 key MSET key value key value... 同时给多个key设置值
OK
redis> KEYS *o* #查找所有符合给定模式 pattern 的 key
1) "four"
2) "two"
3) "one"

redis> SELECT 0 # redis默认使用数据库 0,为了清晰起见,这里再显式指定一次。
OK
redis> SET song "secret base - Zone"
OK
redis> MOVE song 1 # 将 song 移动到数据库 1
(integer) 1

redis> SET message "hello world"
OK
redis> RENAME message greeting #修改 message key为 greeting 即使greeting存在也会被替换掉
OK


redis> SET player "MPlyaer"
OK
redis> EXISTS best_player
(integer) 0
redis> RENAMENX player best_player # 修改key 名,只有当新key保存在才会修改成功
(integer) 1

String 字符串

SET、SETEX、PSETEX

设置字符串值。格式:SET key value [EX seconds] [PX milliseconds] [NX|XX]

1
2
3
4
5
6
7
8
redis 127.0.0.1:6379> SET key "value"
OK

redis 127.0.0.1:6379> SET key-with-expire-time "hello" EX 10086 # 等同于 SETEX key-with-expire-time 10086 "hello" 设置key过期秒数
OK

redis 127.0.0.1:6379> SET key-with-pexpire-time "moto" PX 123321 # 等同于 PSETEX key-with-pexpire-time 123321 "moto" 设置key过期毫秒数
OK
  • EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value
  • PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecondvalue value
  • NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value
  • XX :只在键已经存在时,才对键进行设置操作。

MSET、MGET

同时设置多个key-value。MSET key value [key value …]

1
2
3
4
5
6
7
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK

redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"

MSETNX

同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。MSETNX key value [key value …]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
# MSET 的给定 key 当中有已存在的 key

redis> MSETNX rmdbs "Sqlite" language "python" # rmdbs 键已经存在,操作失败
(integer) 0

redis> EXISTS language # 因为 MSET 是原子性操作,language 没有被设置
(integer) 0

redis> GET rmdbs # rmdbs 也没有被修改
"MySQL"

GETSET

将给定 key 的值设为 value ,并返回 key 的旧值(old value)。GETSET key value

1
2
3
4
5
6
7
8
9
10
11
redis> GETSET db mongodb    # 没有旧值,返回 nil
(nil)

redis> GET db
"mongodb"

redis> GETSET db redis # 返回旧值 mongodb
"mongodb"

redis> GET db
"redis"

APPEND

如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。

如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。

APPEND key value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 对不存在的 key 执行 APPEND

redis> EXISTS myphone # 确保 myphone 不存在
(integer) 0

redis> APPEND myphone "nokia" # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5 # 字符长度


# 对已存在的字符串进行 APPEND

redis> APPEND myphone " - 1110" # 长度从 5 个字符增加到 12 个字符
(integer) 12

redis> GET myphone
"nokia - 1110"

Hash 哈希表

Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。

HSET

HSET key field value ­­ 设置 key 指定的哈希集中指定字段的值。

1
2
redis> HSET website google "www.g.cn"     # 设置一个新域
(integer) 1

HSETNX

HSETNX key field value将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。

若域 field 已经存在,该操作无效。

1
2
3
4
5
redis> HSETNX nosql key-value-store redis
(integer) 1

redis> HSETNX nosql key-value-store redis # 操作无效,域 key-value-store 已存在
(integer) 0

HMSET

HMSET key field value [field value ...]同时将多个 field-value (域-值)对设置到哈希表 key 中。

1
2
3
4
5
6
7
8
redis> HMSET website google 'www.google.com' yahoo 'www.yahoo.com'
OK

redis> HGET website google
"www.google.com"

redis> HGET website yahoo
"www.yahoo.com"

HMGET

HMGET key field [field ...]返回哈希表 key 中,一个或多个给定域的值。List 列表

1
2
3
4
5
6
7
redis> HMSET pet dog "doudou" cat "nounou"    # 一次设置多个域
OK

redis> HMGET pet dog cat fake_pet # 返回值的顺序和传入参数的顺序一样
1) "doudou"
2) "nounou"
3) (nil) # 不存在的域返回nil值

HKEYS

HKEYS key返回哈希表 key 中的所有域。

1
2
3
4
5
6
redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HKEYS website
1) "google"
2) "yahoo"

List(列表)

字符串列表管理方式。

LPUSH

LPUSH key value [value ...]将一个或多个值 value 插入到列表 key 的表头。

如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
redis> LPUSH languages python
(integer) 1

# 加入重复元素

redis> LPUSH languages python
(integer) 2

redis> LRANGE languages 0 -1 # 列表允许重复元素
1) "python"
2) "python"


# 加入多个元素

redis> LPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"

RPUSH

RPUSH key value [value ...]将一个或多个值 value 插入到列表 key 的表尾(最右边)。

如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist aRPUSH mylist bRPUSH mylist c

1
2
3
4
5
6
7
8
9
# 添加多个元素

redis> RPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"

LINDEX

LINDEX key index返回列表 key 中,下标为 index 的元素。

下标(index)参数 startstop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。

你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSH mylist "Hello"
(integer) 2

redis> LINDEX mylist 0
"Hello"

redis> LINDEX mylist -1
"World"

redis> LINDEX mylist 3 # index不在 mylist 的区间范围内
(nil)

LRANGE

LRANGE key start stop返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

下标(index)参数 startstop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。

你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

1
2
3
4
5
6
7
8
9
10
11
12
redis> RPUSH fp-language 'lisp'
(integer) 1

redis> LRANGE fp-language 0 0
1) "lisp"

redis> RPUSH fp-language 'scheme'
(integer) 2

redis> LRANGE fp-language 0 1
1) "lisp"
2) "scheme"

Set 集合

Set 就是一个集合,集合的概念就是一堆不重复值的组合。

SADD

SADD key member [member ...]将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 添加单个元素
redis> SADD bbs "discuz.net"
(integer) 1


# 添加重复元素
redis> SADD bbs "discuz.net"
(integer) 0


# 添加多个元素
redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2

redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"

SMEMBERS

SMEMBERS key返回集合 key 中的所有成员。

1
2
3
4
5
6
7
8
9
# 非空集合

redis> SADD language Ruby Python Clojure
(integer) 3

redis> SMEMBERS language
1) "Python"
2) "Ruby"
3) "Clojure"

SCARD

SCARD key返回集合 key 的基数(集合中元素的数量)。

1
2
3
4
5
6
7
8
9
10
11
redis> SADD tool pc printer phone
(integer) 3

redis> SCARD tool # 非空集合
(integer) 3

redis> DEL tool
(integer) 1

redis> SCARD tool # 空集合
(integer) 0

SDIFF

SDIFF key [key ...]返回一个集合的全部成员,该集合是所有给定集合之间的差集。

1
2
3
4
5
6
7
8
9
10
11
12
13
redis> SMEMBERS peter's_movies
1) "bet man"
2) "start war"
3) "2012"

redis> SMEMBERS joe's_movies
1) "hi, lady"
2) "Fast Five"
3) "2012"

redis> SDIFF peter's_movies joe's_movies
1) "bet man"
2) "start war"

SINTER

SINTER key [key ...]返回一个集合的全部成员,该集合是所有给定集合的交集。

1
2
3
4
5
6
7
8
9
10
11
redis> SMEMBERS group_1
1) "LI LEI"
2) "TOM"
3) "JACK"

redis> SMEMBERS group_2
1) "HAN MEIMEI"
2) "JACK"

redis> SINTER group_1 group_2
1) "JACK"

SUNION

SUNION key [key ...]返回一个集合的全部成员,该集合是所有给定集合的并集。

1
2
3
4
5
6
7
8
9
redis> SMEMBERS songs
1) "Billie Jean"

redis> SMEMBERS my_songs
1) "Believe Me"

redis> SUNION songs my_songs
1) "Billie Jean"
2) "Believe Me"

SortedSet 有序集合

Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

ZADD

ZADD key score member [[score member] [score member] ...]

将一个或多个 member 元素及其 score 值加入到有序集 key 当中。

如果某个 member 已经是有序集的成员,那么更新这个 memberscore 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。

score 值可以是整数值或双精度浮点数。

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
# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,且 score 值不变

redis> ZADD page_rank 10 google.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # 没有改变
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,但是改变 score 值

redis> ZADD page_rank 6 bing.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"

ZRANK

ZRANK key member返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。

1
2
3
4
5
6
7
8
9
10
redis> ZRANGE salary 0 -1 WITHSCORES        # 显示所有成员及其 score 值
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis> ZRANK salary tom # 显示 tom 的薪水排名,第二
(integer) 1

ZRANGE

ZRANGE key start stop [WITHSCORES]返回有序集 key 中,指定区间内的成员。

其中成员的位置按 score 值递增(从小到大)来排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
redis > ZRANGE salary 0 -1 WITHSCORES             # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 1 2 WITHSCORES # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"

redis > ZRANGE salary 0 200000 WITHSCORES # 测试 end 下标超出最大下标时的情况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 200000 3000000 WITHSCORES # 测试当给定区间不存在于有序集时的情况
(empty list or set)

ZCARD

ZCARD key返回有序集 key 的基数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
redis > ZADD salary 2000 tom    # 添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 1

redis > ZADD salary 5000 jack # 再添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 2

redis > EXISTS non_exists_key # 对不存在的 key 进行 ZCARD 操作
(integer) 0

redis > ZCARD non_exists_key
(integer) 0

ZCOUNT

ZCOUNT key min max返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
redis> ZRANGE salary 0 -1 WITHSCORES    # 测试数据
1) "jack"
2) "2000"
3) "peter"
4) "3500"
5) "tom"
6) "5000"

redis> ZCOUNT salary 2000 5000 # 计算薪水在 2000-5000 之间的人数
(integer) 3

redis> ZCOUNT salary 3000 5000 # 计算薪水在 3000-5000 之间的人数
(integer) 2

ZREM

ZREM key member [member ...]移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。

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
# 测试数据
redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"

# 移除单个元素
redis> ZREM page_rank google.com
(integer) 1

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"

# 移除多个元素
redis> ZREM page_rank baidu.com bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
(empty list or set)


# 移除不存在元素
redis> ZREM page_rank non-exists-element
(integer) 0

ZREMRANGEBYRANK

ZREMRANGEBYRANK key start stop移除有序集 key 中,指定排名(rank)区间内的所有成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
redis> ZADD salary 2000 jack
(integer) 1
redis> ZADD salary 5000 tom
(integer) 1
redis> ZADD salary 3500 peter
(integer) 1

redis> ZREMRANGEBYRANK salary 0 1 # 移除下标 0 至 1 区间内的成员
(integer) 2

redis> ZRANGE salary 0 -1 WITHSCORES # 有序集只剩下一个成员
1) "tom"
2) "5000"

ZREMRANGEBYSCORE

ZREMRANGEBYSCORE key min max移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
redis> ZRANGE salary 0 -1 WITHSCORES          # 显示有序集内所有成员及其 score 值
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis> ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工
(integer) 2

redis> ZRANGE salary 0 -1 WITHSCORES # 剩下的有序集成员
1) "jack"
2) "5000"

HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

PFADD

PFADD key element [element ...]将任意数量的元素添加到指定的 HyperLogLog 里面。

  • 返回值:

    整数回复: 如果 HyperLogLog 的内部储存被修改了, 那么返回 1 , 否则返回 0 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
redis> PFADD  databases  "Redis"  "MongoDB"  "MySQL"
(integer) 1

redis> PFCOUNT databases
(integer) 3

redis> PFADD databases "Redis" # Redis 已经存在,不必对估计数量进行更新
(integer) 0

redis> PFCOUNT databases # 元素估计数量没有变化
(integer) 3

redis> PFADD databases "PostgreSQL" # 添加一个不存在的元素
(integer) 1

redis> PFCOUNT databases # 估计数量增一
4

PFCOUNT

PFCOUNT key [key ...]PFCOUNT 命令作用于单个键时, 返回储存在给定键的 HyperLogLog 的近似基数, 如果键不存在, 那么返回 0

PFCOUNT 命令作用于多个键时, 返回所有给定 HyperLogLog 的并集的近似基数, 这个近似基数是通过将所有给定 HyperLogLog 合并至一个临时 HyperLogLog 来计算得出的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
redis> PFADD  databases  "Redis"  "MongoDB"  "MySQL"
(integer) 1

redis> PFCOUNT databases
(integer) 3

redis> PFADD databases "Redis" # Redis 已经存在,不必对估计数量进行更新
(integer) 0

redis> PFCOUNT databases # 元素估计数量没有变化
(integer) 3

redis> PFADD databases "PostgreSQL" # 添加一个不存在的元素
(integer) 1

redis> PFCOUNT databases # 估计数量增一
4

PFMERGE

PFMERGE destkey sourcekey [sourcekey ...]将多个 HyperLogLog 合并(merge)为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的可见集合(observed set)的并集。

1
2
3
4
5
6
7
8
9
10
11
redis> PFADD  nosql  "Redis"  "MongoDB"  "Memcached"
(integer) 1

redis> PFADD RDBMS "MySQL" "MSSQL" "PostgreSQL"
(integer) 1

redis> PFMERGE databases nosql RDBMS
OK

redis> PFCOUNT databases
(integer) 6

GEO 地理位置

Redis >= 3.2.0 版后添加的用于保存经纬度的数据结构。

GEOADD

GEOADD key longitude latitude member [longitude latitude member ...]

将给定的空间元素(纬度、经度、名字)添加到指定的键里面。 这些数据会以有序集合的形式被储存在键里面, 从而使得像 GEORADIUSGEORADIUSBYMEMBER 这样的命令可以在之后通过位置查询取得这些元素。

GEOADD 命令以标准的 x,y 格式接受参数, 所以用户必须先输入经度, 然后再输入纬度。

1
2
3
4
5
6
7
8
9
10
11
12
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEODIST Sicily Palermo Catania
"166274.15156960039"

redis> GEORADIUS Sicily 15 37 100 km
1) "Catania"

redis> GEORADIUS Sicily 15 37 200 km
1) "Palermo"
2) "Catania"

GEOPOS

GEOPOS key member [member ...]从键里面返回所有给定位置元素的位置(经度和纬度)。

因为 GEOPOS 命令接受可变数量的位置元素作为输入, 所以即使用户只给定了一个位置元素, 命令也会返回数组回复。

1
2
3
4
5
6
7
8
9
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEOPOS Sicily Palermo Catania NonExisting
1) 1) "13.361389338970184"
2) "38.115556395496299"
2) 1) "15.087267458438873"
2) "37.50266842333162"
3) (nil)

GEODIST

GEODIST key member1 member2 [unit]返回两个给定位置之间的距离。

如果两个位置之间的其中一个不存在, 那么命令返回空值。

指定单位的参数 unit 必须是以下单位的其中一个:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。

如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEODIST Sicily Palermo Catania
"166274.15156960039"

redis> GEODIST Sicily Palermo Catania km
"166.27415156960038"

redis> GEODIST Sicily Palermo Catania mi
"103.31822459492736"

redis> GEODIST Sicily Foo Bar
(nil)

GEORADIUS

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

范围可以使用以下其中一个单位:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。

在给定以下可选项时, 命令会返回额外的信息:

  • WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
  • WITHCOORD : 将位置元素的经度和维度也一并返回。
  • WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。

命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:

  • ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。
  • DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。

在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。

  • 返回值:

    GEORADIUS 命令返回一个数组, 具体来说:在没有给定任何 WITH 选项的情况下, 命令只会返回一个像 ["New York","Milan","Paris"] 这样的线性(linear)列表。在指定了 WITHCOORDWITHDISTWITHHASH 等选项的情况下, 命令返回一个二层嵌套数组, 内层的每个子数组就表示一个元素。在返回嵌套数组时, 子数组的第一个元素总是位置元素的名字。

    至于额外的信息, 则会作为子数组的后续元素, 按照以下顺序被返回:以浮点数格式返回的中心与位置元素之间的距离, 单位与用户指定范围时的单位一致。geohash 整数。由两个元素组成的坐标,分别为经度和纬度。

    举个例子, GEORADIUS Sicily 15 37 200 km withcoord withdist 这样的命令返回的每个子数组都是类似以下格式的:["Palermo","190.4424",["13.361389338970184","38.115556395496299"]]

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
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
2) "190.4424"
2) 1) "Catania"
2) "56.4413"

redis> GEORADIUS Sicily 15 37 200 km WITHCOORD
1) 1) "Palermo"
2) 1) "13.361389338970184"
2) "38.115556395496299"
2) 1) "Catania"
2) 1) "15.087267458438873"
2) "37.50266842333162"

redis> GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD
1) 1) "Palermo"
2) "190.4424"
3) 1) "13.361389338970184"
2) "38.115556395496299"
2) 1) "Catania"
2) "56.4413"
3) 1) "15.087267458438873"
2) "37.50266842333162"

GEORADIUSBYMEMBER

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点。

1
2
3
4
5
6
7
8
9
redis> GEOADD Sicily 13.583333 37.316667 "Agrigento"
(integer) 1

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEORADIUSBYMEMBER Sicily Agrigento 100 km
1) "Agrigento"
2) "Palermo"

GEOHASH

GEOHASH key member [member ...]返回一个或多个位置元素的 Geohash 表示。

1
2
3
4
5
6
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEOHASH Sicily Palermo Catania
1) "sqc8b49rny0"
2) "sqdtr74hyu0"