2014年,利用工作之余,我翻译了Redis 3非稳定版的官方文档,在网络上被大量转载、推荐和盗链。6年时光白驹过隙,Redis 6稳定版已经发布,增加了很多新特性,鉴于各种资料参差不齐,或陈旧或残缺或错误,于是抽空再倒腾下。
字符串(Strings)
字符串是最基本的Redis值类型。Redis字符串是二进制安全的,也就是说,一个Redis字符串可以包含任意类型的数据,例如一张JPEG图像,或者一个序列化的Ruby对象。
一个字符串值最大为512M字节。
你可以使用Redis的字符串类型做很多有意思的事情,例如,你可以:
- 使用INCR命令族(INCR,DECR,INCRBY),将字符串作为原子性计数器。
- 使用APPEND命令追加字符串。
- 使用GETRANGE和SETRANGE命令,使字符串作为随机访问向量(vectors)。
- 在一个小空间中编码大量数据,或者使用GETBIT和SETBIT命令,创建一个基于Redis的布隆过滤器(Bloom Filter)。
后续我们会详细介绍可用的字符串命令,也会详细介绍Redis数据类型的更多高级信息。
列表(Lists)
Redis列表就是按照插入顺序排序的字符串列表。可以添加一个元素到Redis列表的头部(左边)或者尾部(右边)。
LPUSH命令用于插入一个元素到列表的头部,RPUSH命令用于插入一个元素到列表的尾部。当这两个命令操作于一个不存在的键时,将会创建一个新的列表。同样,如果一个操作会清空列表,那么该键将会从键空间(key space)被移除。这些是非常方便的语义,因为列表命令如果使用不存在的键作为参数,就会表现得像命令运行在一个空列表上一样。
一些列表操作的例子及其结果:
LPUSH mylist a # now the list is “a”
LPUSH mylist b # now the list is “b”, ”a”
RPUSH mylist c # now the list is “b”,”a”, ”c”(RPUSH was used this time)
列表的最大长度是223-1个元素(4294967295,超过40亿个元素)。
从时间复杂度的角度看,Redis列表主要的特性是支持以常量时间在列表的头和尾附近插入和删除元素,即使列表中已经插入了上百万的数据。访问列表两端的元素非常的快速,但是访问一个非常大的列表的中间元素却非常的慢,因为这是一个O(N)时间复杂度的操作。
你可以使用Redis的列表类型做很多有意思的事情,例如,你可以:
- 为社交网络中的时间轴(timeline)建模,使用LPUSH命令往用户时间轴插入元素,使用LRANGE命令获得最近事项。
- 使用LPUSH和LTRIM命令创建一个不会超出给定数量元素的列表,只存储最近的N个元素。
- 列表可以用作消息传递原语,例如,众所周知的用于创建后台任务的Ruby库Resque。
- 你可以用列表做更多的事情,这种数据类型支持很多的命令,包括阻塞命令,如BLPOP。
后续我们会详细介绍可用的列表命令,也会详细介绍Redis数据类型的更多高级信息。
集合(Sets)
Redis集合是一个没有顺序的字符串集合(collection)。可以以O(1)的时间复杂度来添加、删除和测试元素存在与否(不管集合中有多少元素都是常量时间)。
Redis集合具有不允许重复成员的性质。多次加入同一个元素到集合也只会有一个拷贝在其中。实际上来说,这意味着加入一个元素到集合中并不需要检查元素是否已存在。
Redis集合非常有意思的是,支持很多服务器端的命令,可以在很短的时间内和已经存在的集合一起计算并集、交集和差集。
你可以使用Redis的集合类型做很多有意思的事情,例如,你可以:
- 你可以使用Redis集合追踪唯一性的事情。你想知道访问某篇博客文章的所有唯一IP吗?只要在每次页面访问时使用SADD命令就可以了。你可以放心,重复的IP是不会被插入进来的。
- Redis集合可以表示关系。你可以通过使用集合来表示每个标签,来创建一个标签系统。然后你可以把所有拥有此标签的对象的ID通过SADD命令,加入到表示这个标签的集合中。你想获得同时拥有三个不同标签的对象的全部ID吗?用SINTER就可以了。
- 你可以使用SPOP或SRANDMEMBER命令来从集合中随机抽取元素。
后续我们会详细介绍可用的集合命令,也会详细介绍Redis的数据类型的更多高级信息。
哈希/散列(Hashes)
Redis哈希是字符串字段(field)与字符串值(value)之间的映射,所以是表示对象的理想数据类型(例如:一个用户对象有多个字段,像用户名,姓氏,年龄等等):
HMSET user:1000 username antirez password P1pp0 age 34
HGETALL user:1000
HSET user:1000 password 12345
HGETALL user:1000
拥有少量字段(少量指的是大约100)的哈希会以占用很少存储空间的方式被存储,所以你可以在一个很小的Redis实例里存储数百万的对象。
由于哈希主要用来表示对象,对象能存储很多元素,所以你可以用哈希来做很多其他的事情。
每个哈希可以存储多达223-1个字段-值对(field-value pair)(多于40亿个)。
后续我们会详细介绍可用的哈希命令,也会详细介绍Redis的数据类型的更多高级信息。
有序集合(Sorted sets)
Redis有序集合和Redis集合类似,是一个非重复字符串集合(collection)。不同的是,每一个有序集合的成员都有一个关联的分数(score),用于按照分数高低排序。尽管成员是唯一的,但是分数是可以重复的。
对有序集合,我们可以以很快速的(在和元素数量的对数成正比的时间内)方式添加、删除和更新元素。由于元素是有序的而无需事后排序,你可以通过分数或者排名(rank,位置)很快地来获取一个范围内的元素。访问有序集合的中间元素也是很快的,所以你可以使用有序集合作为一个无重复元素、快速访问你想要的一切的聪明的列表:有序的元素、快速的存在性测试、快速的访问中间元素!
总之,有序集合可以在很好的性能下,做很多别的数据库无法模拟的事情。
使用有序集合你可以:
- 例如,多人在线游戏的排行榜,每次提交一个新的分数,你就使用ZADD命令更新。你可以很容易地使用ZRANGE命令获取前几名用户,你也可以用ZRANK命令,通过给定用户名返回其排名。同时使用ZRANK和ZRANGE命令可以展示与给定用户相似的用户及其分数。以上这些操作都非常的快。
- 有序集合常用来索引存储在Redis内的数据。例如,假设你有很多表示用户的哈希,你可以使用有序集合,用年龄作为元素的分数,用用户ID作为元素值,于是你就可以使用ZRANGEBYSCORE命令很快且轻而易举地检索出给定年龄区间的所有用户了。
有序集合或许是最高级的Redis数据类型,后续我们会详细介绍可用的有序集合命令,也会详细介绍Redis数据类型的更多高级信息。
位图(Bitmaps)和超重对数(HyperLogLogs)
Redis还支持位图和超重对数,它们实际上是基于字符串类型的数据类型,但有自己的语义。
请参考数据类型详解来获取这些类型的相关信息(即下一篇,作者注)。
牛仔很忙,毕业于华中科技大学,硕士研究生,校招加入腾讯,从事电子商务相关研发工作。连续两段创业经历后,最近一份经历,是阿里巴巴国际化中台深圳团队负责人,从事阿里电商中台架构、团队管理、双十一大促、稳定性等工作。
我的人生理想是,白天当一名中学老师,晚上当一名滴滴司机。
欢迎关注微信公众号:程序员阮威