Redis实战.pdf
http://www.100md.com
2020年11月16日
![]() |
| 第1页 |
![]() |
| 第6页 |
![]() |
| 第12页 |
![]() |
| 第25页 |
![]() |
| 第37页 |
![]() |
| 第65页 |
参见附件(1319KB,71页)。
Redis实战深入浅出地介绍了Redis的5种数据类型,并通过多个实用示例展示了Redis的用法。除此之外,书中还讲述了Redis的优化方法以及扩展方法,是一本对于学习和使用 Redis 来说不可多得的参考书籍

编辑推荐
当你需要以接近实时的速度访问快速变动的数据流时,Redis这样的键值数据库就是你的极好选择。通过接纳散列、字符串、列表等多种数据类型,Redis对键值对模式进行了扩展,它既提供了极其快速的内存数据集操作,又可以在运行时轻松地将这些数据持久化到磁盘上面。除此之外,Redis还是的、开源的。
本书对Redis本身以及它的键值对模型进行了介绍,读者将接触到包括缓存、分布式广告定向等实际使用案例,学到如何从小型的作业任务开始,扩展Redis以适应大规模的数据集,以及如何与其他传统的关系数据库或是其他NoSQL存储系统进行集成。有经验的开发者应该会对集群和服务器脚本编程等较为深入的内容感兴趣。
本书主要内容
全面介绍Redis
预处理实时数据
管理内存数据集
发布/订阅及配置
持久化到磁盘
本书面向熟悉数据库概念的开发者。阅读本书既不要求读者预先了解NoSQL数据库概念,也不要求读者有任何Redis使用经验。本书也适合具备编程能力的系统管理员阅读。
要本书代码可以访问manning.com/RedisinAction。
内容简介
本书深入浅出地介绍了Redis的5种数据类型,并通过多个实用示例展示了Redis的用法。除此之外,书中还讲述了Redis的优化方法以及扩展方法,是一本对于学习和使用 Redis 来说不可多得的参考书籍。
本书一共由三个部分组成。首部分对Redis进行了介绍,说明了Redis的基本使用方法、它拥有的5种数据结构以及操作这5种数据结构的命令,并讲解了如何使用Redis去构建文章展示网站、cookie、购物车、网页缓存、数据库行缓存等一系列程序。第二部分对Redis命令进行了更详细的介绍,并展示了如何使用Redis去构建更为复杂的辅助工具和应用程序,并在结尾展示了如何使用Redis去构建一个简单的社交网站。第三部分对Redis用户经常会遇到的一些问题进行了介绍,讲解了降低Redis内存占用的方法、扩展Redis性能的方法以及使用Lua语言进行脚本编程的方法。
作者简介
作者介绍
Josiah L. Carlson博士,既是一位经验丰富的数据库专家,也是一位活跃的Redis社区贡献者。
译者简介
黄健宏(huangz),男,1990年出生,目前是程序员、技术图书作者和译者。著有《Redis设计与实现》,翻译了《Redis命令参考》《Disque使用教程》等技术文档。想要了解更多关于黄健宏的信息,请访问他的个人网站huangz.me。
精彩书评
“这本书对于Redis的生态系统非常有帮助。”
——摘自“Redis之父”Salvatore Sanfilippo为本书写的序
“书中介绍的示例都来源于真实的使用案例,这是本书的一个主要优点。”
——Filippo Pacini,SG咨询公司
“本书通过真实而全面的示例,帮助读者从新手成长为专家。”
——Felipe Gutierrez,VMware/Spring Source公司
“这本书提供了深入分析以及富有洞察力的真实案例。”
——Bobby Abraham,Integri有限责任公司
“此书自有黄金屋,此书自有颜如玉!”
——Leo Cassarani,Unboxed咨询公司
精彩书摘
《Redis实战》:
要构建一个文章投票网站,我们首先要做的就是为了这个网站设置一些数值和限制条件:如果一篇文章获得了至少200张支持票(up vote),那么网站就认为这篇文章是一篇有趣的文章;假如这个网站每天发布1000篇文章,而其中的50篇符合网站对有趣文章的要求,那么网站要做的就是把这50篇文章放到文章列表前100位至少一天;另外,这个网站暂时不提供投反对票(down.vote)的功能。
为了产生一个能够随着时间流逝而不断减少的评分,程序需要根据文章的发布时间和当前时间来计算文章的评分,具体的计算方法为:将文章得到的支持票数量乘以一个常数,然后加上文章的发布时间,得出的结果就是文章的评分。
我们使用从UTC时区1970年1月1日到现在为止经过的秒数来计算文章的评分,这个值通常被称为Unix时间。之所以选择使用Unix时间,是因为在所有能够运行Redis的平台上面,使用编程语言获取这个值都是一件非常简单的事情。另外,计算评分时与支持票数量相乘的常量为432,这个常量是通过将一天的秒数(86400)除以文章展示一天所需的支持票数量(200)得出的:文章每获得一张支持票,程序就需要将文章的评分增加432分。
Redis实战截图




Redis 实战
《红丸出品》 http:weibo.comu2446082491
2 71
第一章 Redis快速入门 7
1.1 Key-Value 存储系统简介 ................................................................................................ 7
1.1.1 Voldemort ................................................................................................................. 8
1.1.2 Dynamo .................................................................................................................... 8
1.1.3 memcachedb ............................................................................................................ 9
1.1.4 Cassandra ................................................................................................................. 9
1.1.5 memcached ............................................................................................................ 10
1.1.6 Hypertable .............................................................................................................. 10
1.2 为什么选择 Key-Value Store ....................................................................................... 11
1.2.1 大规模的互联网应用 ........................................................................................... 11
1.2.2 云存储 ................................................................................................................... 11
1.2.3 Redis实际应用案例 .............................................................................................. 12
1.3 初识Redis .................................................................................................................... 14
1.3.1 数据类型 ............................................................................................................... 14
1.3.2 持久化 ................................................................................................................... 14
1.3.3 主从同步 ............................................................................................................... 14
1.3.4 性能 ....................................................................................................................... 15
1.3.5 提供API 的语言 .................................................................................................... 15
1.3.6 适用场合 ............................................................................................................... 15
1.4 快速入门 ...................................................................................................................... 17
1.4.1 安装Redis ............................................................................................................. 17
1.4.2 配置Redis ............................................................................................................. 18
1.4.3 操作数据库 ........................................................................................................... 21
第二章 Redis数据类型及操作 ............................................................................................. 22
2.1 前言 .............................................................................................................................. 22
2.2 strings 类型及操作 .................................................................................................. 23
2.2.1 set ........................................................................................................................... 23
2.2.2 setnx ....................................................................................................................... 23
2.2.3 setex ....................................................................................................................... 24
2.2.4 setrange .................................................................................................................. 24 《红丸出品》 http:weibo.comu2446082491
3 71
2.2.5 mset ........................................................................................................................ 24
2.2.6 msetnx .................................................................................................................... 25
2.2.7 get ........................................................................................................................... 25
2.2.8 getset ...................................................................................................................... 25
2.2.9 getrange.................................................................................................................. 26
2.2.10 mget ...................................................................................................................... 26
2.2.11 incr ........................................................................................................................ 27
2.2.12 incrby .................................................................................................................... 27
2.2.13 decr ....................................................................................................................... 27
2.2.14 decrby ................................................................................................................... 27
2.2.15 append .................................................................................................................. 28
2.2.16 strlen ..................................................................................................................... 28
2.3 hashes 类型及操作 .................................................................................................. 29
2.3.1 hset ......................................................................................................................... 29
2.3.2 hsetnx ..................................................................................................................... 29
2.3.3 hmset ...................................................................................................................... 29
2.3.4 hget ......................................................................................................................... 30
2.3.5 hmget...................................................................................................................... 30
2.3.6 hincrby .................................................................................................................... 30
2.3.7 hexists ..................................................................................................................... 30
2.3.8 hlen ......................................................................................................................... 31
2.3.9 hdel ......................................................................................................................... 31
2.3.10 hkeys ..................................................................................................................... 31
2.3.11 hvals ...................................................................................................................... 31
2.3.12 hgetall ................................................................................................................... 32
2.4 lists 类型及操作 ...................................................................................................... 32
2.4.1 lpush ....................................................................................................................... 32
2.4.2 rpush ....................................................................................................................... 33
2.4.3 linsert ...................................................................................................................... 33
2.4.4 lset .......................................................................................................................... 33 《红丸出品》 http:weibo.comu2446082491
4 71
2.5.5 lrem......................................................................................................................... 34
2.4.6 ltrim ........................................................................................................................ 35
2.4.7 lpop ......................................................................................................................... 36
2.4.8 rpop ........................................................................................................................ 36
2.4.9 rpoplpush ................................................................................................................ 36
2.4.10 lindex .................................................................................................................... 37
2.4.11 llen ........................................................................................................................ 37
2.5 sets 类型及操作 ...................................................................................................... 37
2.5.1 sadd ........................................................................................................................ 37
2.5.2 srem ........................................................................................................................ 38
2.5.3 spop ........................................................................................................................ 38
2.5.4 sdiff ......................................................................................................................... 39
2.5.5 sdiffstore ................................................................................................................. 39
2.5.6 sinter ....................................................................................................................... 40
2.5.7 sinterstore .............................................................................................................. 40
2.5.8 sunion ..................................................................................................................... 40
2.5.9 sunionstore ............................................................................................................. 41
2.5.10 smove ................................................................................................................... 41
2.5.11 scard ..................................................................................................................... 42
2.5.12 sismember ............................................................................................................ 42
2.5.13 srandmember ....................................................................................................... 42
2.6 sorted sets 类型及操作 ........................................................................................... 42
2.6.1 zadd ........................................................................................................................ 43
2.6.2 zrem ........................................................................................................................ 43
2.6.3 zincrby .................................................................................................................... 44
2.6.4 zrank ....................................................................................................................... 44
2.6.5 zrevrank .................................................................................................................. 44
2.6.6 zrevrange ................................................................................................................ 45
2.6.7 zrangebyscore......................................................................................................... 45
2.6.8 zcount ..................................................................................................................... 46 《红丸出品》 http:weibo.comu2446082491
5 71
2.6.9 zcard ....................................................................................................................... 46
2.6.10 zscore .................................................................................................................... 46
2.6.11 zremrangebyrank ................................................................................................. 47
2.6.12 zremrangebyscore ................................................................................................ 47
第三章、Redis常用命令 ....................................................................................................... 48
3.1 键值相关命令 .......................................................................................................... 48
3.1.1 keys ......................................................................................................................... 48
3.1.2 exists ....................................................................................................................... 49
3.1.3 del ........................................................................................................................... 49
3.1.4 expire ...................................................................................................................... 49
3.1.5 move ....................................................................................................................... 50
3.1.6 persist ..................................................................................................................... 50
3.1.7 randomkey .............................................................................................................. 51
3.1.8 rename ................................................................................................................... 51
3.1.9 type ......................................................................................................................... 51
3.2 服务器相关命令 ........................................................................................................... 52
3.2.1 ping ......................................................................................................................... 52
3.2.2 echo ........................................................................................................................ 52
3.2.3 select....................................................................................................................... 52
3.2.4 quit .......................................................................................................................... 52
3.2.5 dbsize ...................................................................................................................... 53
3.2.6 info .......................................................................................................................... 53
3.2.7 monitor ................................................................................................................... 53
3.2.8 config get ................................................................................................................ 53
3.2.9 flushdb .................................................................................................................... 54
3.2.10 flushall .................................................................................................................. 54
第四章 Redis高级实用特性 ................................................................................................. 54
4.1 安全性 .......................................................................................................................... 54
4.2 主从复制 ...................................................................................................................... 55
4.2.1 redis 主从复制特点: .............................................................................................. 55 《红丸出品》 http:weibo.comu2446082491
6 71
4.2.2 redis 主从复制过程: .............................................................................................. 55
4.2.3 如何配置 ............................................................................................................... 56
4.3 事务控制 ...................................................................................................................... 58
4.3.1 简单事务控制 ....................................................................................................... 58
4.3.2 如何取消一个事务 ............................................................................................... 58
4.3.3 乐观锁复杂事务控制 ........................................................................................... 59
4.4 持久化机制 .................................................................................................................. 61
4.4.1 snapshotting方式 .................................................................................................. 61
4.4.2 aof方式 .................................................................................................................. 63
4.5 发布及订阅消息 ........................................................................................................... 66
4.6 Pipeline批量发送请求 ................................................................................................. 67
4.7 虚拟内存的使用 .......................................................................................................... 70
《红丸出品》 http:weibo.comu2446082491
7 71
第一章 Redis 快速入门
Redis是一个Key-Value 存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持 pushpop、addremove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础
上,Redis支持各种不同方式的排序。与 memcached一样,为了保证效率,数据都是缓存在
内存中。区别的是 Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录
文件,并且在此基础上实现了 master-slave(主从)同步。
1.1 Key-Value 存储系统简介
Key-Value Store 是当下比较流行的话题,尤其在构建诸如搜索引擎、IM、P2P、游戏服务器、SNS等大型互联网应用以及提供云计算服务的时候,怎样保证系统在海量数据环境下的高性
能、高可靠性、高扩展性、高可用性、低成本成为所有系统架构们挖苦心思考虑的重点,而
怎样解决数据库服务器的性能瓶颈是最大的挑战。
按照分布式领域的CAP理论(Consistency、 Availability、Tolerance to network Partitions这三
部分在任何系统架构实现时只可能同时满足其中二点,没法三者兼顾)来衡量,传统的关系
数据库的ACID只满足了 Consistency、 Availability,因此在Partition tolerance上就很难做得好。
另外传统的关系数据库处理海量数据、分布式架构时候在 Performance、Scalability、Availability 等方面也存在很大的局限性。
而Key-Value Store 更加注重对海量数据存取的性能、分布式、扩展性支持上,并不需要传统
关系数据库的一些特征,例如:Schema、事务、完整 SQL 查询支持等等,因此在分布式环
境下的性能相对于传统的关系数据库有较大的提升。
Key-Value数据库分为很多种类,具体如下图: 《红丸出品》 http:weibo.comu2446082491
8 71
这些 Key-Value 数据库,有的是用 CC++编写的,有的是用 Java 编写的,还有的是用 Erlang
编写的,每个都有自己的独到之处,我们从中挑选一些比较有特色且应用广泛的产品学习和
了解一下。
1.1.1 Voldemort
Voldemort是一个分布式 KeyValue存储系统,它具有以下特点:
· 数据自动在多个服务器之间复制;
· 数据自动分区,因此每个服务器只包括整体数据的一个子集;
· 服务器故障处理是透明的;
· 支持插入式序列化,允许丰富的 Key和 Value 类型,包括列表和元组,也可以集成常见
的序列化框架,如 Protocol Buffers,Thrift,Avro和 Java Serialization
· 数据项支持版本化,即使在故障情况下,数据完整性也可以得到保障;
· 每个节点都是独立的,无需其他节点协调,因此也没有中央节点;
· 单节点性能优秀:根据机器配置、网络、磁盘系统和数据复制因素的不同,每秒可以执
行 10-20k操作;
· 支持地理分散式部署。
1.1.2 Dynamo
Dynamo是亚马逊的 key-value模式的存储平台,可用性和扩展性都很好,性能也不错:读写
访问中99.9%的响应时间都在300ms内。 《红丸出品》 http:weibo.comu2446082491
9 71
接下来对 Dynamo 需要的一些特性做一下简要的描述:
· Cost-effectiveness - 省钱!Dynamo 不像一些商用数据库产品,需要昂贵的服务器来得
到良好的性能,而且可能增加5%的访问量会需要你花2 万美刀去买一台新服务器。而
在 Dynamo 上,由于是利用一堆廉价机器来存数据,于是你可能只需要花个 500 刀买
个破机器加入到集群里就行了。
· Dynamo 是一个 Key-Value 存储 - 因此他不支持外键和关联查询什么的。其 Value值是
二进制存储的,所以查询条件也只能作用在 Key 上。
· 配置简单的分布式存储 - 这是由于 Dynamo 是去中心化地设计,在集群中它的每一台
机器都是对等的,不像 MongoDB 这样的中心化设计,于是它也不会有单点问题。
1.1.3 memcachedb
memcachedb是 一个由新浪网的开发人员开放出来的开源项目,给 memcached分布式缓存
服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制,让 memcached具备了事
务恢复能力、持久化能力和分布式复制能力,非常适合于需要超高性能读写速度,但是 不
需要严格事务约束,能够被持久化保存的应用场景,例如 memcachedb 被应用在新浪博客上
面。
1.1.4 Cassandra
Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由 Facebook开发,用于储
存特别大的数据。Facebook目前在使用此系统。
主要特性:
· 分布式
· 基于column 的结构化
· 高伸展性
Cassandra 的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布
式网络服务,对 Cassandra 的一个写操作,会被复制到其他节点上去,对 Cassandra 的读操
作,也会被路由到某个节点上面去读取。对于一个 Cassandra 群集来说,扩展性能 是比较
简单的事情,只管在群集里面添加节点就可以了。
Cassandra 是一个混合型的非关系的数据库,类似于 Google 的 BigTable。其主要功能比
Dynomite(分布式的Key-Value存 储系统)更丰富,但支持度却不如文档存储MongoDB(介
于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系
数据库 的。支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂
的数据类型。)Cassandra 最初由 Facebook 开发,后转变成了开源项目。它是一个网络社交
云计算方面理想的数据库。以 Amazon专有的完全分布式的 Dynamo为基础,结合了Google
BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称
之为Dynamo 2.0。
《红丸出品》 http:weibo.comu2446082491
10 71
和其他数据库比较,有几个突出特点:
· 模式灵活 :使用 Cassandra,像文档存储,你不必提前解决记录中的字段。你可以在系
统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型部 署上。
· 真正的可扩展性 :Cassandra是纯粹意义上的水平扩展。为给集群添加更多容量,可以
指向另一台电脑。你不必重启任何进程,改变应用查询,或手动迁移任何数据。
· 多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一个备用的
数据中心将至少有每条记录的完全复制。
· 范围查询 :如果你不喜欢全部的键值查询,则可以设置键的范围来查询。
· 列表数据结构 :在混合模式可以将超级列添加到 5 维。对于每个用户的索引,这是非
常方便的。
· 分布式写操作 :有可以在任何地方任何时间集中读或写任何数据。并且不会有任何单
点失败。
1.1.5 memcached
memcached是一套分布式的快取系统,当初是 Danga Interactive为了 LiveJournal所发展的,但目前被许多软件(如 MediaWiki)所使用。这是一套开放源代码软件,以BSD license授权
释出。
memcached缺乏认证以及安全管制,这代表应该将memcached服务器放置在防火墙后。
memcached的 API使用三十二位元的循环冗余校验(CRC-32)计算键值后,将资料分散在不
同的机器上。当表格满了以后,接下来新增的资料会以 LRU 机制替换掉。由于 memcached
通常只是当作快取系统使用,所以使用 memcached 的应用程式在写回较慢的系统时(像是
后端的数据库)需要额外的程式码更新memcached内的资料。
memcached具有多种语言的客户端开发包,包括:PerlPHPJAVACPythonRubyCMySQL
1.1.6 Hypertable
Hypertable是一个开源、高性能、可伸缩的数据库,它采用与 Google的Bigtable相似的模型。
在过去数年中,Google 为在 PC 集群 上运行的可伸缩计算基础设施设计建造了三个关键部
分。第一个关键的基础设施是Google File System(GFS),这是一个高可用的文件系统,提供
了一个全局的命名空间。它通过跨机器(和跨机架)的文件数据复制来达到高可用性,并因
此免受传统 文件存储系统无法避免的许多失败的影响,比如电源、内存和网络端口等失败。
第二个基础设施是名为 Map-Reduce 的计算框架,它与 GFS 紧密协作,帮 助处理收集到的
海量数据。第三个基础设施是 Bigtable,它是传统数据库的替代。Bigtable 让你可以通过一
些主键来组织海量数据,并实现高效的 查询。Hypertable 是Bigtable的一个开源实现,并且
根据我们的想法进行了一些改进。 《红丸出品》 http:weibo.comu2446082491
11 71
1.2 为什么选择 Key-Value Store
大量的互联网用户选择 Key-Value Store 的原因具体是什么呢? 主要分为下面的 2个主要原
因:
1.2.1 大规模的互联网应用
对于 google,ebay 这样的互联网企业,每时每刻都有无数的用户在使用它们提供的互联网
服务,这些服务带来的就是大量的数据吞吐量,在同一时间,会并发的有成千上万的连接对
数据库进行操作。在这种情况下,单台服务器或者几台服务器远远不能满足这些数据处理的
需求,简单的升级服务器性能这样的scale up的方式也不行,所以唯一可以采用的办法就是
scale out了。scale out的方法有很多种,但大致分为两类:一类仍然采用 RDBMS,然后通过
对数据库的垂直和水平切割将整个数据库部署到一个集群上,这种方法的优点在于可以采用
RDBMS 这种熟悉的技术,但缺点在于它是针对特定应用的,就是说,由于应用的不同,切
割的方法是不一样的。
还有一类就是google 所采用的方法,抛弃 RDBMS,采用key-value 形式的存储,这样可 以
极大的增强系统的可扩展性(scalability),如果要处理的数据持续增大,多加机器就 可
以了。事实上,key-value的存储就是由于 BigTable等相关论文的发表慢慢进入人们的 视
野的。
1.2.2 云存储
如果说上一个问题还有可以替代的解决方案(切割数据库)的话,那么对于云存储来说,也
许key-value的store就是唯一的解决方案了。云存储简单点说就是构建一个大型的存储平台
给别人用,这也就意味着在这上面运行的应用其实是不可控的。如果其中某个客户的应用随
着用户的增长而不断增长时,云存储供应商是没有办法通过数据库的切割来达到 scale 的,因为这个数据是客户的,供应商不了解这个数据自然就没法作出切割。在这种情况下,key-value 的 store 就是唯一的选择了,因为这种条件下的 scalability 必须是自动完成的,不
能有人工干预。这也是为什么几乎所有的现有的云存储都是key-value 形式的,例如Amazon
的smipleDB,底层实现就是 key-value,还有 google的 GoogleAppEngine,采用的是BigTable
的存储形式。也许唯一可能例外的是 MS 的解决方案,我在 Qcon 大会上听说 MS 的 Azure
平台的下一个版本中就会推出基于RDBMS的云存储,尽管我本人仍然对此保持怀疑。
Key-Value Store 最大的特点就是它的可扩展性,这也就是它最大的优势。所谓的可扩展性,在我看来这里包括了两方面内容。一方面,是指 Key-Value Store可以支持极大的数据的存储,它的分布式的架构决定了只要有更多的机器,就能够保证存储更多的数据。另一方面,是指
它可以支持数量很多的并发的查询。对于 RDBMS,一般几百个并发的查询就可以让它很吃
力了,而一个Key-Value Store,可以很轻松的支持上千的并发查询。下面而简单的罗列了一
些特点:
· Key-value store:一个 key-value 数据存储系统,只支持一些基本操作,如: SET(key, value) 《红丸出品》 http:weibo.comu2446082491
12 71
和 GET(key) 等;
· 分布式:多台机器(nodes)同时存储数据和状态,彼此交换消息来保持数据一致,可
视为一个完整的存储系统。
· 数据一致:所有机器上的数据都是同步更新的、不用担心得到不一致的结果;
· 冗余:所有机器(nodes)保存相同的数据,整个系统的存储能力取决于单台机器(node)
的能力;
· 容错:如果有少数 nodes 出错,比如重启、当机、断网、网络丢包等各种 faultfail 都
不影响整个系统的运行;
· 高可靠性:容错、冗余等保证了数据库系统的可靠性。
1.2.3 Redis 实际应用案例
目前全球最大的 Redis 用户是新浪微博,在新浪有 200 多台物理机,400 多个端口正在运行
着Redis, 有+4G 的数据跑在 Redis上来为微博用户提供服务。
在新浪微博Redis的部署场景很多,大概分为如下的2 种:
第一种是应用程序直接访问 Redis数据库 《红丸出品》 http:weibo.comu2446082491
13 71
第二种是应用程序直接访问 Redis,只有当 Redis访问失败时才访问 MySQL
同时,Digg的一项新功能,添加了对文章浏览数的显示,这一功能的一大卖点是其实时性。 《红丸出品》 http:weibo.comu2446082491
14 71
而支持此实时浏览量计数的,正是 Redis。
1.3 初识 Redis
Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起, Redis的开发工作由VMware
主持。
1.3.1 数据类型
作为 Key-value 型数据库,Redis 也提供了键(Key)和键值(Value)的映射关系。但是,除
了常规的数值或字符串,Redis的键值还可以是以下形式之一:
· Lists (列表)
· Sets (集合)
· Sorted sets (有序集合)
· Hashes (哈希表)
键值的数据类型决定了该键值支持的操作。Redis 支持诸如列表、集合或有序集合的交集、并集、查集等高级原子操作;同时,如果键值的类型是普通数字,Redis 则提供自增等原子
操作。
1.3.2 持久化
通常,Redis 将数据存储于内存中,或被配置为使用虚拟内存。通过两种方式可以实现数据
持久化:使用截图的方式,将内存中的数据不断写入磁盘;或使用类似 MySQL 的日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
1.3.3 主从同步
Redis支持将数据同步到多台从库上,这种特性对提高读取性能非常有益。 《红丸出品》 http:weibo.comu2446082491
15 71
1.3.4 性能
相比需要依赖磁盘记录每个更新的数据库,基于内存的特性无疑给 Redis带来了非常优秀的
性能。读写操作之间有显著的性能差异。
1.3.5 提供 API的语言
· C
· C++
· C
· Clojure
· Common Lisp
· Erlang
· Haskell
· Java
· Javascript
· Lua
· Objective-C
· Perl
· PHP
· Python
· Ruby
· Scala
· Go
· Tcl
1.3.6 适用场合
毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数
据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用 Redis灵活多变的数据结
构和数据操作,为不同的大象构建不同的冰箱。希望你喜欢这个比喻。
下面是Redis适用的一些场景:
1、取最新 N 个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的 5000条评论的ID放在
Redis的List集合中,并将超出集合部分从数据库获取。
使用LPUSH latest.comments命令,向 list集合中插入数据
插入完成后再用 LTRIM latest.comments 0 5000 命令使其永远只保存最近5000个 ID
然后我们在客户端获取某一页评论时可以用下面的逻辑
FUNCTION get_latest_comments(start,num_items): 《红丸出品》 http:weibo.comu2446082491
16 71
id_list = redis.lrange(latest.comments,start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB(SELECT ... ORDER BY time LIMIT ...)
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新 N 条,那么你可以再建一个按此分类的
List,只存ID的话,Redis是非常高效的。
2、排行榜应用,取 TOP N 操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的 sorted set出马了,将你要排序的值设置成 sorted
set的score,将具体的数据设置成相应的 value,每次只需要执行一条ZADD命令即可。
3、需要精准设定过期时间的应用
比如你可以把上面说到的 sorted set 的 score 值设置成过期时间的时间戳,那么就可以简单
地通过过期时间排序,定时清除过期数据了,不仅是清除 Redis中的过期数据,你完全可以
把 Redis 里这个过期时间当成是对数据库中数据的索引,用 Redis 来找出哪些数据需要过期
删除,然后再精准地从数据库中删除相应的记录。
4、计数器应用
Redis的命令都是原子性的,你可以轻松地利用 INCR,DECR 命令来构建计数器系统。
5、Uniq 操作,获取某段时间所有数据排重值
这个使用Redis的 set数据结构最合适了,只需要不断地将数据往 set中扔就行了,set意为
集合,所以会自动排重。
6、实时系统,反垃圾系统
通过上面说到的 set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作
的集合并进行分析统计对比等。没有做不到,只有想不到。
7、PubSub 构建实时消息系统
Redis 的 PubSub 系统可以构建实时的消息系统,比如很多用 PubSub 构建的实时聊天系统
的例子。
8、构建队列系统
使用list可以构建队列系统,使用 sorted set甚至可以构建有优先级的队列系统。
9、缓存
这个不必说了,性能优于Memcached,数据结构更多样化。 《红丸出品》 http:weibo.comu2446082491
17 71
1.4 快速入门
1.4.1 安装 Redis
Redis的官方下载站是 http:redis.iodownload,可以去上面下载最新的安装程序下来,我写
此文章时的的稳定版本是2.2.12。
怎么安装 Redis数据库呢?下面将介绍 Linux版本的安装方法
步骤一: 下载Redis
下载安装包:wget http:redis.googlecode.comfilesredis-2.2.12.tar.gz
[root@localhost 4setup] wget http:redis.googlecode.comfilesredis-2.2.12.tar.gz--19:06:56-- http:redis.googlecode.comfilesredis-2.2.12.tar.gz
正在解析主机 redis.googlecode.com... 74.125.71.82
Connecting to redis.googlecode.com|74.125.71.82|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:455240 (445K) [applicationx-gzip]
Saving to: `redis-2.2.12.tar.gz'
100%[==========================================>] 455,240 34.8Ks in 13s
19:07:16 (34.8 KBs) - `redis-2.2.12.tar.gz' saved [455240455240]
[root@localhost 4setup]
步骤二: 编译源程序
[root@localhost 4setup] ll
总计 29168
-rw-r--r-- 1 root root 455240 2011-07-22 redis-2.2.12.tar.gz
[root@localhost 4setup] tar xzf redis-2.2.12.tar.gz
[root@localhost 4setup] cd redis-2.2.12
[root@localhost redis-2.2.12] make
cd src make all
make[1]: Entering directory `root4setupredis-2.2.12src'
步骤三: 启动Redis服务 《红丸出品》 http:weibo.comu2446082491
18 71
srcredis-server
[root@localhost redis-2.2.12] srcredis-server
[6246] 05 Aug 19:17:22 Warning: no config file specified, using the default config. In order to
specify a config file use 'redis-server pathtoredis.conf'
[6246] 05 Aug 19:17:22 Server started, Redis version 2.2.12
[6246] 05 Aug 19:17:22 WARNING overcommit_memory is set to 0! Background save may fail
under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to
etcsysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this
to take effect.
[6246] 05 Aug 19:17:22 The server is now ready to accept connections on port 6379
[6246] 05 Aug 19:17:22 - 0 clients connected (0 slaves), 539544 bytes in use
Redis 服务端的默认连接端口是 6379
步骤四: 将Redis作为 Linux 服务随机启动
vi etcrc.local, 使用 vi编辑器打开随机启动配置文件,并在其中加入下面一行代码
root4setupredis-2.2.12srcredis-server
步骤五: 客户端连接验证
新打开一个 Session 输入:srcredis-cli,如果出现下面提示,那么您就可以开始 Redis 之
旅了
[root@localhost redis-2.2.12] srcredis-cli
redis 127.0.0.1:6379>
步骤六: 查看Redis日志
查看服务器端 session,即可对Redis的运行状况进行查看或分析了
[6246] 05 Aug 19:24:33 - 0 clients connected (0 slaves), 539544 bytes in use
[6246] 05 Aug 19:24:37 - Accepted 127.0.0.1:51381
[6246] 05 Aug 19:24:38 - 1 clients connected (0 slaves), 547372 bytes in use
以上的几个步骤就OK了!!这样一个简单的Redis数据库就可以畅通无阻地运行起来了。
步骤七: 停止Redis实例
最简单的方法是在启动实例的 session中,直接使用Control-C来将实例停止。
我们还可以用客户端来停止服务,如可以用 shutdown来停止 Redis实例, 具体如下:
[root@localhost redis-2.2.12] srcredis-cli shutdown
1.4.2 配置 Redis
如果是一个专业的 DBA,那么实例启动时会加很多的参数以便使系统运行的非常稳定,这样
就可能会在启动时在 Redis后面加一个参数,以指定配置文件的路径,就象 mysql一样的读
取启动配置文件的方式来启动数据库。源码编译完成后,在 redis-2.2.12 目录下有一个
redis.conf 文件,这个文件即是 Redis的配置文件,用配置文件来启动 Redis的方法如下: 《红丸出品》 http:weibo.comu2446082491
19 71
[root@localhost redis-2.2.12] srcredis-server redis.conf
[6353] 05 Aug 19:36:45 Server started, Redis version 2.2.12
[6353] 05 Aug 19:36:45 WARNING overcommit_memory is set to 0! Background save may fail
under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to
etcsysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this
to take effect.
[6353] 05 Aug 19:36:45 The server is now ready to accept connections on port 6379
[6353] 05 Aug 19:36:45 - 0 clients connected (0 slaves), 539540 bytes in use
Redis支持很多的参数,但都有默认值。
· daemonize:
默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
· pidfile
当 Redis 在后台运行的时候,Redis 默认会把 pid 文件放在varrunredis.pid,你可以配
置到其他地址。当运行多个 redis服务时,需要指定不同的pid 文件和端口
· bind
指定Redis只接收来自于该 IP地址的请求,如果不进行设置,那么将处理所有请求,在
生产环境中最好设置该项
· port
监听端口,默认为6379
· timeout
设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接
· loglevel
log等级分为4 级,debug, verbose, notice, 和warning。生产环境下一般开启 notice
· logfile
配置log文件地址,默认使用标准输出,即打印在命令行终端的窗口上
· databases
设置数据库的个数,可以使用 SELECT命令来切换数据库。默认使用的数据库是0
· save
设置Redis进行数据库镜像的频率。
if(在60 秒之内有 10000个keys发生变化时){
进行镜像备份
}else if(在300 秒之内有10个keys发生了变化){
进行镜像备份
}else if(在900 秒之内有1个keys发生了变化){
进行镜像备份
}
· rdbcompression
在进行镜像备份时,是否进行压缩
· dbfilename
镜像备份文件的文件名
· dir
数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为Redis在进 《红丸出品》 http:weibo.comu2446082491
20 71
行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,再把该该
临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放
在这个指定的路径当中
· slaveof
设置该数据库为其他数据库的从数据库
· masterauth
当主数据库连接需要密码验证时,在这里指定
· requirepass
设置客户端连接后进行任何其他指定前需要使用的密码。警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K 次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。
· maxclients
限制同时连接的客户数量。当连接数超过这个值时,redis 将不再接收其他连接请求,客户端尝试连接时将收到error信息。
· maxmemory
设置 redis 能够使用的最大内存。当内存满了的时候,如果还接收到 set 命令,redis 将
先尝试剔除设置过expire信息的key,而不管该 key的过期时间还没有到达。在删除时,将按照过期时间进行删除,最早将要被过期的 key将最先被删除。如果带有expire信息
的 key都删光了,那么将返回错误。这样,redis将不再接收写请求,只接收get请求。
maxmemory的设置比较适合于把redis当作于类似memcached的缓存来使用。
· appendonly
默认情况下,redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时
的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较
大范围的数据丢失。所以 redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
开启 append only 模式之后,redis 会把所接收到的每一次写操作请求都追加到
appendonly.aof 文件中,当redis重新启动时,会从该文件恢复出之前的状态。但是这样
会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对
appendonly.aof 进行重新整理。所以我认为推荐生产环境下的做法为关闭镜像,开启
appendonly.aof,同时可以选择在访问较少的时间每天对appendonly.aof 进行重写一次。
· appendfsync
设置对 appendonly.aof 文件进行同步的频率。always 表示每次有写操作都进行同步,everysec表示对写操作进行累积,每秒同步一次。这个需要根据实际业务场景进行配置
· vm-enabled
是否开启虚拟内存支持。因为 redis 是一个内存数据库,而且当内存满的时候,无法接
收新的写请求,所以在redis 2.0中,提供了虚拟内存的支持。但是需要注意的是,redis
中,所有的 key都会放在内存中,在内存不够时,只会把value值放入交换区。这样保
证了虽然使用虚拟内存,但性能基本不受影响,同时,你需要注意的是你要把
vm-max-memory 设置到足够来放下你的所有的key
· vm-swap-file
设置虚拟内存的交换文件路径
· vm-max-memory
这里设置开启虚拟内存之后,redis 将使用的最大物理内存的大小。默认为 0,redis 将
把他所有的能放到交换文件的都放到交换文件中,以尽量少的使用物理内存。在生产环
境下,需要根据实际情况设置该值,最好不要使用默认的 0 《红丸出品》 http:weibo.comu2446082491
21 71
· vm-page-size
设置虚拟内存的页大小,如果你的 value 值比较大,比如说你要在 value 中放置博客、新闻之类的所有文章内容,就设大一点,如果要放置的都是很小的内容,那就设小一点。
· vm-pages
设置交换文件的总的 page数量,需要注意的是,page table信息会放在物理内存中,每
8 个page就会占据 RAM中的1个 byte。总的虚拟内存大小 = vm-page-size vm-pages
· vm-max-threads
设置 VM IO 同时使用的线程数量。因为在进行内存交换时,对数据有编码和解码的过
程,所以尽管 IO 设备在硬件上本上不能支持很多的并发读写,但是还是如果你所保存
的 vlaue 值比较大,将该值设大一些,还是能够提升性能的
· glueoutputbuf
把小的输出缓存放在一起,以便能够在一个 TCP packet中为客户端发送多个响应,具体
原理和真实效果我不是很清楚。所以根据注释,你不是很确定的时候就设置成 yes
· hash-max-zipmap-entries
在 redis 2.0中引入了 hash数据结构。当 hash中包含超过指定元素个数并且最大的元素
没有超过临界时,hash 将以一种特殊的编码方式(大大减少内存使用)来存储,这里
可以设置这两个临界值
· activerehashing
开启之后,redis 将在每 100 毫秒时使用 1 毫秒的 CPU 时间来对 redis 的 hash 表进行重
新 hash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能
够接受Redis时不时的对请求有2 毫秒的延迟的话,把这项配置为 no。如果没有这么严
格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
1.4.3 操作数据库
下面我们来简单的操作一下数据库。
插入数据
redis 127.0.0.1:6379> set name wwl
OK
设置一个key-value 对
查询数据
redis 127.0.0.1:6379> get name
wwl
取出key 所对应的value
删除键值
redis 127.0.0.1:6379> del name
删除这个key 及对应的value
验证键是否存在
redis 127.0.0.1:6379> exists name
(integer) 0 《红丸出品》 http:weibo.comu2446082491
22 71
其中0,代表此key不存在;1代表存在
第二章 Redis 数据类型及操作
2.1 前言
Redis的作者antirez(Salvatore Sanfilippo)曾经发表了一篇名为 Redis宣言(Redis Manifesto)
的文章,文中列举了 Redis 的七个原则,以向大家阐明Redis 的思想。
1、Redis是一个操作数据结构的语言工具,它提供基于 TCP的协议以操作丰富的数据结构。
在Redis中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身
及这些操作的时间空间复杂度。
2、Redis定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis能够有如此
高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构,Redis 会尝试其它的存储方面
的选择,但是永远不会改变它是一个内存数据库的角色。
3、Redis使用基础的 API操作基础的数据结构,Redis的 API与数据结构一样,都是一些最基
础的元素,你几乎可以将任何信息交互使用此 API格式表示。作者调侃说,如果有其它非人
类的智能生物存在,他们也能理解 Redis的API。因为它是如此的基础。
4、Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些
其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》
接上后四十回一样。
5、Redis始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为
了一个小功能而往源码里添加上千行代码, 解决复杂问题的方法就是让复杂问题永远不要提
复杂的问题。
6、Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下
的Redis。第二个层面的API支持更复杂的 multi-key操作。它们各有所长,但是我们不会推
出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。 《红丸出品》 http:weibo.comu2446082491
23 71
7、我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享
受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让
Redis不好玩的开发模式。
Redis的作者antirez曾笑称Redis为一个数据结构服务器(data structures server),我认为这
是一个非常准确的表述,Redis 的所有功能就是将数据以其固有的几种结构来保存,并提供
给用户操作这几种结构的接口。本文将介绍 Redis支持的各种数据类型及其操作接口。
2.2 strings 类型及操作
string是最简单的类型,你可以理解成与 Memcached是一模一样的类型,一个 key 对应一个
value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。
string类型是二进制安全的。意思是 redis的 string可以包含任何数据,比如 jpg图片或者序
列化的对象。从内部实现来看其实 string可以看作byte 数组,最大上限是1G字节,下面是
string类型的定义:
struct sdshdr {
long len;
long free;
char buf[];
};
len是buf 数组的长度。
free 是数组中剩余可用字节数,由此可以理解为什么 string类型是二进制安全的了,因为它
本质上就是个byte 数组,当然可以包含任何数据了
buf 是个char数组用于存贮实际的字符串内容,其实char和 c中的byte是等价的,都是一
个字节。
另外string类型可以被部分命令按 int处理.比如incr 等命令,如果只用 string类型,redis就
可以被看作加上持久化特性的 memcached。 当然redis对 string类型的操作比memcached还
是多很多的,具体操作方法如下:
2.2.1 set
设置key 对应的值为 string类型的value。
例如我们添加一个 name= HongWan的键值对,可以这样做:
redis 127.0.0.1:6379> set name HongWan
OK
redis 127.0.0.1:6379>
2.2.2 setnx
设置key 对应的值为 string类型的value。 如果 key 已经存在,返回 0, nx是 not exist的意思。 《红丸出品》 http:weibo.comu2446082491
24 71
例如我们添加一个 name= HongWan_new的键值对,可以这样做:
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379> setnx name HongWan_new
(integer) 0
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379>
由于原来name 有一个对应的值,所以本次的修改不生效,且返回码是 0。
2.2.3 setex
设置key 对应的值为 string类型的value,并指定此键值对应的有效期。
例如我们添加一个 haircolor= red的键值对,并指定它的有效期是 10秒,可以这样做:
redis 127.0.0.1:6379> setex haircolor 10 red
OK
redis 127.0.0.1:6379> get haircolor
red
redis 127.0.0.1:6379> get haircolor
(nil)
redis 127.0.0.1:6379>
可见由于最后一次的调用是 10秒以后了,所以取不到 haicolor 这个键对应的值。
2.2.4 setrange
设置指定key 的value 值的子字符串。
例如我们希望将 HongWan的126邮箱替换为 gmail邮箱,那么我们可以这样做:
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379> setrange name 8 gmail.com
(integer) 17
redis 127.0.0.1:6379> get name
HongWan@gmail.com
redis 127.0.0.1:6379>
其中的8是指从下标为8(包含8)的字符开始替换
2.2.5 mset
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值
被设置。
redis 127.0.0.1:6379> mset key1 HongWan1 key2 HongWan2 《红丸出品》 http:weibo.comu2446082491
25 71
OK
redis 127.0.0.1:6379> get key1
HongWan1
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379>
2.2.6 msetnx
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值
被设置,但是不会覆盖已经存在的 key。
redis 127.0.0.1:6379> get key1
HongWan1
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379> msetnx key2 HongWan2_new key3 HongWan3
(integer) 0
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379> get key3
(nil)
可以看出如果这条命令返回 0,那么里面操作都会回滚,都不会被执行。
2.2.7 get
获取key 对应的string值,如果key 不存在返回 nil。
例如我们获取一个库中存在的键 name,可以很快得到它对应的 value
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379>
我们获取一个库中不存在的键 name1,那么它会返回一个 nil以表时无此键值对
redis 127.0.0.1:6379> get name1
(nil)
redis 127.0.0.1:6379>
2.2.8 getset
设置key 的值,并返回 key 的旧值。
redis 127.0.0.1:6379> get name
HongWan 《红丸出品》 http:weibo.comu2446082491
26 71
redis 127.0.0.1:6379> getset name HongWan_new
HongWan
redis 127.0.0.1:6379> get name
HongWan_new
redis 127.0.0.1:6379>
接下来我们看一下如果 key 不存的时候会什么样儿?
redis 127.0.0.1:6379> getset name1 aaa
(nil)
redis 127.0.0.1:6379>
可见,如果key不存在,那么将返回 nil
2.2.9 getrange
获取指定key 的value 值的子字符串。
具体样例如下:
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379> getrange name 0 6
HongWan
redis 127.0.0.1:6379>
字符串左面下标是从 0开始的
redis 127.0.0.1:6379> getrange name -7 -1
126.com
redis 127.0.0.1:6379>
字符串右面下标是从-1开始的
redis 127.0.0.1:6379> getrange name 7 100
@126.com
redis 127.0.0.1:6379>
当下标超出字符串长度时,将默认为是同方向的最大下标
2.2.10 mget
一次获取多个key 的值,如果对应key 不存在,则对应返回 nil。
具体样例如下:
redis 127.0.0.1:6379> mget key1 key2 key3
1) HongWan1
2) HongWan2
3) (nil)
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
27 71
key3由于没有这个键定义,所以返回 nil。
2.2.11 incr
对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一
个不存在的key,则设置 key 为1
redis 127.0.0.1:6379> set age 20
OK
redis 127.0.0.1:6379> incr age
(integer) 21
redis 127.0.0.1:6379> get age
21
redis 127.0.0.1:6379>
2.2.12 incrby
同incr类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0
redis 127.0.0.1:6379> get age
21
redis 127.0.0.1:6379> incrby age 5
(integer) 26
redis 127.0.0.1:6379> get name
HongWan@gmail.com
redis 127.0.0.1:6379> get age
26
redis 127.0.0.1:6379>
2.2.13 decr
对key的值做的是减减操作,decr一个不存在 key,则设置key为-1
redis 127.0.0.1:6379> get age
26
redis 127.0.0.1:6379> decr age
(integer) 25
redis 127.0.0.1:6379> get age
25
redis 127.0.0.1:6379>
2.2.14 decrby
同decr,减指定值。 《红丸出品》 http:weibo.comu2446082491
28 71
redis 127.0.0.1:6379> get age
25
redis 127.0.0.1:6379> decrby age 5
(integer) 20
redis 127.0.0.1:6379> get age
20
redis 127.0.0.1:6379>
decrby 完全是为了可读性,我们完全可以通过 incrby 一个负值来实现同样效果,反之一样。
redis 127.0.0.1:6379> get age
20
redis 127.0.0.1:6379> incrby age -5
(integer) 15
redis 127.0.0.1:6379> get age
15
redis 127.0.0.1:6379>
2.2.15 append
给指定key的字符串值追加 value,返回新字符串值的长度。
例如我们向name的值追加一个@126.com 字符串,那么可以这样做:
redis 127.0.0.1:6379> append name @126.com
(integer) 15
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379>
2.2.16 strlen
取指定key的value值的长度。
redis 127.0.0.1:6379> get name
HongWan_new
redis 127.0.0.1:6379> strlen name
(integer) 11
redis 127.0.0.1:6379> get age
15
redis 127.0.0.1:6379> strlen age
(integer) 2
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
29 71
2.3 hashes 类型及操作
Redis hash是一个 string类型的field和value的映射表.它的添加、删除操作都是 O(1) (平均)。
hash特别适合用于存储对象。相较于将对象的每个字段存成单个 string类型。将一个对象存
储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。省内存的原因是新
建一个hash对象时开始是用 zipmap(又称为 small hash)来存储的。这个 zipmap其实并不
是hash table,但是 zipmap相比正常的hash实现可以节省不少hash 本身需要的一些元数据
存储开销。尽管 zipmap的添加,删除,查找都是 O(n),但是由于一般对象的 field数量都不
太多。所以使用 zipmap 也是很快的,也就是说添加删除平均还是 O(1)。如果 field 或者 value
的大小超出一定限制后, Redis会在内部自动将zipmap替换成正常的 hash实现. 这个限制可
以在配置文件中指定
hash-max-zipmap-entries 64 配置字段最多 64个
hash-max-zipmap-value 512 配置value 最大为512字节
2.3.1 hset
设置hash field为指定值,如果 key 不存在,则先创建。
redis 127.0.0.1:6379> hset myhash field1 Hello
(integer) 1
redis 127.0.0.1:6379>
2.3.2 hsetnx
设置hash field为指定值,如果 key 不存在,则先创建。如果 field已经存在,返回0,nx是
not exist的意思。
redis 127.0.0.1:6379> hsetnx myhash field Hello
(integer) 1
redis 127.0.0.1:6379> hsetnx myhash field Hello
(integer) 0
redis 127.0.0.1:6379>
第一次执行是成功的,但第二次执行相同的命令失败,原因是field已经存在了。
2.3.3 hmset
同时设置hash的多个field。
redis 127.0.0.1:6379> hmset myhash field1 Hello field2 World
OK
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
30 71
2.3.4 hget
获取指定的hash field。
redis 127.0.0.1:6379> hget myhash field1
Hello
redis 127.0.0.1:6379> hget myhash field2
World
redis 127.0.0.1:6379> hget myhash field3
(nil)
redis 127.0.0.1:6379>
由于数据库没有 field3,所以取到的是一个空值nil
2.3.5 hmget
获取全部指定的 hash filed。
redis 127.0.0.1:6379> hmget myhash field1 field2 field3
1) Hello
2) World
3) (nil)
redis 127.0.0.1:6379>
由于数据库没有 field3,所以取到的是一个空值nil
2.3.6 hincrby
指定的hash filed 加上给定值。
redis 127.0.0.1:6379> hset myhash field3 20
(integer) 1
redis 127.0.0.1:6379> hget myhash field3
20
redis 127.0.0.1:6379> hincrby myhash field3 -8
(integer) 12
redis 127.0.0.1:6379> hget myhash field3
12
redis 127.0.0.1:6379>
在本例中我们将 field3 的值从20 降到了12,即做了一个减8 的操作。
2.3.7 hexists
测试指定field是否存在。
redis 127.0.0.1:6379> hexists myhash field1
(integer) 1 《红丸出品》 http:weibo.comu2446082491
31 71
redis 127.0.0.1:6379> hexists myhash field9
(integer) 0
redis 127.0.0.1:6379>
通过上例可以说明 field1存在,但field9是不存在的。
2.3.8 hlen
返回指定hash的 field数量。
redis 127.0.0.1:6379> hlen myhash
(integer) 4
redis 127.0.0.1:6379>
通过上例可以看到 myhash中有4 个field。
2.3.9 hdel
返回指定hash的 field数量。
redis 127.0.0.1:6379> hlen myhash
(integer) 4
redis 127.0.0.1:6379> hdel myhash field1
(integer) 1
redis 127.0.0.1:6379> hlen myhash
(integer) 3
redis 127.0.0.1:6379>
2.3.10 hkeys
返回hash的所有 field。
redis 127.0.0.1:6379> hkeys myhash
1) field2
2) field
3) field3
redis 127.0.0.1:6379>
说明这个hash中有3 个field
2.3.11 hvals
返回hash的所有 value。
redis 127.0.0.1:6379> hvals myhash
1) World
2) Hello
3) 12 《红丸出品》 http:weibo.comu2446082491
32 71
redis 127.0.0.1:6379>
说明这个hash中有3 个field
2.3.12 hgetall
获取某个hash中全部的filed及value。
redis 127.0.0.1:6379> hgetall myhash
1) field2
2) World
3) field
4) Hello
5) field3
6) 12
redis 127.0.0.1:6379>
可见,一下子将 myhash中所有的field及对应的value 都取出来了。
2.4 lists类型及操作
list 是一个链表结构,主要功能是 push、pop、获取一个范围的所有值等等,操作中 key 理
解为链表的名字。
Redis的list类型其实就是一个每个子元素都是 string类型的双向链表。链表的最大长度是(2
的32次方)。我们可以通过 push,pop操作从链表的头部或者尾部添加删除元素。这使得 list
既可以用作栈,也可以用作队列。
有意思的是list的 pop操作还有阻塞版本的,当我们[lr]pop一个 list对象时,如果list是空,或者不存在,会立即返回 nil。但是阻塞版本的 b[lr]pop可以则可以阻塞,当然可以加超时时
间,超时后也会返回 nil。为什么要阻塞版本的 pop 呢,主要是为了避免轮询。举个简单的
例子如果我们用 list来实现一个工作队列。执行任务的thread可以调用阻塞版本的 pop去获
取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。说了这么多,接下来看一下实际操作的方法吧:
2.4.1 lpush
在key对应list的头部添加字符串元素
redis 127.0.0.1:6379> lpush mylist world
(integer) 1
redis 127.0.0.1:6379> lpush mylist hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist 0 -1
1) hello 《红丸出品》 http:weibo.comu2446082491
33 71
2) world
redis 127.0.0.1:6379>
在此处我们先插入了一个world,然后在world的头部插入了一个 hello。其中 lrange 是用于
取mylist的内容。
2.4.2 rpush
在key对应list的尾部添加字符串元素
redis 127.0.0.1:6379> rpush mylist2 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist2 world
(integer) 2
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
2) world
redis 127.0.0.1:6379>
在此处我们先插入了一个hello,然后在hello的尾部插入了一个world。
2.4.3 linsert
在key对应list的特定位置之前或之后添加字符串元素
redis 127.0.0.1:6379> rpush mylist3 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist3 world
(integer) 2
redis 127.0.0.1:6379> linsert mylist3 before world there
(integer) 3
redis 127.0.0.1:6379> lrange mylist3 0 -1
1) hello
2) there
3) world
redis 127.0.0.1:6379>
在此处我们先插入了一个 hello,然后在 hello 的尾部插入了一个 world,然后又在 world 的
前面插入了there。
2.4.4 lset
设置list中指定下标的元素值(下标从0开始)
redis 127.0.0.1:6379> rpush mylist4 one
(integer) 1
redis 127.0.0.1:6379> rpush mylist4 two 《红丸出品》 http:weibo.comu2446082491
34 71
(integer) 2
redis 127.0.0.1:6379> rpush mylist4 three
(integer) 3
redis 127.0.0.1:6379> lset mylist4 0 four
OK
redis 127.0.0.1:6379> lset mylist4 -2 five
OK
redis 127.0.0.1:6379> lrange mylist4 0 -1
1) four
2) five
3) three
redis 127.0.0.1:6379>
在此处我们依次插入了 one,two,three,然后将标是0的值设置为four,再将下标是-2 的值设
置为five。
2.5.5 lrem
从key对应list中删除 count个和value相同的元素。
count>0 时,按从头到尾的顺序删除,具体如下:
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist5 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 4
redis 127.0.0.1:6379> lrem mylist5 2 hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) foo
2) hello
redis 127.0.0.1:6379>
count<0 时,按从尾到头的顺序删除,具体如下:
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist6 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 4 《红丸出品》 http:weibo.comu2446082491
35 71
redis 127.0.0.1:6379> lrem mylist6 -2 hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) hello
2) foo
redis 127.0.0.1:6379>
count=0 时,删除全部,具体如下:
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist7 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 4
redis 127.0.0.1:6379> lrem mylist7 0 hello
(integer) 3
redis 127.0.0.1:6379> lrange mylist7 0 -1
1) foo
redis 127.0.0.1:6379>
2.4.6 ltrim
保留指定key 的值范围内的数据
redis 127.0.0.1:6379> rpush mylist8 one
(integer) 1
redis 127.0.0.1:6379> rpush mylist8 two
(integer) 2
redis 127.0.0.1:6379> rpush mylist8 three
(integer) 3
redis 127.0.0.1:6379> rpush mylist8 four
(integer) 4
redis 127.0.0.1:6379> ltrim mylist8 1 -1
OK
redis 127.0.0.1:6379> lrange mylist8 0 -1
1) two
2) three
3) four
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
36 71
2.4.7 lpop
从list的头部删除元素,并返回删除元素
redis 127.0.0.1:6379> lrange mylist 0 -1
1) hello
2) world
redis 127.0.0.1:6379> lpop mylist
hello
redis 127.0.0.1:6379> lrange mylist 0 -1
1) world
redis 127.0.0.1:6379>
2.4.8 rpop
从list的尾部删除元素,并返回删除元素
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
2) world
redis 127.0.0.1:6379> rpop mylist2
world
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
redis 127.0.0.1:6379>
2.4.9 rpoplpush
从第一个list的尾部移除元素并添加到第二个 list的头部,最后返回被移除的元素值,整个操
作是原子的.如果第一个list是空或者不存在返回 nil
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
3) hello
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) hello
2) foo
redis 127.0.0.1:6379> rpoplpush mylist5 mylist6
hello
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
redis 127.0.0.1:6379> lrange mylist6 0 -1 《红丸出品》 http:weibo.comu2446082491
37 71
1) hello
2) hello
3) foo
redis 127.0.0.1:6379>
2.4.10 lindex
返回名称为key的 list中index位置的元素
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
redis 127.0.0.1:6379> lindex mylist5 0
three
redis 127.0.0.1:6379> lindex mylist5 1
foo
redis 127.0.0.1:6379>
2.4.11 llen
返回key 对应list的长度
redis 127.0.0.1:6379> llen mylist5
(integer) 2
redis 127.0.0.1:6379>
2.5 sets类型及操作
set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合
求交并差等操作,操作中key 理解为集合的名字。
Redis的set是 string类型的无序集合。set元素最大可以包含(2的 32次方)个元素。
set的是通过hash table 实现的,所以添加、删除和查找的复杂度都是 O(1)。hash table 会随
着添加或者删除自动的调整大小。需要注意的是调整 hash table大小时候需要同步(获取写
锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在 sorted
set 中使用了。关于 set 集合类型除了基本的添加删除操作,其他有用的操作还包含集合的
取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现 sns
中的好友推荐和 blog的tag功能。下面详细介绍 set相关命令:
2.5.1 sadd
向名称为key 的set中添加元素 《红丸出品》 http:weibo.comu2446082491
38 71
redis 127.0.0.1:6379> sadd myset hello
(integer) 1
redis 127.0.0.1:6379> sadd myset world
(integer) 1
redis 127.0.0.1:6379> sadd myset world
(integer) 0
redis 127.0.0.1:6379> smembers myset
1) world
2) hello
redis 127.0.0.1:6379>
本例中,我们向myset中添加了三个元素,但由于第三个元素跟第二个元素是相同的,所以
第三个元素没有添加成功,最后我们用smembers来查看myset中的所有元素。
2.5.2 srem
删除名称为key的 set中的元素member
redis 127.0.0.1:6379> sadd myset2 one
(integer) 1
redis 127.0.0.1:6379> sadd myset2 two
(integer) 1
redis 127.0.0.1:6379> sadd myset2 three
(integer) 1
redis 127.0.0.1:6379> srem myset2 one
(integer) 1
redis 127.0.0.1:6379> srem myset2 four
(integer) 0
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379>
本例中,我们向myset2中添加了三个元素后,再调用 srem来删除 one 和four,但由于元素
中没有four所以,此条 srem命令执行失败。
2.5.3 spop
随机返回并删除名称为 key 的set中一个元素
redis 127.0.0.1:6379> sadd myset3 one
(integer) 1
redis 127.0.0.1:6379> sadd myset3 two
(integer) 1
redis 127.0.0.1:6379> sadd myset3 three
(integer) 1 《红丸出品》 http:weibo.comu2446082491
39 71
redis 127.0.0.1:6379> spop myset3
three
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379>
本例中,我们向myset3中添加了三个元素后,再调用spop来随机删除一个元素,可以看到
three元素被删除了。
2.5.4 sdiff
返回所有给定key 与第一个key的差集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sdiff myset2 myset3
1) three
redis 127.0.0.1:6379>
本例中,我们可以看到 myset2中的元素与 myset3中不同的只是three,所以只有three被查
出来了,而不是 three和one,因为one 是 myset3的元素。
我们也可以将myset2和 myset3换个顺序来看一下结果:
redis 127.0.0.1:6379> sdiff myset3 myset2
1) one
redis 127.0.0.1:6379>
这个结果中只显示了,myset3中的元素与 myset2中不同的元素。
2.5.5 sdiffstore
返回所有给定key 与第一个key的差集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sdiffstore myset4 myset2 myset3
(integer) 1
redis 127.0.0.1:6379> smembers myset4 《红丸出品》 http:weibo.comu2446082491
40 71
1) three
redis 127.0.0.1:6379>
2.5.6 sinter
返回所有给定key 的交集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sinter myset2 myset3
1) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的交集two被查出来了
2.5.7 sinterstore
返回所有给定key 的交集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sinterstore myset5 myset2 myset3
(integer) 1
redis 127.0.0.1:6379> smembers myset5
1) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的交集被保存到myset5 中了
2.5.8 sunion
返回所有给定key 的并集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two 《红丸出品》 http:weibo.comu2446082491
41 71
2) one
redis 127.0.0.1:6379> sunion myset2 myset3
1) three
2) one
3) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的并集被查出来了
2.5.9 sunionstore
返回所有给定key 的并集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sunionstore myset6 myset2 myset3
(integer) 3
redis 127.0.0.1:6379> smembers myset6
1) three
2) one
3) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的并集被保存到myset6 中了
2.5.10 smove
从第一个key 对应的set中移除member 并添加到第二个对应set中
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> smove myset2 myset7 three
(integer) 1
redis 127.0.0.1:6379> smembers myset7
1) three
redis 127.0.0.1:6379>
通过本例可以看到,myset2 的three 被移到 myset7中了 《红丸出品》 http:weibo.comu2446082491
42 71
2.5.11 scard
返回名称为key的 set的元素个数
redis 127.0.0.1:6379> scard myset2
(integer) 1
redis 127.0.0.1:6379>
通过本例可以看到,myset2 的成员数量为1
2.5.12 sismember
测试member 是否是名称为 key的 set的元素
redis 127.0.0.1:6379> smembers myset2
1) two
redis 127.0.0.1:6379> sismember myset2 two
(integer) 1
redis 127.0.0.1:6379> sismember myset2 one
(integer) 0
redis 127.0.0.1:6379>
通过本例可以看到,two是myset2 的成员,而 one不是。
2.5.13 srandmember
随机返回名称为 key的set的一个元素,但是不删除元素
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> srandmember myset3
two
redis 127.0.0.1:6379> srandmember myset3
one
redis 127.0.0.1:6379>
2.6 sorted sets 类型及操作
sorted set是set的一个升级版本,它在 set的基础上增加了一个顺序属性,这一属性在添加
修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解为有
两列的mysql表,一列存value,一列存顺序。操作中 key理解为 zset的名字。
和 set 一样 sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double
类型的score。sorted set的实现是skip list和hash table 的混合体。
《红丸出品》 http:weibo.comu2446082491
43 71
当元素被添加到集合中时,一个元素到score 的映射被添加到hash table中,所以给定一个
元素获取score 的开销是 O(1),另一个score 到元素的映射被添加到 skip list,并按照score 排
序,所以就可以有序的获取集合中的元素。添加,删除操作开销都是 O(log(N))和 skip list的
开销一致,redis的 skip list实现用的是双向链表,这样就可以逆序从尾部取元素。sorted set最
经常的使用方式应该是作为索引来使用.我们可以把要排序的字段作为 score 存储,对象的 id
当元素存储。下面是 sorted set相关命令
2.6.1 zadd
向名称为 key 的 zset 中添加元素 member,score 用于排序。如果该元素已经存在,则根据
score 更新该元素的顺序
redis 127.0.0.1:6379> zadd myzset 1 one
(integer) 1
redis 127.0.0.1:6379> zadd myzset 2 two
(integer) 1
redis 127.0.0.1:6379> zadd myzset 3 two
(integer) 0
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
3) two
4) 3
redis 127.0.0.1:6379>
本例中我们向 myzset 中添加了 one 和 two,并且 two 被设置了 2 次,那么将以最后一次的
设置为准,最后我们将所有元素都显示出来并显示出了元素的score。
2.6.2 zrem
删除名称为key的 zset中的元素member
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
3) two
4) 3
redis 127.0.0.1:6379> zrem myzset two
(integer) 1
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
redis 127.0.0.1:6379>
可以看到two被删除了 《红丸出品》 http:weibo.comu2446082491
44 71
2.6.3 zincrby
如果在名称为key 的zset中已经存在元素 member,则该元素的score增加 increment;否则
向集合中添加该元素,其 score 的值为increment
redis 127.0.0.1:6379> zadd myzset2 1 one
(integer) 1
redis 127.0.0.1:6379> zadd myzset2 2 two
(integer) 1
redis 127.0.0.1:6379> zincrby myzset2 2 one
3
redis 127.0.0.1:6379> zrange myzset2 0 -1 withscores
1) two
2) 2
3) one
4) 3
redis 127.0.0.1:6379>
本例中将one 的 score 从1 增加了2,增加到了 3
2.6.4 zrank
返回名称为key的 zset中member 元素的排名(按 score从小到大排序)即下标
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrank myzset3 two
(integer) 1
redis 127.0.0.1:6379>
本例中将two的下标是1,我这里取的是下标,而不是 score
2.6.5 zrevrank
返回名称为key的 zset中member 元素的排名(按 score从大到小排序)即下标
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1 《红丸出品》 http:weibo.comu2446082491
45 71
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrevrank myzset3 two
(integer) 2
redis 127.0.0.1:6379>
按从大到小排序的话 two是第三个元素,下标是2
2.6.6 zrevrange
返回名称为key的 zset(按score从大到小排序)中的index从 start到 end的所有元素
redis 127.0.0.1:6379> zrevrange myzset3 0 -1 withscores
1) five
2) 5
3) three
4) 3
5) two
6) 2
7) one
8) 1
redis 127.0.0.1:6379>
首先按score从大到小排序,再取出全部元素
2.6.7 zrangebyscore
返回集合中score在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrangebyscore myzset3 2 3 withscores
1) two
2) 2
3) three 《红丸出品》 http:weibo.comu2446082491
46 71
4) 3
redis 127.0.0.1:6379>
本例中,返回了 score在2~3区间的元素
2.6.8 zcount
返回集合中score在给定区间的数量
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zcount myzset3 2 3
(integer) 2
redis 127.0.0.1:6379>
本例中,计算了 score在2~3之间的元素数目
2.6.9 zcard
返回集合中元素个数
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zcard myzset3
(integer) 4
redis 127.0.0.1:6379>
从本例看出myzset3 这个集全的元素数量是4
2.6.10 zscore
返回给定元素对应的 score 《红丸出品》 http:weibo.comu2446082491
47 71
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zscore myzset3 two
2
redis 127.0.0.1:6379>
此例中我们成功的将 two的score取出来了。
2.6.11 zremrangebyrank
删除集合中排名在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zremrangebyrank myzset3 3 3
(integer) 1
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
redis 127.0.0.1:6379>
在本例中我们将 myzset3中按从小到大排序结果的下标为3的元素删除了。
2.6.12 zremrangebyscore
删除集合中score在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores 《红丸出品》 http:weibo.comu2446082491
48 71
1) one
2) 1
3) two
4) 2
5) three
6) 3
redis 127.0.0.1:6379> zremrangebyscore myzset3 1 2
(integer) 2
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) three
2) 3
redis 127.0.0.1:6379>
在本例中我们将 myzset3中按从小到大排序结果的 score 在1~2之间的元素删除了。
第三章、Redis 常用命令
Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些 command
可以在Linux终端使用。在编程时,比如各类语言包,这些命令都有对应的方法。下面将 Redis
提供的命令做一总结。
3.1 键值相关命令
3.1.1 keys
返回满足给定pattern 的所有key
redis 127.0.0.1:6379> keys
1) myzset2
2) myzset3
3) mylist
4) myset2
5) myset3
6) myset4
7) k_zs_1
8) myset5
9) myset6
10) myset7
11) myhash
12) myzset
13) age 《红丸出品》 http:weibo.comu2446082491
49 71
14) myset
15) mylist5
16) mylist6
17) mylist7
18) mylist8
用表达式,代表取出所有的 key
redis 127.0.0.1:6379> keys mylist
1) mylist
2) mylist5
3) mylist6
4) mylist7
5) mylist8
redis 127.0.0.1:6379>
用表达式mylist,代表取出所有以mylist开头的key
3.1.2 exists
确认一个key 是否存在
redis 127.0.0.1:6379> exists HongWan
(integer) 0
redis 127.0.0.1:6379> exists age
(integer) 1
redis 127.0.0.1:6379>
从结果来数据库中不存在HongWan这个 key,但是age 这个key 是存在的
3.1.3 del
删除 ......
《红丸出品》 http:weibo.comu2446082491
2 71
第一章 Redis快速入门 7
1.1 Key-Value 存储系统简介 ................................................................................................ 7
1.1.1 Voldemort ................................................................................................................. 8
1.1.2 Dynamo .................................................................................................................... 8
1.1.3 memcachedb ............................................................................................................ 9
1.1.4 Cassandra ................................................................................................................. 9
1.1.5 memcached ............................................................................................................ 10
1.1.6 Hypertable .............................................................................................................. 10
1.2 为什么选择 Key-Value Store ....................................................................................... 11
1.2.1 大规模的互联网应用 ........................................................................................... 11
1.2.2 云存储 ................................................................................................................... 11
1.2.3 Redis实际应用案例 .............................................................................................. 12
1.3 初识Redis .................................................................................................................... 14
1.3.1 数据类型 ............................................................................................................... 14
1.3.2 持久化 ................................................................................................................... 14
1.3.3 主从同步 ............................................................................................................... 14
1.3.4 性能 ....................................................................................................................... 15
1.3.5 提供API 的语言 .................................................................................................... 15
1.3.6 适用场合 ............................................................................................................... 15
1.4 快速入门 ...................................................................................................................... 17
1.4.1 安装Redis ............................................................................................................. 17
1.4.2 配置Redis ............................................................................................................. 18
1.4.3 操作数据库 ........................................................................................................... 21
第二章 Redis数据类型及操作 ............................................................................................. 22
2.1 前言 .............................................................................................................................. 22
2.2 strings 类型及操作 .................................................................................................. 23
2.2.1 set ........................................................................................................................... 23
2.2.2 setnx ....................................................................................................................... 23
2.2.3 setex ....................................................................................................................... 24
2.2.4 setrange .................................................................................................................. 24 《红丸出品》 http:weibo.comu2446082491
3 71
2.2.5 mset ........................................................................................................................ 24
2.2.6 msetnx .................................................................................................................... 25
2.2.7 get ........................................................................................................................... 25
2.2.8 getset ...................................................................................................................... 25
2.2.9 getrange.................................................................................................................. 26
2.2.10 mget ...................................................................................................................... 26
2.2.11 incr ........................................................................................................................ 27
2.2.12 incrby .................................................................................................................... 27
2.2.13 decr ....................................................................................................................... 27
2.2.14 decrby ................................................................................................................... 27
2.2.15 append .................................................................................................................. 28
2.2.16 strlen ..................................................................................................................... 28
2.3 hashes 类型及操作 .................................................................................................. 29
2.3.1 hset ......................................................................................................................... 29
2.3.2 hsetnx ..................................................................................................................... 29
2.3.3 hmset ...................................................................................................................... 29
2.3.4 hget ......................................................................................................................... 30
2.3.5 hmget...................................................................................................................... 30
2.3.6 hincrby .................................................................................................................... 30
2.3.7 hexists ..................................................................................................................... 30
2.3.8 hlen ......................................................................................................................... 31
2.3.9 hdel ......................................................................................................................... 31
2.3.10 hkeys ..................................................................................................................... 31
2.3.11 hvals ...................................................................................................................... 31
2.3.12 hgetall ................................................................................................................... 32
2.4 lists 类型及操作 ...................................................................................................... 32
2.4.1 lpush ....................................................................................................................... 32
2.4.2 rpush ....................................................................................................................... 33
2.4.3 linsert ...................................................................................................................... 33
2.4.4 lset .......................................................................................................................... 33 《红丸出品》 http:weibo.comu2446082491
4 71
2.5.5 lrem......................................................................................................................... 34
2.4.6 ltrim ........................................................................................................................ 35
2.4.7 lpop ......................................................................................................................... 36
2.4.8 rpop ........................................................................................................................ 36
2.4.9 rpoplpush ................................................................................................................ 36
2.4.10 lindex .................................................................................................................... 37
2.4.11 llen ........................................................................................................................ 37
2.5 sets 类型及操作 ...................................................................................................... 37
2.5.1 sadd ........................................................................................................................ 37
2.5.2 srem ........................................................................................................................ 38
2.5.3 spop ........................................................................................................................ 38
2.5.4 sdiff ......................................................................................................................... 39
2.5.5 sdiffstore ................................................................................................................. 39
2.5.6 sinter ....................................................................................................................... 40
2.5.7 sinterstore .............................................................................................................. 40
2.5.8 sunion ..................................................................................................................... 40
2.5.9 sunionstore ............................................................................................................. 41
2.5.10 smove ................................................................................................................... 41
2.5.11 scard ..................................................................................................................... 42
2.5.12 sismember ............................................................................................................ 42
2.5.13 srandmember ....................................................................................................... 42
2.6 sorted sets 类型及操作 ........................................................................................... 42
2.6.1 zadd ........................................................................................................................ 43
2.6.2 zrem ........................................................................................................................ 43
2.6.3 zincrby .................................................................................................................... 44
2.6.4 zrank ....................................................................................................................... 44
2.6.5 zrevrank .................................................................................................................. 44
2.6.6 zrevrange ................................................................................................................ 45
2.6.7 zrangebyscore......................................................................................................... 45
2.6.8 zcount ..................................................................................................................... 46 《红丸出品》 http:weibo.comu2446082491
5 71
2.6.9 zcard ....................................................................................................................... 46
2.6.10 zscore .................................................................................................................... 46
2.6.11 zremrangebyrank ................................................................................................. 47
2.6.12 zremrangebyscore ................................................................................................ 47
第三章、Redis常用命令 ....................................................................................................... 48
3.1 键值相关命令 .......................................................................................................... 48
3.1.1 keys ......................................................................................................................... 48
3.1.2 exists ....................................................................................................................... 49
3.1.3 del ........................................................................................................................... 49
3.1.4 expire ...................................................................................................................... 49
3.1.5 move ....................................................................................................................... 50
3.1.6 persist ..................................................................................................................... 50
3.1.7 randomkey .............................................................................................................. 51
3.1.8 rename ................................................................................................................... 51
3.1.9 type ......................................................................................................................... 51
3.2 服务器相关命令 ........................................................................................................... 52
3.2.1 ping ......................................................................................................................... 52
3.2.2 echo ........................................................................................................................ 52
3.2.3 select....................................................................................................................... 52
3.2.4 quit .......................................................................................................................... 52
3.2.5 dbsize ...................................................................................................................... 53
3.2.6 info .......................................................................................................................... 53
3.2.7 monitor ................................................................................................................... 53
3.2.8 config get ................................................................................................................ 53
3.2.9 flushdb .................................................................................................................... 54
3.2.10 flushall .................................................................................................................. 54
第四章 Redis高级实用特性 ................................................................................................. 54
4.1 安全性 .......................................................................................................................... 54
4.2 主从复制 ...................................................................................................................... 55
4.2.1 redis 主从复制特点: .............................................................................................. 55 《红丸出品》 http:weibo.comu2446082491
6 71
4.2.2 redis 主从复制过程: .............................................................................................. 55
4.2.3 如何配置 ............................................................................................................... 56
4.3 事务控制 ...................................................................................................................... 58
4.3.1 简单事务控制 ....................................................................................................... 58
4.3.2 如何取消一个事务 ............................................................................................... 58
4.3.3 乐观锁复杂事务控制 ........................................................................................... 59
4.4 持久化机制 .................................................................................................................. 61
4.4.1 snapshotting方式 .................................................................................................. 61
4.4.2 aof方式 .................................................................................................................. 63
4.5 发布及订阅消息 ........................................................................................................... 66
4.6 Pipeline批量发送请求 ................................................................................................. 67
4.7 虚拟内存的使用 .......................................................................................................... 70
《红丸出品》 http:weibo.comu2446082491
7 71
第一章 Redis 快速入门
Redis是一个Key-Value 存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持 pushpop、addremove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础
上,Redis支持各种不同方式的排序。与 memcached一样,为了保证效率,数据都是缓存在
内存中。区别的是 Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录
文件,并且在此基础上实现了 master-slave(主从)同步。
1.1 Key-Value 存储系统简介
Key-Value Store 是当下比较流行的话题,尤其在构建诸如搜索引擎、IM、P2P、游戏服务器、SNS等大型互联网应用以及提供云计算服务的时候,怎样保证系统在海量数据环境下的高性
能、高可靠性、高扩展性、高可用性、低成本成为所有系统架构们挖苦心思考虑的重点,而
怎样解决数据库服务器的性能瓶颈是最大的挑战。
按照分布式领域的CAP理论(Consistency、 Availability、Tolerance to network Partitions这三
部分在任何系统架构实现时只可能同时满足其中二点,没法三者兼顾)来衡量,传统的关系
数据库的ACID只满足了 Consistency、 Availability,因此在Partition tolerance上就很难做得好。
另外传统的关系数据库处理海量数据、分布式架构时候在 Performance、Scalability、Availability 等方面也存在很大的局限性。
而Key-Value Store 更加注重对海量数据存取的性能、分布式、扩展性支持上,并不需要传统
关系数据库的一些特征,例如:Schema、事务、完整 SQL 查询支持等等,因此在分布式环
境下的性能相对于传统的关系数据库有较大的提升。
Key-Value数据库分为很多种类,具体如下图: 《红丸出品》 http:weibo.comu2446082491
8 71
这些 Key-Value 数据库,有的是用 CC++编写的,有的是用 Java 编写的,还有的是用 Erlang
编写的,每个都有自己的独到之处,我们从中挑选一些比较有特色且应用广泛的产品学习和
了解一下。
1.1.1 Voldemort
Voldemort是一个分布式 KeyValue存储系统,它具有以下特点:
· 数据自动在多个服务器之间复制;
· 数据自动分区,因此每个服务器只包括整体数据的一个子集;
· 服务器故障处理是透明的;
· 支持插入式序列化,允许丰富的 Key和 Value 类型,包括列表和元组,也可以集成常见
的序列化框架,如 Protocol Buffers,Thrift,Avro和 Java Serialization
· 数据项支持版本化,即使在故障情况下,数据完整性也可以得到保障;
· 每个节点都是独立的,无需其他节点协调,因此也没有中央节点;
· 单节点性能优秀:根据机器配置、网络、磁盘系统和数据复制因素的不同,每秒可以执
行 10-20k操作;
· 支持地理分散式部署。
1.1.2 Dynamo
Dynamo是亚马逊的 key-value模式的存储平台,可用性和扩展性都很好,性能也不错:读写
访问中99.9%的响应时间都在300ms内。 《红丸出品》 http:weibo.comu2446082491
9 71
接下来对 Dynamo 需要的一些特性做一下简要的描述:
· Cost-effectiveness - 省钱!Dynamo 不像一些商用数据库产品,需要昂贵的服务器来得
到良好的性能,而且可能增加5%的访问量会需要你花2 万美刀去买一台新服务器。而
在 Dynamo 上,由于是利用一堆廉价机器来存数据,于是你可能只需要花个 500 刀买
个破机器加入到集群里就行了。
· Dynamo 是一个 Key-Value 存储 - 因此他不支持外键和关联查询什么的。其 Value值是
二进制存储的,所以查询条件也只能作用在 Key 上。
· 配置简单的分布式存储 - 这是由于 Dynamo 是去中心化地设计,在集群中它的每一台
机器都是对等的,不像 MongoDB 这样的中心化设计,于是它也不会有单点问题。
1.1.3 memcachedb
memcachedb是 一个由新浪网的开发人员开放出来的开源项目,给 memcached分布式缓存
服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制,让 memcached具备了事
务恢复能力、持久化能力和分布式复制能力,非常适合于需要超高性能读写速度,但是 不
需要严格事务约束,能够被持久化保存的应用场景,例如 memcachedb 被应用在新浪博客上
面。
1.1.4 Cassandra
Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由 Facebook开发,用于储
存特别大的数据。Facebook目前在使用此系统。
主要特性:
· 分布式
· 基于column 的结构化
· 高伸展性
Cassandra 的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布
式网络服务,对 Cassandra 的一个写操作,会被复制到其他节点上去,对 Cassandra 的读操
作,也会被路由到某个节点上面去读取。对于一个 Cassandra 群集来说,扩展性能 是比较
简单的事情,只管在群集里面添加节点就可以了。
Cassandra 是一个混合型的非关系的数据库,类似于 Google 的 BigTable。其主要功能比
Dynomite(分布式的Key-Value存 储系统)更丰富,但支持度却不如文档存储MongoDB(介
于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系
数据库 的。支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂
的数据类型。)Cassandra 最初由 Facebook 开发,后转变成了开源项目。它是一个网络社交
云计算方面理想的数据库。以 Amazon专有的完全分布式的 Dynamo为基础,结合了Google
BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称
之为Dynamo 2.0。
《红丸出品》 http:weibo.comu2446082491
10 71
和其他数据库比较,有几个突出特点:
· 模式灵活 :使用 Cassandra,像文档存储,你不必提前解决记录中的字段。你可以在系
统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型部 署上。
· 真正的可扩展性 :Cassandra是纯粹意义上的水平扩展。为给集群添加更多容量,可以
指向另一台电脑。你不必重启任何进程,改变应用查询,或手动迁移任何数据。
· 多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一个备用的
数据中心将至少有每条记录的完全复制。
· 范围查询 :如果你不喜欢全部的键值查询,则可以设置键的范围来查询。
· 列表数据结构 :在混合模式可以将超级列添加到 5 维。对于每个用户的索引,这是非
常方便的。
· 分布式写操作 :有可以在任何地方任何时间集中读或写任何数据。并且不会有任何单
点失败。
1.1.5 memcached
memcached是一套分布式的快取系统,当初是 Danga Interactive为了 LiveJournal所发展的,但目前被许多软件(如 MediaWiki)所使用。这是一套开放源代码软件,以BSD license授权
释出。
memcached缺乏认证以及安全管制,这代表应该将memcached服务器放置在防火墙后。
memcached的 API使用三十二位元的循环冗余校验(CRC-32)计算键值后,将资料分散在不
同的机器上。当表格满了以后,接下来新增的资料会以 LRU 机制替换掉。由于 memcached
通常只是当作快取系统使用,所以使用 memcached 的应用程式在写回较慢的系统时(像是
后端的数据库)需要额外的程式码更新memcached内的资料。
memcached具有多种语言的客户端开发包,包括:PerlPHPJAVACPythonRubyCMySQL
1.1.6 Hypertable
Hypertable是一个开源、高性能、可伸缩的数据库,它采用与 Google的Bigtable相似的模型。
在过去数年中,Google 为在 PC 集群 上运行的可伸缩计算基础设施设计建造了三个关键部
分。第一个关键的基础设施是Google File System(GFS),这是一个高可用的文件系统,提供
了一个全局的命名空间。它通过跨机器(和跨机架)的文件数据复制来达到高可用性,并因
此免受传统 文件存储系统无法避免的许多失败的影响,比如电源、内存和网络端口等失败。
第二个基础设施是名为 Map-Reduce 的计算框架,它与 GFS 紧密协作,帮 助处理收集到的
海量数据。第三个基础设施是 Bigtable,它是传统数据库的替代。Bigtable 让你可以通过一
些主键来组织海量数据,并实现高效的 查询。Hypertable 是Bigtable的一个开源实现,并且
根据我们的想法进行了一些改进。 《红丸出品》 http:weibo.comu2446082491
11 71
1.2 为什么选择 Key-Value Store
大量的互联网用户选择 Key-Value Store 的原因具体是什么呢? 主要分为下面的 2个主要原
因:
1.2.1 大规模的互联网应用
对于 google,ebay 这样的互联网企业,每时每刻都有无数的用户在使用它们提供的互联网
服务,这些服务带来的就是大量的数据吞吐量,在同一时间,会并发的有成千上万的连接对
数据库进行操作。在这种情况下,单台服务器或者几台服务器远远不能满足这些数据处理的
需求,简单的升级服务器性能这样的scale up的方式也不行,所以唯一可以采用的办法就是
scale out了。scale out的方法有很多种,但大致分为两类:一类仍然采用 RDBMS,然后通过
对数据库的垂直和水平切割将整个数据库部署到一个集群上,这种方法的优点在于可以采用
RDBMS 这种熟悉的技术,但缺点在于它是针对特定应用的,就是说,由于应用的不同,切
割的方法是不一样的。
还有一类就是google 所采用的方法,抛弃 RDBMS,采用key-value 形式的存储,这样可 以
极大的增强系统的可扩展性(scalability),如果要处理的数据持续增大,多加机器就 可
以了。事实上,key-value的存储就是由于 BigTable等相关论文的发表慢慢进入人们的 视
野的。
1.2.2 云存储
如果说上一个问题还有可以替代的解决方案(切割数据库)的话,那么对于云存储来说,也
许key-value的store就是唯一的解决方案了。云存储简单点说就是构建一个大型的存储平台
给别人用,这也就意味着在这上面运行的应用其实是不可控的。如果其中某个客户的应用随
着用户的增长而不断增长时,云存储供应商是没有办法通过数据库的切割来达到 scale 的,因为这个数据是客户的,供应商不了解这个数据自然就没法作出切割。在这种情况下,key-value 的 store 就是唯一的选择了,因为这种条件下的 scalability 必须是自动完成的,不
能有人工干预。这也是为什么几乎所有的现有的云存储都是key-value 形式的,例如Amazon
的smipleDB,底层实现就是 key-value,还有 google的 GoogleAppEngine,采用的是BigTable
的存储形式。也许唯一可能例外的是 MS 的解决方案,我在 Qcon 大会上听说 MS 的 Azure
平台的下一个版本中就会推出基于RDBMS的云存储,尽管我本人仍然对此保持怀疑。
Key-Value Store 最大的特点就是它的可扩展性,这也就是它最大的优势。所谓的可扩展性,在我看来这里包括了两方面内容。一方面,是指 Key-Value Store可以支持极大的数据的存储,它的分布式的架构决定了只要有更多的机器,就能够保证存储更多的数据。另一方面,是指
它可以支持数量很多的并发的查询。对于 RDBMS,一般几百个并发的查询就可以让它很吃
力了,而一个Key-Value Store,可以很轻松的支持上千的并发查询。下面而简单的罗列了一
些特点:
· Key-value store:一个 key-value 数据存储系统,只支持一些基本操作,如: SET(key, value) 《红丸出品》 http:weibo.comu2446082491
12 71
和 GET(key) 等;
· 分布式:多台机器(nodes)同时存储数据和状态,彼此交换消息来保持数据一致,可
视为一个完整的存储系统。
· 数据一致:所有机器上的数据都是同步更新的、不用担心得到不一致的结果;
· 冗余:所有机器(nodes)保存相同的数据,整个系统的存储能力取决于单台机器(node)
的能力;
· 容错:如果有少数 nodes 出错,比如重启、当机、断网、网络丢包等各种 faultfail 都
不影响整个系统的运行;
· 高可靠性:容错、冗余等保证了数据库系统的可靠性。
1.2.3 Redis 实际应用案例
目前全球最大的 Redis 用户是新浪微博,在新浪有 200 多台物理机,400 多个端口正在运行
着Redis, 有+4G 的数据跑在 Redis上来为微博用户提供服务。
在新浪微博Redis的部署场景很多,大概分为如下的2 种:
第一种是应用程序直接访问 Redis数据库 《红丸出品》 http:weibo.comu2446082491
13 71
第二种是应用程序直接访问 Redis,只有当 Redis访问失败时才访问 MySQL
同时,Digg的一项新功能,添加了对文章浏览数的显示,这一功能的一大卖点是其实时性。 《红丸出品》 http:weibo.comu2446082491
14 71
而支持此实时浏览量计数的,正是 Redis。
1.3 初识 Redis
Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起, Redis的开发工作由VMware
主持。
1.3.1 数据类型
作为 Key-value 型数据库,Redis 也提供了键(Key)和键值(Value)的映射关系。但是,除
了常规的数值或字符串,Redis的键值还可以是以下形式之一:
· Lists (列表)
· Sets (集合)
· Sorted sets (有序集合)
· Hashes (哈希表)
键值的数据类型决定了该键值支持的操作。Redis 支持诸如列表、集合或有序集合的交集、并集、查集等高级原子操作;同时,如果键值的类型是普通数字,Redis 则提供自增等原子
操作。
1.3.2 持久化
通常,Redis 将数据存储于内存中,或被配置为使用虚拟内存。通过两种方式可以实现数据
持久化:使用截图的方式,将内存中的数据不断写入磁盘;或使用类似 MySQL 的日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
1.3.3 主从同步
Redis支持将数据同步到多台从库上,这种特性对提高读取性能非常有益。 《红丸出品》 http:weibo.comu2446082491
15 71
1.3.4 性能
相比需要依赖磁盘记录每个更新的数据库,基于内存的特性无疑给 Redis带来了非常优秀的
性能。读写操作之间有显著的性能差异。
1.3.5 提供 API的语言
· C
· C++
· C
· Clojure
· Common Lisp
· Erlang
· Haskell
· Java
· Javascript
· Lua
· Objective-C
· Perl
· PHP
· Python
· Ruby
· Scala
· Go
· Tcl
1.3.6 适用场合
毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数
据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用 Redis灵活多变的数据结
构和数据操作,为不同的大象构建不同的冰箱。希望你喜欢这个比喻。
下面是Redis适用的一些场景:
1、取最新 N 个数据的操作
比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的 5000条评论的ID放在
Redis的List集合中,并将超出集合部分从数据库获取。
使用LPUSH latest.comments
插入完成后再用 LTRIM latest.comments 0 5000 命令使其永远只保存最近5000个 ID
然后我们在客户端获取某一页评论时可以用下面的逻辑
FUNCTION get_latest_comments(start,num_items): 《红丸出品》 http:weibo.comu2446082491
16 71
id_list = redis.lrange(latest.comments,start,start+num_items-1)
IF id_list.length < num_items
id_list = SQL_DB(SELECT ... ORDER BY time LIMIT ...)
END
RETURN id_list
END
如果你还有不同的筛选维度,比如某个分类的最新 N 条,那么你可以再建一个按此分类的
List,只存ID的话,Redis是非常高效的。
2、排行榜应用,取 TOP N 操作
这个需求与上面需求的不同之处在于,前面操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的 sorted set出马了,将你要排序的值设置成 sorted
set的score,将具体的数据设置成相应的 value,每次只需要执行一条ZADD命令即可。
3、需要精准设定过期时间的应用
比如你可以把上面说到的 sorted set 的 score 值设置成过期时间的时间戳,那么就可以简单
地通过过期时间排序,定时清除过期数据了,不仅是清除 Redis中的过期数据,你完全可以
把 Redis 里这个过期时间当成是对数据库中数据的索引,用 Redis 来找出哪些数据需要过期
删除,然后再精准地从数据库中删除相应的记录。
4、计数器应用
Redis的命令都是原子性的,你可以轻松地利用 INCR,DECR 命令来构建计数器系统。
5、Uniq 操作,获取某段时间所有数据排重值
这个使用Redis的 set数据结构最合适了,只需要不断地将数据往 set中扔就行了,set意为
集合,所以会自动排重。
6、实时系统,反垃圾系统
通过上面说到的 set功能,你可以知道一个终端用户是否进行了某个操作,可以找到其操作
的集合并进行分析统计对比等。没有做不到,只有想不到。
7、PubSub 构建实时消息系统
Redis 的 PubSub 系统可以构建实时的消息系统,比如很多用 PubSub 构建的实时聊天系统
的例子。
8、构建队列系统
使用list可以构建队列系统,使用 sorted set甚至可以构建有优先级的队列系统。
9、缓存
这个不必说了,性能优于Memcached,数据结构更多样化。 《红丸出品》 http:weibo.comu2446082491
17 71
1.4 快速入门
1.4.1 安装 Redis
Redis的官方下载站是 http:redis.iodownload,可以去上面下载最新的安装程序下来,我写
此文章时的的稳定版本是2.2.12。
怎么安装 Redis数据库呢?下面将介绍 Linux版本的安装方法
步骤一: 下载Redis
下载安装包:wget http:redis.googlecode.comfilesredis-2.2.12.tar.gz
[root@localhost 4setup] wget http:redis.googlecode.comfilesredis-2.2.12.tar.gz--19:06:56-- http:redis.googlecode.comfilesredis-2.2.12.tar.gz
正在解析主机 redis.googlecode.com... 74.125.71.82
Connecting to redis.googlecode.com|74.125.71.82|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:455240 (445K) [applicationx-gzip]
Saving to: `redis-2.2.12.tar.gz'
100%[==========================================>] 455,240 34.8Ks in 13s
19:07:16 (34.8 KBs) - `redis-2.2.12.tar.gz' saved [455240455240]
[root@localhost 4setup]
步骤二: 编译源程序
[root@localhost 4setup] ll
总计 29168
-rw-r--r-- 1 root root 455240 2011-07-22 redis-2.2.12.tar.gz
[root@localhost 4setup] tar xzf redis-2.2.12.tar.gz
[root@localhost 4setup] cd redis-2.2.12
[root@localhost redis-2.2.12] make
cd src make all
make[1]: Entering directory `root4setupredis-2.2.12src'
步骤三: 启动Redis服务 《红丸出品》 http:weibo.comu2446082491
18 71
srcredis-server
[root@localhost redis-2.2.12] srcredis-server
[6246] 05 Aug 19:17:22 Warning: no config file specified, using the default config. In order to
specify a config file use 'redis-server pathtoredis.conf'
[6246] 05 Aug 19:17:22 Server started, Redis version 2.2.12
[6246] 05 Aug 19:17:22 WARNING overcommit_memory is set to 0! Background save may fail
under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to
etcsysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this
to take effect.
[6246] 05 Aug 19:17:22 The server is now ready to accept connections on port 6379
[6246] 05 Aug 19:17:22 - 0 clients connected (0 slaves), 539544 bytes in use
Redis 服务端的默认连接端口是 6379
步骤四: 将Redis作为 Linux 服务随机启动
vi etcrc.local, 使用 vi编辑器打开随机启动配置文件,并在其中加入下面一行代码
root4setupredis-2.2.12srcredis-server
步骤五: 客户端连接验证
新打开一个 Session 输入:srcredis-cli,如果出现下面提示,那么您就可以开始 Redis 之
旅了
[root@localhost redis-2.2.12] srcredis-cli
redis 127.0.0.1:6379>
步骤六: 查看Redis日志
查看服务器端 session,即可对Redis的运行状况进行查看或分析了
[6246] 05 Aug 19:24:33 - 0 clients connected (0 slaves), 539544 bytes in use
[6246] 05 Aug 19:24:37 - Accepted 127.0.0.1:51381
[6246] 05 Aug 19:24:38 - 1 clients connected (0 slaves), 547372 bytes in use
以上的几个步骤就OK了!!这样一个简单的Redis数据库就可以畅通无阻地运行起来了。
步骤七: 停止Redis实例
最简单的方法是在启动实例的 session中,直接使用Control-C来将实例停止。
我们还可以用客户端来停止服务,如可以用 shutdown来停止 Redis实例, 具体如下:
[root@localhost redis-2.2.12] srcredis-cli shutdown
1.4.2 配置 Redis
如果是一个专业的 DBA,那么实例启动时会加很多的参数以便使系统运行的非常稳定,这样
就可能会在启动时在 Redis后面加一个参数,以指定配置文件的路径,就象 mysql一样的读
取启动配置文件的方式来启动数据库。源码编译完成后,在 redis-2.2.12 目录下有一个
redis.conf 文件,这个文件即是 Redis的配置文件,用配置文件来启动 Redis的方法如下: 《红丸出品》 http:weibo.comu2446082491
19 71
[root@localhost redis-2.2.12] srcredis-server redis.conf
[6353] 05 Aug 19:36:45 Server started, Redis version 2.2.12
[6353] 05 Aug 19:36:45 WARNING overcommit_memory is set to 0! Background save may fail
under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to
etcsysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this
to take effect.
[6353] 05 Aug 19:36:45 The server is now ready to accept connections on port 6379
[6353] 05 Aug 19:36:45 - 0 clients connected (0 slaves), 539540 bytes in use
Redis支持很多的参数,但都有默认值。
· daemonize:
默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
· pidfile
当 Redis 在后台运行的时候,Redis 默认会把 pid 文件放在varrunredis.pid,你可以配
置到其他地址。当运行多个 redis服务时,需要指定不同的pid 文件和端口
· bind
指定Redis只接收来自于该 IP地址的请求,如果不进行设置,那么将处理所有请求,在
生产环境中最好设置该项
· port
监听端口,默认为6379
· timeout
设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接
· loglevel
log等级分为4 级,debug, verbose, notice, 和warning。生产环境下一般开启 notice
· logfile
配置log文件地址,默认使用标准输出,即打印在命令行终端的窗口上
· databases
设置数据库的个数,可以使用 SELECT
· save
设置Redis进行数据库镜像的频率。
if(在60 秒之内有 10000个keys发生变化时){
进行镜像备份
}else if(在300 秒之内有10个keys发生了变化){
进行镜像备份
}else if(在900 秒之内有1个keys发生了变化){
进行镜像备份
}
· rdbcompression
在进行镜像备份时,是否进行压缩
· dbfilename
镜像备份文件的文件名
· dir
数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为Redis在进 《红丸出品》 http:weibo.comu2446082491
20 71
行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,再把该该
临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放
在这个指定的路径当中
· slaveof
设置该数据库为其他数据库的从数据库
· masterauth
当主数据库连接需要密码验证时,在这里指定
· requirepass
设置客户端连接后进行任何其他指定前需要使用的密码。警告:因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K 次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解。
· maxclients
限制同时连接的客户数量。当连接数超过这个值时,redis 将不再接收其他连接请求,客户端尝试连接时将收到error信息。
· maxmemory
设置 redis 能够使用的最大内存。当内存满了的时候,如果还接收到 set 命令,redis 将
先尝试剔除设置过expire信息的key,而不管该 key的过期时间还没有到达。在删除时,将按照过期时间进行删除,最早将要被过期的 key将最先被删除。如果带有expire信息
的 key都删光了,那么将返回错误。这样,redis将不再接收写请求,只接收get请求。
maxmemory的设置比较适合于把redis当作于类似memcached的缓存来使用。
· appendonly
默认情况下,redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时
的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较
大范围的数据丢失。所以 redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
开启 append only 模式之后,redis 会把所接收到的每一次写操作请求都追加到
appendonly.aof 文件中,当redis重新启动时,会从该文件恢复出之前的状态。但是这样
会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对
appendonly.aof 进行重新整理。所以我认为推荐生产环境下的做法为关闭镜像,开启
appendonly.aof,同时可以选择在访问较少的时间每天对appendonly.aof 进行重写一次。
· appendfsync
设置对 appendonly.aof 文件进行同步的频率。always 表示每次有写操作都进行同步,everysec表示对写操作进行累积,每秒同步一次。这个需要根据实际业务场景进行配置
· vm-enabled
是否开启虚拟内存支持。因为 redis 是一个内存数据库,而且当内存满的时候,无法接
收新的写请求,所以在redis 2.0中,提供了虚拟内存的支持。但是需要注意的是,redis
中,所有的 key都会放在内存中,在内存不够时,只会把value值放入交换区。这样保
证了虽然使用虚拟内存,但性能基本不受影响,同时,你需要注意的是你要把
vm-max-memory 设置到足够来放下你的所有的key
· vm-swap-file
设置虚拟内存的交换文件路径
· vm-max-memory
这里设置开启虚拟内存之后,redis 将使用的最大物理内存的大小。默认为 0,redis 将
把他所有的能放到交换文件的都放到交换文件中,以尽量少的使用物理内存。在生产环
境下,需要根据实际情况设置该值,最好不要使用默认的 0 《红丸出品》 http:weibo.comu2446082491
21 71
· vm-page-size
设置虚拟内存的页大小,如果你的 value 值比较大,比如说你要在 value 中放置博客、新闻之类的所有文章内容,就设大一点,如果要放置的都是很小的内容,那就设小一点。
· vm-pages
设置交换文件的总的 page数量,需要注意的是,page table信息会放在物理内存中,每
8 个page就会占据 RAM中的1个 byte。总的虚拟内存大小 = vm-page-size vm-pages
· vm-max-threads
设置 VM IO 同时使用的线程数量。因为在进行内存交换时,对数据有编码和解码的过
程,所以尽管 IO 设备在硬件上本上不能支持很多的并发读写,但是还是如果你所保存
的 vlaue 值比较大,将该值设大一些,还是能够提升性能的
· glueoutputbuf
把小的输出缓存放在一起,以便能够在一个 TCP packet中为客户端发送多个响应,具体
原理和真实效果我不是很清楚。所以根据注释,你不是很确定的时候就设置成 yes
· hash-max-zipmap-entries
在 redis 2.0中引入了 hash数据结构。当 hash中包含超过指定元素个数并且最大的元素
没有超过临界时,hash 将以一种特殊的编码方式(大大减少内存使用)来存储,这里
可以设置这两个临界值
· activerehashing
开启之后,redis 将在每 100 毫秒时使用 1 毫秒的 CPU 时间来对 redis 的 hash 表进行重
新 hash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能
够接受Redis时不时的对请求有2 毫秒的延迟的话,把这项配置为 no。如果没有这么严
格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
1.4.3 操作数据库
下面我们来简单的操作一下数据库。
插入数据
redis 127.0.0.1:6379> set name wwl
OK
设置一个key-value 对
查询数据
redis 127.0.0.1:6379> get name
wwl
取出key 所对应的value
删除键值
redis 127.0.0.1:6379> del name
删除这个key 及对应的value
验证键是否存在
redis 127.0.0.1:6379> exists name
(integer) 0 《红丸出品》 http:weibo.comu2446082491
22 71
其中0,代表此key不存在;1代表存在
第二章 Redis 数据类型及操作
2.1 前言
Redis的作者antirez(Salvatore Sanfilippo)曾经发表了一篇名为 Redis宣言(Redis Manifesto)
的文章,文中列举了 Redis 的七个原则,以向大家阐明Redis 的思想。
1、Redis是一个操作数据结构的语言工具,它提供基于 TCP的协议以操作丰富的数据结构。
在Redis中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身
及这些操作的时间空间复杂度。
2、Redis定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis能够有如此
高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构,Redis 会尝试其它的存储方面
的选择,但是永远不会改变它是一个内存数据库的角色。
3、Redis使用基础的 API操作基础的数据结构,Redis的 API与数据结构一样,都是一些最基
础的元素,你几乎可以将任何信息交互使用此 API格式表示。作者调侃说,如果有其它非人
类的智能生物存在,他们也能理解 Redis的API。因为它是如此的基础。
4、Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些
其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》
接上后四十回一样。
5、Redis始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为
了一个小功能而往源码里添加上千行代码, 解决复杂问题的方法就是让复杂问题永远不要提
复杂的问题。
6、Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下
的Redis。第二个层面的API支持更复杂的 multi-key操作。它们各有所长,但是我们不会推
出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。 《红丸出品》 http:weibo.comu2446082491
23 71
7、我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享
受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让
Redis不好玩的开发模式。
Redis的作者antirez曾笑称Redis为一个数据结构服务器(data structures server),我认为这
是一个非常准确的表述,Redis 的所有功能就是将数据以其固有的几种结构来保存,并提供
给用户操作这几种结构的接口。本文将介绍 Redis支持的各种数据类型及其操作接口。
2.2 strings 类型及操作
string是最简单的类型,你可以理解成与 Memcached是一模一样的类型,一个 key 对应一个
value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。
string类型是二进制安全的。意思是 redis的 string可以包含任何数据,比如 jpg图片或者序
列化的对象。从内部实现来看其实 string可以看作byte 数组,最大上限是1G字节,下面是
string类型的定义:
struct sdshdr {
long len;
long free;
char buf[];
};
len是buf 数组的长度。
free 是数组中剩余可用字节数,由此可以理解为什么 string类型是二进制安全的了,因为它
本质上就是个byte 数组,当然可以包含任何数据了
buf 是个char数组用于存贮实际的字符串内容,其实char和 c中的byte是等价的,都是一
个字节。
另外string类型可以被部分命令按 int处理.比如incr 等命令,如果只用 string类型,redis就
可以被看作加上持久化特性的 memcached。 当然redis对 string类型的操作比memcached还
是多很多的,具体操作方法如下:
2.2.1 set
设置key 对应的值为 string类型的value。
例如我们添加一个 name= HongWan的键值对,可以这样做:
redis 127.0.0.1:6379> set name HongWan
OK
redis 127.0.0.1:6379>
2.2.2 setnx
设置key 对应的值为 string类型的value。 如果 key 已经存在,返回 0, nx是 not exist的意思。 《红丸出品》 http:weibo.comu2446082491
24 71
例如我们添加一个 name= HongWan_new的键值对,可以这样做:
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379> setnx name HongWan_new
(integer) 0
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379>
由于原来name 有一个对应的值,所以本次的修改不生效,且返回码是 0。
2.2.3 setex
设置key 对应的值为 string类型的value,并指定此键值对应的有效期。
例如我们添加一个 haircolor= red的键值对,并指定它的有效期是 10秒,可以这样做:
redis 127.0.0.1:6379> setex haircolor 10 red
OK
redis 127.0.0.1:6379> get haircolor
red
redis 127.0.0.1:6379> get haircolor
(nil)
redis 127.0.0.1:6379>
可见由于最后一次的调用是 10秒以后了,所以取不到 haicolor 这个键对应的值。
2.2.4 setrange
设置指定key 的value 值的子字符串。
例如我们希望将 HongWan的126邮箱替换为 gmail邮箱,那么我们可以这样做:
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379> setrange name 8 gmail.com
(integer) 17
redis 127.0.0.1:6379> get name
HongWan@gmail.com
redis 127.0.0.1:6379>
其中的8是指从下标为8(包含8)的字符开始替换
2.2.5 mset
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值
被设置。
redis 127.0.0.1:6379> mset key1 HongWan1 key2 HongWan2 《红丸出品》 http:weibo.comu2446082491
25 71
OK
redis 127.0.0.1:6379> get key1
HongWan1
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379>
2.2.6 msetnx
一次设置多个 key 的值,成功返回 ok 表示所有的值都设置了,失败返回 0 表示没有任何值
被设置,但是不会覆盖已经存在的 key。
redis 127.0.0.1:6379> get key1
HongWan1
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379> msetnx key2 HongWan2_new key3 HongWan3
(integer) 0
redis 127.0.0.1:6379> get key2
HongWan2
redis 127.0.0.1:6379> get key3
(nil)
可以看出如果这条命令返回 0,那么里面操作都会回滚,都不会被执行。
2.2.7 get
获取key 对应的string值,如果key 不存在返回 nil。
例如我们获取一个库中存在的键 name,可以很快得到它对应的 value
redis 127.0.0.1:6379> get name
HongWan
redis 127.0.0.1:6379>
我们获取一个库中不存在的键 name1,那么它会返回一个 nil以表时无此键值对
redis 127.0.0.1:6379> get name1
(nil)
redis 127.0.0.1:6379>
2.2.8 getset
设置key 的值,并返回 key 的旧值。
redis 127.0.0.1:6379> get name
HongWan 《红丸出品》 http:weibo.comu2446082491
26 71
redis 127.0.0.1:6379> getset name HongWan_new
HongWan
redis 127.0.0.1:6379> get name
HongWan_new
redis 127.0.0.1:6379>
接下来我们看一下如果 key 不存的时候会什么样儿?
redis 127.0.0.1:6379> getset name1 aaa
(nil)
redis 127.0.0.1:6379>
可见,如果key不存在,那么将返回 nil
2.2.9 getrange
获取指定key 的value 值的子字符串。
具体样例如下:
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379> getrange name 0 6
HongWan
redis 127.0.0.1:6379>
字符串左面下标是从 0开始的
redis 127.0.0.1:6379> getrange name -7 -1
126.com
redis 127.0.0.1:6379>
字符串右面下标是从-1开始的
redis 127.0.0.1:6379> getrange name 7 100
@126.com
redis 127.0.0.1:6379>
当下标超出字符串长度时,将默认为是同方向的最大下标
2.2.10 mget
一次获取多个key 的值,如果对应key 不存在,则对应返回 nil。
具体样例如下:
redis 127.0.0.1:6379> mget key1 key2 key3
1) HongWan1
2) HongWan2
3) (nil)
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
27 71
key3由于没有这个键定义,所以返回 nil。
2.2.11 incr
对 key 的值做加加操作,并返回新的值。注意 incr 一个不是 int 的 value 会返回错误,incr 一
个不存在的key,则设置 key 为1
redis 127.0.0.1:6379> set age 20
OK
redis 127.0.0.1:6379> incr age
(integer) 21
redis 127.0.0.1:6379> get age
21
redis 127.0.0.1:6379>
2.2.12 incrby
同incr类似,加指定值 ,key 不存在时候会设置 key,并认为原来的 value 是 0
redis 127.0.0.1:6379> get age
21
redis 127.0.0.1:6379> incrby age 5
(integer) 26
redis 127.0.0.1:6379> get name
HongWan@gmail.com
redis 127.0.0.1:6379> get age
26
redis 127.0.0.1:6379>
2.2.13 decr
对key的值做的是减减操作,decr一个不存在 key,则设置key为-1
redis 127.0.0.1:6379> get age
26
redis 127.0.0.1:6379> decr age
(integer) 25
redis 127.0.0.1:6379> get age
25
redis 127.0.0.1:6379>
2.2.14 decrby
同decr,减指定值。 《红丸出品》 http:weibo.comu2446082491
28 71
redis 127.0.0.1:6379> get age
25
redis 127.0.0.1:6379> decrby age 5
(integer) 20
redis 127.0.0.1:6379> get age
20
redis 127.0.0.1:6379>
decrby 完全是为了可读性,我们完全可以通过 incrby 一个负值来实现同样效果,反之一样。
redis 127.0.0.1:6379> get age
20
redis 127.0.0.1:6379> incrby age -5
(integer) 15
redis 127.0.0.1:6379> get age
15
redis 127.0.0.1:6379>
2.2.15 append
给指定key的字符串值追加 value,返回新字符串值的长度。
例如我们向name的值追加一个@126.com 字符串,那么可以这样做:
redis 127.0.0.1:6379> append name @126.com
(integer) 15
redis 127.0.0.1:6379> get name
HongWan@126.com
redis 127.0.0.1:6379>
2.2.16 strlen
取指定key的value值的长度。
redis 127.0.0.1:6379> get name
HongWan_new
redis 127.0.0.1:6379> strlen name
(integer) 11
redis 127.0.0.1:6379> get age
15
redis 127.0.0.1:6379> strlen age
(integer) 2
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
29 71
2.3 hashes 类型及操作
Redis hash是一个 string类型的field和value的映射表.它的添加、删除操作都是 O(1) (平均)。
hash特别适合用于存储对象。相较于将对象的每个字段存成单个 string类型。将一个对象存
储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。省内存的原因是新
建一个hash对象时开始是用 zipmap(又称为 small hash)来存储的。这个 zipmap其实并不
是hash table,但是 zipmap相比正常的hash实现可以节省不少hash 本身需要的一些元数据
存储开销。尽管 zipmap的添加,删除,查找都是 O(n),但是由于一般对象的 field数量都不
太多。所以使用 zipmap 也是很快的,也就是说添加删除平均还是 O(1)。如果 field 或者 value
的大小超出一定限制后, Redis会在内部自动将zipmap替换成正常的 hash实现. 这个限制可
以在配置文件中指定
hash-max-zipmap-entries 64 配置字段最多 64个
hash-max-zipmap-value 512 配置value 最大为512字节
2.3.1 hset
设置hash field为指定值,如果 key 不存在,则先创建。
redis 127.0.0.1:6379> hset myhash field1 Hello
(integer) 1
redis 127.0.0.1:6379>
2.3.2 hsetnx
设置hash field为指定值,如果 key 不存在,则先创建。如果 field已经存在,返回0,nx是
not exist的意思。
redis 127.0.0.1:6379> hsetnx myhash field Hello
(integer) 1
redis 127.0.0.1:6379> hsetnx myhash field Hello
(integer) 0
redis 127.0.0.1:6379>
第一次执行是成功的,但第二次执行相同的命令失败,原因是field已经存在了。
2.3.3 hmset
同时设置hash的多个field。
redis 127.0.0.1:6379> hmset myhash field1 Hello field2 World
OK
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
30 71
2.3.4 hget
获取指定的hash field。
redis 127.0.0.1:6379> hget myhash field1
Hello
redis 127.0.0.1:6379> hget myhash field2
World
redis 127.0.0.1:6379> hget myhash field3
(nil)
redis 127.0.0.1:6379>
由于数据库没有 field3,所以取到的是一个空值nil
2.3.5 hmget
获取全部指定的 hash filed。
redis 127.0.0.1:6379> hmget myhash field1 field2 field3
1) Hello
2) World
3) (nil)
redis 127.0.0.1:6379>
由于数据库没有 field3,所以取到的是一个空值nil
2.3.6 hincrby
指定的hash filed 加上给定值。
redis 127.0.0.1:6379> hset myhash field3 20
(integer) 1
redis 127.0.0.1:6379> hget myhash field3
20
redis 127.0.0.1:6379> hincrby myhash field3 -8
(integer) 12
redis 127.0.0.1:6379> hget myhash field3
12
redis 127.0.0.1:6379>
在本例中我们将 field3 的值从20 降到了12,即做了一个减8 的操作。
2.3.7 hexists
测试指定field是否存在。
redis 127.0.0.1:6379> hexists myhash field1
(integer) 1 《红丸出品》 http:weibo.comu2446082491
31 71
redis 127.0.0.1:6379> hexists myhash field9
(integer) 0
redis 127.0.0.1:6379>
通过上例可以说明 field1存在,但field9是不存在的。
2.3.8 hlen
返回指定hash的 field数量。
redis 127.0.0.1:6379> hlen myhash
(integer) 4
redis 127.0.0.1:6379>
通过上例可以看到 myhash中有4 个field。
2.3.9 hdel
返回指定hash的 field数量。
redis 127.0.0.1:6379> hlen myhash
(integer) 4
redis 127.0.0.1:6379> hdel myhash field1
(integer) 1
redis 127.0.0.1:6379> hlen myhash
(integer) 3
redis 127.0.0.1:6379>
2.3.10 hkeys
返回hash的所有 field。
redis 127.0.0.1:6379> hkeys myhash
1) field2
2) field
3) field3
redis 127.0.0.1:6379>
说明这个hash中有3 个field
2.3.11 hvals
返回hash的所有 value。
redis 127.0.0.1:6379> hvals myhash
1) World
2) Hello
3) 12 《红丸出品》 http:weibo.comu2446082491
32 71
redis 127.0.0.1:6379>
说明这个hash中有3 个field
2.3.12 hgetall
获取某个hash中全部的filed及value。
redis 127.0.0.1:6379> hgetall myhash
1) field2
2) World
3) field
4) Hello
5) field3
6) 12
redis 127.0.0.1:6379>
可见,一下子将 myhash中所有的field及对应的value 都取出来了。
2.4 lists类型及操作
list 是一个链表结构,主要功能是 push、pop、获取一个范围的所有值等等,操作中 key 理
解为链表的名字。
Redis的list类型其实就是一个每个子元素都是 string类型的双向链表。链表的最大长度是(2
的32次方)。我们可以通过 push,pop操作从链表的头部或者尾部添加删除元素。这使得 list
既可以用作栈,也可以用作队列。
有意思的是list的 pop操作还有阻塞版本的,当我们[lr]pop一个 list对象时,如果list是空,或者不存在,会立即返回 nil。但是阻塞版本的 b[lr]pop可以则可以阻塞,当然可以加超时时
间,超时后也会返回 nil。为什么要阻塞版本的 pop 呢,主要是为了避免轮询。举个简单的
例子如果我们用 list来实现一个工作队列。执行任务的thread可以调用阻塞版本的 pop去获
取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。说了这么多,接下来看一下实际操作的方法吧:
2.4.1 lpush
在key对应list的头部添加字符串元素
redis 127.0.0.1:6379> lpush mylist world
(integer) 1
redis 127.0.0.1:6379> lpush mylist hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist 0 -1
1) hello 《红丸出品》 http:weibo.comu2446082491
33 71
2) world
redis 127.0.0.1:6379>
在此处我们先插入了一个world,然后在world的头部插入了一个 hello。其中 lrange 是用于
取mylist的内容。
2.4.2 rpush
在key对应list的尾部添加字符串元素
redis 127.0.0.1:6379> rpush mylist2 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist2 world
(integer) 2
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
2) world
redis 127.0.0.1:6379>
在此处我们先插入了一个hello,然后在hello的尾部插入了一个world。
2.4.3 linsert
在key对应list的特定位置之前或之后添加字符串元素
redis 127.0.0.1:6379> rpush mylist3 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist3 world
(integer) 2
redis 127.0.0.1:6379> linsert mylist3 before world there
(integer) 3
redis 127.0.0.1:6379> lrange mylist3 0 -1
1) hello
2) there
3) world
redis 127.0.0.1:6379>
在此处我们先插入了一个 hello,然后在 hello 的尾部插入了一个 world,然后又在 world 的
前面插入了there。
2.4.4 lset
设置list中指定下标的元素值(下标从0开始)
redis 127.0.0.1:6379> rpush mylist4 one
(integer) 1
redis 127.0.0.1:6379> rpush mylist4 two 《红丸出品》 http:weibo.comu2446082491
34 71
(integer) 2
redis 127.0.0.1:6379> rpush mylist4 three
(integer) 3
redis 127.0.0.1:6379> lset mylist4 0 four
OK
redis 127.0.0.1:6379> lset mylist4 -2 five
OK
redis 127.0.0.1:6379> lrange mylist4 0 -1
1) four
2) five
3) three
redis 127.0.0.1:6379>
在此处我们依次插入了 one,two,three,然后将标是0的值设置为four,再将下标是-2 的值设
置为five。
2.5.5 lrem
从key对应list中删除 count个和value相同的元素。
count>0 时,按从头到尾的顺序删除,具体如下:
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist5 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist5 hello
(integer) 4
redis 127.0.0.1:6379> lrem mylist5 2 hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) foo
2) hello
redis 127.0.0.1:6379>
count<0 时,按从尾到头的顺序删除,具体如下:
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist6 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist6 hello
(integer) 4 《红丸出品》 http:weibo.comu2446082491
35 71
redis 127.0.0.1:6379> lrem mylist6 -2 hello
(integer) 2
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) hello
2) foo
redis 127.0.0.1:6379>
count=0 时,删除全部,具体如下:
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 1
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 2
redis 127.0.0.1:6379> rpush mylist7 foo
(integer) 3
redis 127.0.0.1:6379> rpush mylist7 hello
(integer) 4
redis 127.0.0.1:6379> lrem mylist7 0 hello
(integer) 3
redis 127.0.0.1:6379> lrange mylist7 0 -1
1) foo
redis 127.0.0.1:6379>
2.4.6 ltrim
保留指定key 的值范围内的数据
redis 127.0.0.1:6379> rpush mylist8 one
(integer) 1
redis 127.0.0.1:6379> rpush mylist8 two
(integer) 2
redis 127.0.0.1:6379> rpush mylist8 three
(integer) 3
redis 127.0.0.1:6379> rpush mylist8 four
(integer) 4
redis 127.0.0.1:6379> ltrim mylist8 1 -1
OK
redis 127.0.0.1:6379> lrange mylist8 0 -1
1) two
2) three
3) four
redis 127.0.0.1:6379> 《红丸出品》 http:weibo.comu2446082491
36 71
2.4.7 lpop
从list的头部删除元素,并返回删除元素
redis 127.0.0.1:6379> lrange mylist 0 -1
1) hello
2) world
redis 127.0.0.1:6379> lpop mylist
hello
redis 127.0.0.1:6379> lrange mylist 0 -1
1) world
redis 127.0.0.1:6379>
2.4.8 rpop
从list的尾部删除元素,并返回删除元素
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
2) world
redis 127.0.0.1:6379> rpop mylist2
world
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) hello
redis 127.0.0.1:6379>
2.4.9 rpoplpush
从第一个list的尾部移除元素并添加到第二个 list的头部,最后返回被移除的元素值,整个操
作是原子的.如果第一个list是空或者不存在返回 nil
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
3) hello
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) hello
2) foo
redis 127.0.0.1:6379> rpoplpush mylist5 mylist6
hello
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
redis 127.0.0.1:6379> lrange mylist6 0 -1 《红丸出品》 http:weibo.comu2446082491
37 71
1) hello
2) hello
3) foo
redis 127.0.0.1:6379>
2.4.10 lindex
返回名称为key的 list中index位置的元素
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) three
2) foo
redis 127.0.0.1:6379> lindex mylist5 0
three
redis 127.0.0.1:6379> lindex mylist5 1
foo
redis 127.0.0.1:6379>
2.4.11 llen
返回key 对应list的长度
redis 127.0.0.1:6379> llen mylist5
(integer) 2
redis 127.0.0.1:6379>
2.5 sets类型及操作
set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合
求交并差等操作,操作中key 理解为集合的名字。
Redis的set是 string类型的无序集合。set元素最大可以包含(2的 32次方)个元素。
set的是通过hash table 实现的,所以添加、删除和查找的复杂度都是 O(1)。hash table 会随
着添加或者删除自动的调整大小。需要注意的是调整 hash table大小时候需要同步(获取写
锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在 sorted
set 中使用了。关于 set 集合类型除了基本的添加删除操作,其他有用的操作还包含集合的
取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现 sns
中的好友推荐和 blog的tag功能。下面详细介绍 set相关命令:
2.5.1 sadd
向名称为key 的set中添加元素 《红丸出品》 http:weibo.comu2446082491
38 71
redis 127.0.0.1:6379> sadd myset hello
(integer) 1
redis 127.0.0.1:6379> sadd myset world
(integer) 1
redis 127.0.0.1:6379> sadd myset world
(integer) 0
redis 127.0.0.1:6379> smembers myset
1) world
2) hello
redis 127.0.0.1:6379>
本例中,我们向myset中添加了三个元素,但由于第三个元素跟第二个元素是相同的,所以
第三个元素没有添加成功,最后我们用smembers来查看myset中的所有元素。
2.5.2 srem
删除名称为key的 set中的元素member
redis 127.0.0.1:6379> sadd myset2 one
(integer) 1
redis 127.0.0.1:6379> sadd myset2 two
(integer) 1
redis 127.0.0.1:6379> sadd myset2 three
(integer) 1
redis 127.0.0.1:6379> srem myset2 one
(integer) 1
redis 127.0.0.1:6379> srem myset2 four
(integer) 0
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379>
本例中,我们向myset2中添加了三个元素后,再调用 srem来删除 one 和four,但由于元素
中没有four所以,此条 srem命令执行失败。
2.5.3 spop
随机返回并删除名称为 key 的set中一个元素
redis 127.0.0.1:6379> sadd myset3 one
(integer) 1
redis 127.0.0.1:6379> sadd myset3 two
(integer) 1
redis 127.0.0.1:6379> sadd myset3 three
(integer) 1 《红丸出品》 http:weibo.comu2446082491
39 71
redis 127.0.0.1:6379> spop myset3
three
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379>
本例中,我们向myset3中添加了三个元素后,再调用spop来随机删除一个元素,可以看到
three元素被删除了。
2.5.4 sdiff
返回所有给定key 与第一个key的差集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sdiff myset2 myset3
1) three
redis 127.0.0.1:6379>
本例中,我们可以看到 myset2中的元素与 myset3中不同的只是three,所以只有three被查
出来了,而不是 three和one,因为one 是 myset3的元素。
我们也可以将myset2和 myset3换个顺序来看一下结果:
redis 127.0.0.1:6379> sdiff myset3 myset2
1) one
redis 127.0.0.1:6379>
这个结果中只显示了,myset3中的元素与 myset2中不同的元素。
2.5.5 sdiffstore
返回所有给定key 与第一个key的差集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sdiffstore myset4 myset2 myset3
(integer) 1
redis 127.0.0.1:6379> smembers myset4 《红丸出品》 http:weibo.comu2446082491
40 71
1) three
redis 127.0.0.1:6379>
2.5.6 sinter
返回所有给定key 的交集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sinter myset2 myset3
1) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的交集two被查出来了
2.5.7 sinterstore
返回所有给定key 的交集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sinterstore myset5 myset2 myset3
(integer) 1
redis 127.0.0.1:6379> smembers myset5
1) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的交集被保存到myset5 中了
2.5.8 sunion
返回所有给定key 的并集
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two 《红丸出品》 http:weibo.comu2446082491
41 71
2) one
redis 127.0.0.1:6379> sunion myset2 myset3
1) three
2) one
3) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的并集被查出来了
2.5.9 sunionstore
返回所有给定key 的并集,并将结果存为另一个 key
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> sunionstore myset6 myset2 myset3
(integer) 3
redis 127.0.0.1:6379> smembers myset6
1) three
2) one
3) two
redis 127.0.0.1:6379>
通过本例的结果可以看出, myset2和myset3 的并集被保存到myset6 中了
2.5.10 smove
从第一个key 对应的set中移除member 并添加到第二个对应set中
redis 127.0.0.1:6379> smembers myset2
1) three
2) two
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> smove myset2 myset7 three
(integer) 1
redis 127.0.0.1:6379> smembers myset7
1) three
redis 127.0.0.1:6379>
通过本例可以看到,myset2 的three 被移到 myset7中了 《红丸出品》 http:weibo.comu2446082491
42 71
2.5.11 scard
返回名称为key的 set的元素个数
redis 127.0.0.1:6379> scard myset2
(integer) 1
redis 127.0.0.1:6379>
通过本例可以看到,myset2 的成员数量为1
2.5.12 sismember
测试member 是否是名称为 key的 set的元素
redis 127.0.0.1:6379> smembers myset2
1) two
redis 127.0.0.1:6379> sismember myset2 two
(integer) 1
redis 127.0.0.1:6379> sismember myset2 one
(integer) 0
redis 127.0.0.1:6379>
通过本例可以看到,two是myset2 的成员,而 one不是。
2.5.13 srandmember
随机返回名称为 key的set的一个元素,但是不删除元素
redis 127.0.0.1:6379> smembers myset3
1) two
2) one
redis 127.0.0.1:6379> srandmember myset3
two
redis 127.0.0.1:6379> srandmember myset3
one
redis 127.0.0.1:6379>
2.6 sorted sets 类型及操作
sorted set是set的一个升级版本,它在 set的基础上增加了一个顺序属性,这一属性在添加
修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解为有
两列的mysql表,一列存value,一列存顺序。操作中 key理解为 zset的名字。
和 set 一样 sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double
类型的score。sorted set的实现是skip list和hash table 的混合体。
《红丸出品》 http:weibo.comu2446082491
43 71
当元素被添加到集合中时,一个元素到score 的映射被添加到hash table中,所以给定一个
元素获取score 的开销是 O(1),另一个score 到元素的映射被添加到 skip list,并按照score 排
序,所以就可以有序的获取集合中的元素。添加,删除操作开销都是 O(log(N))和 skip list的
开销一致,redis的 skip list实现用的是双向链表,这样就可以逆序从尾部取元素。sorted set最
经常的使用方式应该是作为索引来使用.我们可以把要排序的字段作为 score 存储,对象的 id
当元素存储。下面是 sorted set相关命令
2.6.1 zadd
向名称为 key 的 zset 中添加元素 member,score 用于排序。如果该元素已经存在,则根据
score 更新该元素的顺序
redis 127.0.0.1:6379> zadd myzset 1 one
(integer) 1
redis 127.0.0.1:6379> zadd myzset 2 two
(integer) 1
redis 127.0.0.1:6379> zadd myzset 3 two
(integer) 0
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
3) two
4) 3
redis 127.0.0.1:6379>
本例中我们向 myzset 中添加了 one 和 two,并且 two 被设置了 2 次,那么将以最后一次的
设置为准,最后我们将所有元素都显示出来并显示出了元素的score。
2.6.2 zrem
删除名称为key的 zset中的元素member
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
3) two
4) 3
redis 127.0.0.1:6379> zrem myzset two
(integer) 1
redis 127.0.0.1:6379> zrange myzset 0 -1 withscores
1) one
2) 1
redis 127.0.0.1:6379>
可以看到two被删除了 《红丸出品》 http:weibo.comu2446082491
44 71
2.6.3 zincrby
如果在名称为key 的zset中已经存在元素 member,则该元素的score增加 increment;否则
向集合中添加该元素,其 score 的值为increment
redis 127.0.0.1:6379> zadd myzset2 1 one
(integer) 1
redis 127.0.0.1:6379> zadd myzset2 2 two
(integer) 1
redis 127.0.0.1:6379> zincrby myzset2 2 one
3
redis 127.0.0.1:6379> zrange myzset2 0 -1 withscores
1) two
2) 2
3) one
4) 3
redis 127.0.0.1:6379>
本例中将one 的 score 从1 增加了2,增加到了 3
2.6.4 zrank
返回名称为key的 zset中member 元素的排名(按 score从小到大排序)即下标
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrank myzset3 two
(integer) 1
redis 127.0.0.1:6379>
本例中将two的下标是1,我这里取的是下标,而不是 score
2.6.5 zrevrank
返回名称为key的 zset中member 元素的排名(按 score从大到小排序)即下标
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1 《红丸出品》 http:weibo.comu2446082491
45 71
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrevrank myzset3 two
(integer) 2
redis 127.0.0.1:6379>
按从大到小排序的话 two是第三个元素,下标是2
2.6.6 zrevrange
返回名称为key的 zset(按score从大到小排序)中的index从 start到 end的所有元素
redis 127.0.0.1:6379> zrevrange myzset3 0 -1 withscores
1) five
2) 5
3) three
4) 3
5) two
6) 2
7) one
8) 1
redis 127.0.0.1:6379>
首先按score从大到小排序,再取出全部元素
2.6.7 zrangebyscore
返回集合中score在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zrangebyscore myzset3 2 3 withscores
1) two
2) 2
3) three 《红丸出品》 http:weibo.comu2446082491
46 71
4) 3
redis 127.0.0.1:6379>
本例中,返回了 score在2~3区间的元素
2.6.8 zcount
返回集合中score在给定区间的数量
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zcount myzset3 2 3
(integer) 2
redis 127.0.0.1:6379>
本例中,计算了 score在2~3之间的元素数目
2.6.9 zcard
返回集合中元素个数
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zcard myzset3
(integer) 4
redis 127.0.0.1:6379>
从本例看出myzset3 这个集全的元素数量是4
2.6.10 zscore
返回给定元素对应的 score 《红丸出品》 http:weibo.comu2446082491
47 71
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zscore myzset3 two
2
redis 127.0.0.1:6379>
此例中我们成功的将 two的score取出来了。
2.6.11 zremrangebyrank
删除集合中排名在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
7) five
8) 5
redis 127.0.0.1:6379> zremrangebyrank myzset3 3 3
(integer) 1
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) one
2) 1
3) two
4) 2
5) three
6) 3
redis 127.0.0.1:6379>
在本例中我们将 myzset3中按从小到大排序结果的下标为3的元素删除了。
2.6.12 zremrangebyscore
删除集合中score在给定区间的元素
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores 《红丸出品》 http:weibo.comu2446082491
48 71
1) one
2) 1
3) two
4) 2
5) three
6) 3
redis 127.0.0.1:6379> zremrangebyscore myzset3 1 2
(integer) 2
redis 127.0.0.1:6379> zrange myzset3 0 -1 withscores
1) three
2) 3
redis 127.0.0.1:6379>
在本例中我们将 myzset3中按从小到大排序结果的 score 在1~2之间的元素删除了。
第三章、Redis 常用命令
Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些 command
可以在Linux终端使用。在编程时,比如各类语言包,这些命令都有对应的方法。下面将 Redis
提供的命令做一总结。
3.1 键值相关命令
3.1.1 keys
返回满足给定pattern 的所有key
redis 127.0.0.1:6379> keys
1) myzset2
2) myzset3
3) mylist
4) myset2
5) myset3
6) myset4
7) k_zs_1
8) myset5
9) myset6
10) myset7
11) myhash
12) myzset
13) age 《红丸出品》 http:weibo.comu2446082491
49 71
14) myset
15) mylist5
16) mylist6
17) mylist7
18) mylist8
用表达式,代表取出所有的 key
redis 127.0.0.1:6379> keys mylist
1) mylist
2) mylist5
3) mylist6
4) mylist7
5) mylist8
redis 127.0.0.1:6379>
用表达式mylist,代表取出所有以mylist开头的key
3.1.2 exists
确认一个key 是否存在
redis 127.0.0.1:6379> exists HongWan
(integer) 0
redis 127.0.0.1:6379> exists age
(integer) 1
redis 127.0.0.1:6379>
从结果来数据库中不存在HongWan这个 key,但是age 这个key 是存在的
3.1.3 del
删除 ......
您现在查看是摘要介绍页, 详见PDF附件(1319KB,71页)。





