目录
1.字符串类型
1.1 简介
字符串类型:简单的字符串、复杂的字符串(JSON、XML)、数字、二进制(图片、视频等),但是最大值不能超过 512M。
1.2 基本命令
设置值
SET key value [EX seconds] [PX milliseconds] [NX|XX]
SET mykey "Hello"
- EX seconds – 设置键key的过期时间,单位时秒
- PX milliseconds – 设置键key的过期时间,单位时毫秒
- NX – 只有键key不存在的时候才会设置key的值 :setnx命令(可以作为分布式锁的一种实现方案)
- XX – 只有键key存在的时候才会设置key的值:setex命令
将键key设定为指定的“字符串”值。
如果 key 已经保存了一个值,那么这个操作会直接覆盖原来的值,并且忽略原始类型。
当set命令执行成功之后,之前设置的过期时间都将失效
获取值
GET key
redis> SET mykey "Hello"
OK
redis> GET mykey
"Hello"
批量设置值和批量获取值
//批量设置
MSET key value [key value ...]
redis> MSET key1 "Hello" key2 "World"
OK
//批量获取
MGET key [key ...]
redis> SET key1 "Hello"
OK
redis> SET key2 "World"
OK
redis> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)
计数
INCR key
redis> SET mykey "10"
OK
redis> INCR mykey
(integer) 11
redis> GET mykey
"11"
对存储在指定key的数值执行原子的加1操作。
如果指定的key不存在,那么在执行incr操作之前,会先将它的值设定为0。
如果指定的key中存储的值不是字符串类型(fix:)或者存储的字符串类型不能表示为一个整数,
那么执行这个命令时服务器会返回一个错误(eq:(error) ERR value is not an integer or out of range)。
这个操作仅限于64位的有符号整型数据。
注意: 由于redis并没有一个明确的类型来表示整型数据,所以这个操作是一个字符串操作。
执行这个操作的时候,key对应存储的字符串被解析为10进制的64位有符号整型数据。
事实上,Redis 内部采用整数形式(Integer representation)来存储对应的整数值,所以对该类字符串值实际上是用整数保存,也就不存在存储整数的字符串表示(String representation)所带来的额外消耗。
除了 incr 命令,Redis提供了 decr(自减)、incrby(自增指定数字)、decrby(自减指定数字)、incrbyfloat(自增浮点数)
Redis中文官网: Redis
1.3 应用场景
缓存
将热点并且不频繁更改的数据放到Redis中。
计数
Redis的原子递增操作最常用的使用场景是计数器。
使用思路是:每次有相关操作的时候,就向Redis服务器发送一个incr命令。
例如这样一个场景:我们有一个web应用,我们想记录每个用户每天访问这个网站的次数。
web应用只需要通过拼接用户id和代表当前时间的字符串作为key,每次用户访问这个页面的时候对这个key执行一下incr命令。
这个场景可以有很多种扩展方法:
通过结合使用INCR和EXPIRE命令,可以实现一个只记录用户在指定间隔时间内的访问次数的计数器
客户端可以通过GETSET命令获取当前计数器的值并且重置为0
通过类似于DECR或者INCRBY等原子递增/递减的命令,可以根据用户的操作来增加或者减少某些值 比如在线游戏,需要对用户的游戏分数进行实时控制,分数可能增加也可能减少。
限速器
限速器是一种可以限制某些操作执行速率的特殊场景。
传统的例子就是限制某个公共api的请求数目。
假设我们要解决如下问题:限制某个api每秒每个ip的请求次数不超过10次。
我们可以通过incr命令来解决这个问题。
FUNCTION LIMIT_API_CALL(ip)
ts = CURRENT_UNIX_TIME()
keyname = ip+":"+ts
current = GET(keyname)
IF current != NULL AND current > 10 THEN
ERROR "too many requests per second"
ELSE
MULTI
INCR(keyname,1)
EXPIRE(keyname,10)
EXEC
PERFORM_API_CALL()
END
这种方法的基本点是每个ip每秒生成一个可以记录请求数的计数器。
但是这些计数器每次递增的时候都设置了10秒的过期时间,这样在进入下一秒之后,redis会自动删除前一秒的计数器。
注意上面伪代码中我们用到了MULTI和EXEC命令,将递增操作和设置过期时间的操作放在了一个事务中, 从而保证了两个操作的原子性。
2.哈希
2.1 简介
哈希就是键值对,可以理解为下图。
2.2 基本命令
设置值、获取值
HSET key field value
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HGET myhash field1
"Hello"
删除field
HDEL key field [field ...]
redis> HSET myhash field1 "foo"
(integer) 1
redis> HDEL myhash field1
(integer) 1
redis> HDEL myhash field2
(integer) 0
从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。
如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0。
计算field 个数
HLEN key
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2
返回 key 指定的哈希集包含的字段的数量。
批量设置或获取 field-value
HMGET key field [field ...]
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HMGET myhash field1 field2 nofield
1) "Hello"
2) "World"
3) (nil)
HMSET key field value [field value ...]
redis> HMSET myhash field1 "Hello" field2 "World"
OK
redis> HGET myhash field1
"Hello"
redis> HGET myhash field2
"World"
判断field是否存在
HEXISTS key field
redis> HSET myhash field1 "foo"
(integer) 1
redis> HEXISTS myhash field1
(integer) 1
redis> HEXISTS myhash field2
(integer) 0
获取所有的 field 或 所有的 value 或 所有的 field-value
HKEYS key
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HKEYS myhash
1) "field1"
2) "field2"
HVALS key
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HVALS myhash
1) "Hello"
2) "World"
HGETALL key
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
3.列表
3.1 简介
列表是用来存储多个有序的字符串的,比如 a、b、c、d、e 五个元素从左到右有序的列表,可以对两端插入或者弹出元素,可以通过下标索引获取列表中的元素,可以用列表来充当 栈 或 队列 来用。一个列表中最多可以存储2^32 - 1个元素。
两个特点:
- 列表中的元素有序
- 列表中的元素可以重复
3.2 基本命令
添加操作
RPUSH key value [value ...]
redis> RPUSH mylist "hello"
(integer) 1
redis> RPUSH mylist "world"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"
LPUSH key value [value ...]
redis> LPUSH mylist "world"
(integer) 1
redis> LPUSH mylist "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "world"
//把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
//当 key 不存在时,这个list会被看作是空list,任何操作都不会发生。
//当 key 存在,但保存的不是一个list的时候,会返回error。
LINSERT key BEFORE|AFTER pivot value
redis> RPUSH mylist "Hello"
(integer) 1
redis> RPUSH mylist "World"
(integer) 2
redis> LINSERT mylist BEFORE "World" "There"
(integer) 3
redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"
查找
//查找指定范围内的元素列表
LRANGE key start stop
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LRANGE mylist 0 0
1) "one"
redis> LRANGE mylist -3 2
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist -100 100
1) "one"
2) "two"
3) "three"
redis> LRANGE mylist 5 10
(empty list or set)
//获取列表指定索引下标的元素
LINDEX key index
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
(nil)
//获取列表的长度:列表不存在返回为 :0
LLEN key
redis> LPUSH mylist "World"
(integer) 1
redis> LPUSH mylist "Hello"
(integer) 2
redis> LLEN mylist
(integer) 2
删除
//移除并且返回 key 对应的 list 的第一个元素。
LPOP key
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LPOP mylist
"one"
redis> LRANGE mylist 0 -1
1) "two"
2) "three"
//移除并返回存于 key 的 list 的最后一个元素。
RPOP key
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> RPOP mylist
"three"
redis> LRANGE mylist 0 -1
1) "one"
2) "two"
//删除指定元素
//count > 0: 从头往尾移除值为 value 的元素。
//count < 0: 从尾往头移除值为 value 的元素。
//count = 0: 移除所有值为 value 的元素。
LREM key count value
redis> RPUSH mylist "hello"
(integer) 1
redis> RPUSH mylist "hello"
(integer) 2
redis> RPUSH mylist "foo"
(integer) 3
redis> RPUSH mylist "hello"
(integer) 4
redis> LREM mylist -2 "hello"
(integer) 2
redis> LRANGE mylist 0 -1
1) "hello"
2) "foo"
//按照索引范围修剪列表
LTRIM key start stop
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LTRIM mylist 1 -1
OK
redis> LRANGE mylist 0 -1
1) "two"
2) "three"
修改
//设置 index 位置的list元素的值为 value
//当index超出范围时会返回一个error
LSET key index value
redis> RPUSH mylist "one"
(integer) 1
redis> RPUSH mylist "two"
(integer) 2
redis> RPUSH mylist "three"
(integer) 3
redis> LSET mylist 0 "four"
OK
redis> LSET mylist -2 "five"
OK
redis> LRANGE mylist 0 -1
1) "four"
2) "five"
3) "three"
4.集合
4.1 简介
集合(set)用于保存多个字符串,集合中不允许出现重复的元素,集合中的元素是无序的,不能通过索引来获取对应的元素。集合中最多可以存储 2^32 - 1 个元素
Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集
4.2 基本命令
集合内添加元素
SADD key member [member ...]
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "World"
2) "Hello"
集合内删除元素
SREM key member [member ...]
//在key集合中移除指定的元素. 如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0.
//如果key的类型不是一个集合,则返回错误.
//栗子
redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SREM myset "one"
(integer) 1
redis> SREM myset "four"
(integer) 0
redis> SMEMBERS myset
1) "three"
2) "two"
计算元素个数
SCARD key
//返回集合存储的key的基数 (集合元素的数量).
//集合的基数(元素的数量),如果key不存在,则返回 0.
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SCARD myset
(integer) 2
判断元素是否在集合中
SISMEMBER key member
//返回成员 member 是否是存储的集合 key的成员.
//如果member元素是集合key的成员,则返回1
//如果member元素不是key的成员,或者集合key不存在,则返回0
redis> SADD myset "one"
(integer) 1
redis> SISMEMBER myset "one"
(integer) 1
redis> SISMEMBER myset "two"
(integer) 0
随机从集合返回指定个数元素
SRANDMEMBER key [count]
//仅提供key参数,那么随机返回key集合中的一个元素.
//不使用count 参数的情况下该命令返回随机的元素,如果key不存在则返回nil。
//使用count参数,则返回一个随机的元素数组,如果key不存在则返回一个空的数组。
redis> SADD myset one two three
(integer) 3
redis> SRANDMEMBER myset
"one"
redis> SRANDMEMBER myset 2
1) "three"
2) "one"
redis> SRANDMEMBER myset -5
1) "one"
2) "one"
3) "one"
4) "one"
5) "one"
从集合随机弹出元素(会将元素删除)
//从存储在key的集合中移除并返回一个或多个随机元素
//被删除的元素,或者当key不存在时返回nil
SPOP key [count]
SADD myset "one"
SADD myset "two"
SADD myset "three"
SPOP myset
SMEMBERS myset
SADD myset "four"
SADD myset "five"
SPOP myset 3
SMEMBERS myset
获取所有元素
//返回key集合所有的元素.
SMEMBERS key
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SMEMBERS myset
1) "World"
2) "Hello"
求多个集合的交集
SINTER key [key ...]
//返回指定所有的集合的成员的交集.
//如果key不存在则被认为是一个空的集合,当给定的集合为空的时候,结果也为空.(一个集合为空,结果一直为空).
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTER key1 key2
1) "c"
求多个集合饿并集
SUNION key [key ...]
//返回给定的多个集合的并集中的所有成员.
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
求多个集合的差集
SDIFF key [key ...]
//返回一个集合与给定集合的差集的元素.
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFF key1 key2
1) "a"
2) "b"
将交集、并集、差集的结果进行保存
SINTERSTORE destination key [key ...] //交集保存
SDIFFSTORE destination key [key ...] //差集保存
SUNIONSTORE destination key [key ...] //并集保存
//以并集保存为例
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNIONSTORE key key1 key2
(integer) 5
redis> SMEMBERS key
1) "c"
2) "e"
3) "b"
4) "a"
5) "d"
5.有序集合
5.1 简介
有序集合也是集合,它有着集合不能存在重复成员的特性,但不同于集合的是,有序集合中的元素可以进行排序,但他与列表使用下标作为排序的依据不同的是,它给每一个元素设置一个分数(score)作为排序的依据。有序集合中的元素不能重复,但是score可以重复。
5.2 基本命令
添加元素
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 1 "uno"
(integer) 1
redis> ZADD myzset 2 "two" 3 "three"
(integer) 2
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "uno"
4) "1"
5) "two"
6) "2"
7) "three"
8) "3"
计算成员个事
ZCARD key
//返回key的有序集元素个数。
//key存在的时候,返回有序集的元素个数,否则返回0。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZCARD myzset
(integer) 2
计算某个成员的分数
ZSCORE key member
//返回有序集key中,成员member的score值。
//如果member元素不是有序集key的成员,或key不存在,返回nil。
//member成员的score值(double型浮点数),以字符串形式表示。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZSCORE myzset "one"
"1"
计算成员的排名
返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。排名以0为底,也就是说,score值最小的成员排名为0。
ZRANK key member
//如果member是有序集key的成员,返回integer-reply:member的排名。
//如果member不是有序集key的成员,返回bulk-string-reply: nil。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANK myzset "three"
(integer) 2
redis> ZRANK myzset "four"
(nil)
ZREVRANK key member
//返回有序集key中成员member的排名,其中有序集成员按score值从大到小排列。排名以0为底,也就是说,score值最大的成员排名为0。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANK myzset "one"
(integer) 2
redis> ZREVRANK myzset "four"
(nil)
删除成员
ZREM key member [member ...]
//当key存在,但是其不是有序集合类型,就返回一个错误。
//返回的是从有序集合中删除的成员个数,不包括不存在的成员。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREM myzset "two"
(integer) 1
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "three"
4) "3"
增加成员的分数
ZINCRBY key increment member
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZINCRBY myzset 2 "one"
"3"
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "two"
2) "2"
3) "one"
4) "3"
为有序集key的成员member的score值加上增量increment。如果key中不存在member,就在key中添加一个member,score是increment(就好像它之前的score是0.0)。如果key不存在,就创建一个只含有指定member成员的有序集合。
当key不是有序集类型时,返回一个错误。
score值必须是字符串表示的整数值或双精度浮点数,并且能接受double精度的浮点数。也有可能给一个负数来减少score的值。
返回值:member成员的新score值,以字符串形式表示。
指定范围内的操作
ZRANGE key start stop [WITHSCORES]
//返回存储在有序集合key中的指定范围的元素。 返回的元素可以认为是按得分从最低到最高排列。 如果得分相同,将按字典排序。
ZADD myzset 1 "one"
ZADD myzset 2 "two"
ZADD myzset 3 "three"
ZRANGE myzset 0 -1
ZRANGE myzset 2 3
ZRANGE myzset -2 -1
ZREVRANGE key start stop [WITHSCORES]
//返回有序集key中,指定区间内的成员。其中成员的位置按score值递减(从大到小)来排列。
//具有相同score值的成员按字典序的反序排列。
//除了成员按score值递减的次序排列这一点外,ZREVRANGE命令的其他方面和ZRANGE命令一样。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANGE myzset 0 -1
1) "three"
2) "two"
3) "one"
redis> ZREVRANGE myzset 2 3
1) "one"
redis> ZREVRANGE myzset -2 -1
1) "two"
2) "one"
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
//如果M是常量(比如,用limit总是请求前10个元素),你可以认为是O(log(N))。
//返回key的有序集合中的分数在min和max之间的所有元素(包括分数等于max或者min的元素)。元素被认为是从低分到高分排序的。
//具有相同分数的元素按字典序排列(这个根据redis对有序集合实现的情况而定,并不需要进一步计算)。
edis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANGEBYSCORE myzset -inf +inf
1) "one"
2) "two"
3) "three"
redis> ZRANGEBYSCORE myzset 1 2
1) "one"
2) "two"
redis> ZRANGEBYSCORE myzset (1 2
1) "two"
redis> ZRANGEBYSCORE myzset (1 (2
(empty list or set)
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
//ZREVRANGEBYSCORE 返回有序集合中指定分数区间内的成员,分数由高到低排序。
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANGEBYSCORE myzset +inf -inf
1) "three"
2) "two"
3) "one"
redis> ZREVRANGEBYSCORE myzset 2 1
1) "two"
2) "one"
redis> ZREVRANGEBYSCORE myzset 2 (1
1) "two"
redis> ZREVRANGEBYSCORE myzset (2 (1
(empty list or set)
返回指定分数范围内成员个数
ZCOUNT key min max
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZCOUNT myzset -inf +inf
(integer) 3
redis> ZCOUNT myzset (1 3
(integer) 2
交集
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [SUM|MIN|MAX]
计算给定的numkeys个有序集合的交集,并且把结果放到destination中。
在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。
默认情况下,结果中一个元素的分数是有序集合中该元素分数之和,前提是该元素在这些有序集合中都存在。
因为交集要求其成员必须是给定的每个有序集合中的成员,结果集中的每个元素的分数和输入的有序集合个数相等。
redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3
(integer) 2
redis> ZRANGE out 0 -1 WITHSCORES
1) "one"
2) "5"
3) "two"
4) "10"
并集
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [SUM|MIN|MAX]
计算给定的numkeys个有序集合的并集,并且把结果放到destination中。
在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。
默认情况下,结果集中某个成员的score值是所有给定集下该成员score值之和。
redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZUNIONSTORE out 2 zset1 zset2 WEIGHTS 2 3
(integer) 3
redis> ZRANGE out 0 -1 WITHSCORES
1) "one"
2) "5"
3) "three"
4) "9"
5) "two"
6) "10"