《“Java技术员”成长手册》,包含框架、存储、搜索、优化、分布式等必备知识,都收集在GitHub JavaEgg ,N线互联网开发必备技能兵器谱,欢迎指导
Redis简介
Redis:REmote DIctionary Server(远程字典服务器)。
Redis 是一个全开源免费(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。一般作为一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器
Redis 介绍
redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步,所以Redis也可以被看成是一个数据结构服务器。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的官网地址,非常好记,是redis.io。(域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)目前,Vmware在资助着redis项目的开发和维护
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。这就是redis提供的两种持久化的方式,RDB(Redis DataBase)和AOF(Append Only File)。
Redis 特点
Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案。
Redis从它的许多竞争继承来的三个主要特点:
Redis数据库完全在内存中,使用磁盘仅用于持久性。
相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
-
Redis可以将数据复制到任意数量的从服务器。
Redis 优势
- 异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。SET操作每秒钟 110000 次,GET操作每秒钟 81000 次,网站一般使用Redis作为缓存服务器。
- 支持丰富的数据类型:Redis支持大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
- 操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
- MultiUtility工具:Redis是一个多功能实用工具,可以在很多如:缓存,消息传递队列中使用(Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据;
redis使用场景
- 取最新N个数据的操作
- 排行榜应用,取TOP N 操作
- 需要精确设定过期时间的应用
- 定时器、计数器应用
- Uniq操作,获取某段时间所有数据排重值
- 实时系统,反垃圾系统
- Pub/Sub构建实时消息系统
- 构建队列系统
- 缓存
安装
$ wget http://download.redis.io/releases/redis-5.0.6.tar.gz
$ tar xzf redis-5.0.6.tar.gz
$ cd redis-5.0.6
$ make
新版本的编译文件在src中(之前在bin目录),启动server
$ src/redis-server
启动客户端
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
Redis数据类型操作手册
String(字符串)
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,如图中所示,内部为当前字符串实际分配的空间 capacity 一般要高于实际字符串长度 len。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩容时一次只会多扩 1M 的空间。需要注意的是字符串最大长度为 512M。
Hash(字典)
Redis hash 是一个键值对集合。KV模式不变,但V是一个键值对。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 的字典相当于 Java 语言里面的 HashMap,它是无序字典, 内部实现结构上同 Java 的 HashMap 也是一致的,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。
它的底层实际是个链表,
Redis 的列表相当于 Java 语言里面的 LinkedList,注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)
Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理
右边进左边出:队列
> rpush books python java golang
(integer) 3
\> llen books
(integer) 3
\> lpop books
"python"
\> lpop books
"java"
\> lpop books
"golang"
\> lpop books
(nil)
右边进右边出:栈
> rpush books python java golang
(integer) 3
\> rpop books
"golang"
\> rpop books
"java"
\> rpop books
"python"
\> rpop books
(nil)
Set(集合)
Redis的Set是string类型的无序集合。它是通过HashTable实现的, 相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值NULL
。
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。
redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
它类似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。它的内部实现用的是一种叫做「跳跃列表」的数据结构。
redis常见数据类型查阅:
Key(键)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
DEL | DEL key [key ...] | 删除给定的一个或多个 key。 不存在的 key 会被忽略 | |
DUMP | DUMP key | 序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键 | |
EXISTS | EXISTS key | 检查给定 key 是否存在 | |
EXPIRE | EXPIRE key seconds | 为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除 | |
PERSIST | PERSIST key | 移除 key 的过期时间,key 将持久保持。 | |
EXPIREAT | EXPIREAT key timestamp | EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置生存时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp) | EXPIREAT cache 1355292000 # 这个 key 将在 2012.12.12 过期 |
KEYS | KEYS pattern | 查找所有符合给定模式 pattern 的 key | KEYS * # 匹配数据库内所有 key |
MOVE | MOVE key db | 将当前数据库的 key 移动到给定的数据库 db 当中如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。 因此,也可以利用这一特性,将 MOVE 当作锁(locking)原语(primitive) | MOVE song 1 # 将 song 移动到数据库 1 |
TTL | TTL key | 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)当 key 不存在时,返回 -2 。当 key 存在但没有设置剩余生存时间时,返回 -1 。否则,以秒为单位,返回 key 的剩余生存时间 | |
PTTL | PTTL key | 以毫秒为单位返回 key 的剩余的过期时间。 | |
TYPE | TYPE key | 返回 key 所储存的值的类型 | |
RENAME | RENAME key newkey | 将 key 改名为 newkey 。当 key 和 newkey 相同,或者 key 不存在时,返回一个错误。当 newkey 已经存在时, RENAME 命令将覆盖旧值 |
String (字符串)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
SET | SET key value [EX seconds] [PX milliseconds] [NX|XX] | 将字符串值 value 关联到 key 。如果 key 已经持有其他值, SET 就覆写旧值,无视类型 | SET key "value" |
MSET | MSET key value [key value ...] | 同时设置一个或多个 key-value 对。如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作 | MSET date "2012.3.30" time "11:00 a.m." weather "sunny" |
SETNX | SETNX key value | 将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作 SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写 | |
MSETNX | MSETNX key value [key value ...] | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。即使只有一个给定 key 已存在, MSETNX 也会拒绝执行所有给定 key 的设置操作 | |
SETRANGE | SETRANGE key offset value | 用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。不存在的 key 当作空白字符串处理 | |
SETBIT | SETBIT key offset value | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit) | GETBIT bit 100 # bit 默认被初始化为 0 |
SETEX | SETEX key seconds value | 将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。如果 key 已经存在, SETEX 命令将覆写旧值。 | |
PSETEX | PSETEX key milliseconds value | 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位 | |
STRLEN | STRLEN key | 返回 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误 | |
GET | GET key | 返回 key 所关联的字符串值。如果 key 不存在那么返回特殊值 nil | |
MGET | MGET key [key ...] | 返回所有(一个或多个)给定 key 的值。如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败 | |
GETRANGE | GETRANGE key start end | 返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。 | GETRANGE greeting 0 4 |
GETSET | GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。当 key 存在但不是字符串类型时,返回一个错误。 | |
GETBIT | GETBIT key offset | 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。当 offset 比字符串值的长度大,或者 key 不存在时,返回 0 | |
APPEND | APPEND key value | 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样 | |
DECR | DECR key | 将 key 中储存的数字值减一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作 | redis> SET failure_times 10OK redis> DECR failure_times(integer) 9 |
DECRBY | DECRBY key decrement | 将 key 所储存的值减去减量 decrement | |
INCR | INCR key | 将 key 中储存的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作 | |
INCRBY | INCRBY key increment | 将 key 所储存的值加上增量 increment | |
INCRBYFLOAT | INCRBYFLOAT key increment | 为 key 中所储存的值加上浮点数增量 increment | INCRBYFLOAT mykey 0.1 |
BITCOUNT | BITCOUNT key [start] [end] | 计算给定字符串中,被设置为 1 的比特位的数量 | |
BITOP | BITOP operation destkey key [key ...] | 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。 |
☆☆位图:
String命令中包含了一种特殊的操作,直接操作bit,某些特殊场景下,会节省存储空间。可以在存取bool型数据的场景使用,比如存取用户男女比例,用户某一段日期签到记录,
在我们平时开发过程中,会有一些 bool 型数据需要存取,比如用户一年的签到记录,签了是 1,没签是 0,要记录 365 天。如果使用普通的 key/value,每个用户要记录 365 个,当用户上亿的时候,需要的存储空间是惊人的。
为了解决这个问题,Redis 提供了位图数据结构,这样每天的签到记录只占据一个位,365 天就是 365 个位,46 个字节 (一个稍长一点的字符串) 就可以完全容纳下,这就大大节约了存储空间。
位图不是特殊的数据结构,它的内容其实就是普通的字符串,也就是 byte 数组。我们可以使用普通的 get/set 直接获取和设置整个位图的内容,也可以使用位图操作 getbit/setbit 等将 byte 数组看成「位数组」来处理
Redis 的位数组是自动扩展,如果设置了某个偏移位置超出了现有的内容范围,就会自动将位数组进行零扩充。
接下来我们使用 redis-cli 设置第一个字符,也就是位数组的前 8 位,我们只需要设置值为 1 的位,如上图所示,h 字符只有 1/2/4 位需要设置,e 字符只有 9/10/13/15 位需要设置。值得注意的是位数组的顺序和字符的位顺序是相反的。
127.0.0.1:6379> setbit s 1 1
(integer) 0
127.0.0.1:6379> setbit s 2 1
(integer) 0
127.0.0.1:6379> setbit s 4 1
(integer) 0
127.0.0.1:6379> setbit s 9 1
(integer) 0
127.0.0.1:6379> setbit s 10 1
(integer) 0
127.0.0.1:6379> setbit s 13 1
(integer) 0
127.0.0.1:6379> setbit s 15 1
(integer) 0
127.0.0.1:6379> get s
"he"
上面这个例子可以理解为「零存整取」,同样我们还也可以「零存零取」,「整存零取」。「零存」就是使用 setbit 对位值进行逐个设置,「整存」就是使用字符串一次性填充所有位数组,覆盖掉旧值。
bitcount和bitop, bitpos,bitfield 都是操作位图的指令。
List(列表)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
LPUSH | LPUSH key value [value ...] | 将一个或多个值 value 插入到列表 key 的表头如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头 | 正着进反着出 |
LPUSHX | LPUSHX key value | 将值 value 插入到列表 key 的表头,当且仅当 key 存在并且是一个列表。和 LPUSH 命令相反,当 key 不存在时, LPUSHX 命令什么也不做 | |
RPUSH | RPUSH key value [value ...] | 将一个或多个值 value 插入到列表 key 的表尾(最右边) | 怎么进怎么出 |
RPUSHX | RPUSHX key value | 将值 value 插入到列表 key 的表尾,当且仅当 key 存在并且是一个列表。和 RPUSH 命令相反,当 key 不存在时, RPUSHX 命令什么也不做。 | |
LPOP | LPOP key | 移除并返回列表 key 的头元素。 | |
BLPOP | BLPOP key [key ...] timeout | 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止 | |
RPOP | RPOP key | 移除并返回列表 key 的尾元素。 | |
BRPOP | BRPOP key [key ...] timeout | 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 | |
BRPOPLPUSH | BRPOPLPUSH source destination timeout | 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 | |
RPOPLPUSH | RPOPLPUSH source destinationb | 命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素 | RPOPLPUSH list01 list02 |
LSET | LSET key index value | 将列表 key 下标为 index 的元素的值设置为 value | |
LLEN | LLEN key | 返回列表 key 的长度。如果 key 不存在,则 key 被解释为一个空列表,返回 0 .如果 key 不是列表类型,返回一个错误 | |
LINDEX | LINDEX key index | 返回列表 key 中,下标为 index 的元素。下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。相当于 Java 链表的get(int index) 方法,它需要对链表进行遍历,性能随着参数index 增大而变差。 |
|
LRANGE | LRANGE key start stop | 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定 | |
LREM | LREM key count value | 根据参数 count 的值,移除列表中与参数 value 相等的元素 | |
LTRIM | LTRIM key start stop | 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除 | |
LINSERT | LINSERT key BEFORE|AFTER pivot value | 将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。当 pivot 不存在于列表 key 时,不执行任何操作。当 key 不存在时, key 被视为空列表,不执行任何操作。如果 key 不是列表类型,返回一个错误。 | LINSERT list01 before c++ c#(在c++之前加上C#) |
Hash(哈希表)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
HSET | HSET key field value | 将哈希表 key 中的域 field 的值设为 value 。如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果域 field 已经存在于哈希表中,旧值将被覆盖。 | |
HMSET | HMSET key field value [field value ...] | 同时将多个 field-value (域-值)对设置到哈希表 key 中。此命令会覆盖哈希表中已存在的域。 | |
HSETNX | HSETNX key field value | 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。若域 field 已经存在,该操作无效 | |
HGET | HGET key field | 返回哈希表 key 中给定域 field 的值 | |
HMGET | HMGET key field [field ...] | 返回哈希表 key 中,一个或多个给定域的值。 | |
HGETALL | HGETALL key | 返回哈希表 key 中,所有的域和值。在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍 | |
HDEL | HDEL key field [field ...] | 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略 | |
HEXISTS | HEXISTS key field | 查看哈希表 key 中,给定域 field 是否存在 | |
HLEN | HLEN key | 返回哈希表 key 中域的数量 | |
HKEYS | HKEYS key | 返回哈希表 key 中的所有域 | |
HVALS | HVALS key | 返回哈希表 key 中所有域的值 | |
HSTRLEN | HSTRLEN key field | 返回哈希表 key 中,与给定域 field 相关联的值的字符串长度(string length)。如果给定的键或者域不存在,那么命令返回 0 | |
HINCRBY | HINCRBY key field increment | 为哈希表 key 中的域 field 的值加上增量 increment | |
HINCRBYFLOAT | HINCRBYFLOAT key field increment | 为哈希表 key 中的域 field 加上浮点数增量 increment | |
HSCAN | HSCAN key cursor [MATCH pattern] [COUNT count] | 迭代哈希表中的键值对。 |
Set(集合)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
SADD | SADD key member [member ...] | 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。假如 key 不存在,则创建一个只包含 member 元素作成员的集合。当 key 不是集合类型时,返回一个错误 | |
SCARD | SCARD key | 返回集合 key 的基数(集合中元素的数量)。 | |
SDIFF | SDIFF key [key ...] | 返回一个集合的全部成员,该集合是所有给定集合之间的差集。不存在的 key 被视为空集。 | 差集 |
SDIFFSTORE | SDIFFSTORE destination key [key ...] | 这个命令的作用和 SDIFF 类似,但它将结果保存到 destination 集合,而不是简单地返回结果集。如果 destination 集合已经存在,则将其覆盖。destination 可以是 key 本身。 | |
SINTER | SINTER key [key ...] | 返回一个集合的全部成员,该集合是所有给定集合的交集。不存在的 key 被视为空集。当给定集合当中有一个空集时,结果也为空集(根据集合运算定律) | 交集 |
SINTERSTORE | SINTERSTORE destination key [key ...] | 这个命令类似于 SINTER 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。如果 destination 集合已经存在,则将其覆盖。destination 可以是 key 本身 | |
SUNION | SUNION key [key ...] | 返回一个集合的全部成员,该集合是所有给定集合的并集。不存在的 key 被视为空集 | 并集 |
SUNIONSTORE | SUNIONSTORE destination key [key ...] | 这个命令类似于 SUNION 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。如果 destination 已经存在,则将其覆盖。destination 可以是 key 本身 | |
SMEMBERS | SMEMBERS key | 返回集合 key 中的所有成员。不存在的 key 被视为空集合 | |
SRANDMEMBER | SRANDMEMBER key [count] | 如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素 | |
SISMEMBER | SISMEMBER key member | 判断 member 元素是否集合 key 的成员 | |
SMOVE | SMOVE source destination member | 将 member 元素从 source 集合移动到 destination 集合。 | |
SPOP | SPOP key | 移除并返回集合中的一个随机元素。如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。 | |
SREM | SREM key member [member ...] | 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。当 key 不是集合类型,返回一个错误 | |
SSCAN | SSCAN key cursor [MATCH pattern] [COUNT count] | 迭代集合中的元素 |
SortedSet(有序集合)常用命令
命令 | 用法 | 描述 | 示例 |
---|---|---|---|
ZADD | ZADD key score1 member1 [score2 member2] | 向有序集合添加一个或多个成员,或者更新已存在成员的分数 | |
ZCARD | ZCARD key | 返回有序集 key 的基数。 | |
ZCOUNT | ZCOUNT key min max | 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。关于参数 min 和 max 的详细使用方法,请参考 ZRANGEBYSCORE 命令。 | |
ZRANGE | ZRANGE key start stop [WITHSCORES] | 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递增(从小到大)来排序 | |
ZREVRANGE | ZREVRANGE key start stop [WITHSCORES] | 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递减(从大到小)来排列。具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。除了成员按 score 值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。 | |
ZREVRANGEBYSCORE | ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] | 返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。 | |
ZREVRANK | ZREVRANK key member | 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。排名以 0 为底,也就是说, score 值最大的成员排名为 0 。使用 ZRANK 命令可以获得成员按 score 值递增(从小到大)排列的排名。 | |
ZSCORE | ZSCORE key member | 返回有序集 key 中,成员 member 的 score 值。如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。 | |
ZRANGEBYSCORE | ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] | 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 | |
ZRANK | ZRANK key member | 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。 | |
ZINCRBY | ZINCRBY key increment member | 为有序集 key 的成员 member 的 score 值加上增量 increment | |
ZREM | ZREM key member [member ...] | 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。当 key 存在但不是有序集类型时,返回一个错误。 | |
ZREMRANGEBYRANK | ZREMRANGEBYRANK key start stop | 移除有序集 key 中,指定排名(rank)区间内的所有成员 | |
ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key min max | 移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。 | |
ZUNIONSTORE | ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] | 计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。 | |
ZINTERSTORE | ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] | 计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之和. | |
ZSCAN | ZSCAN key cursor [MATCH pattern] [COUNT count] | 迭代有序集合中的元素(包括元素成员和元素分值) | |
ZRANGEBYLEX | ZRANGEBYLEX key min max [LIMIT offset count] | 当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的字典序(lexicographical ordering)来进行排序,而这个命令则可以返回给定的有序集合键 key 中,值介于 min 和 max 之间的成员。 | |
ZLEXCOUNT | ZLEXCOUNT key min max | 对于一个所有成员的分值都相同的有序集合键 key 来说,这个命令会返回该集合中,成员介于 min 和 max 范围内的元素数量。这个命令的 min 参数和 max 参数的意义和 ZRANGEBYLEX 命令的 min 参数和 max 参数的意义一样 | |
ZREMRANGEBYLEX | ZREMRANGEBYLEX key min max | 对于一个所有成员的分值都相同的有序集合键 key 来说,这个命令会移除该集合中,成员介于 min 和 max 范围内的所有元素。这个命令的 min 参数和 max 参数的意义和 ZRANGEBYLEX 命令的 min 参数和 max 参数的意义一样 |
HyperLogLog
Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
场景:可以用来统计站点的UV...
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。但是会有误差。
命令 | 用法 | 描述 |
---|---|---|
pfadd | [PFADD key element [element ...] | 添加指定元素到 HyperLogLog 中 |
pfcount | [PFCOUNT key [key ...] | 返回给定 HyperLogLog 的基数估算值。 |
pfmerge | [PFMERGE destkey sourcekey [sourcekey ...] | 将多个 HyperLogLog 合并为一个 HyperLogLog |
public class JedisTest {
public static void main(String[] args) {
Jedis jedis = new Jedis();
for (int i = 0; i < 100000; i++) {
jedis.pfadd("codehole", "user" + i);
}
long total = jedis.pfcount("codehole");
System.out.printf("%d %d\n", 100000, total);
jedis.close();
}
}