去年大概九月份时,使用Scrapy+Redis实现分布式爬取数据,然后接触到Redis,并查看源码了解到Redis中的List、Set和Zset类型,学会了一些简单的命令。而现在基本天天使用Redis,上百台服务器上跑着Redis,使用Redis成为现在一项必要工作。所以,今天就好好梳理下Redis的几种数据类型和自己在工作经常使用的一些命令。
Redis支持五种数据类型:String(字符串)、List(列表)、Set(集合)、Zset(有序集合)、Hash(哈希),它们所有读写操作都是原子性的。为了保持效率,Redis的数据都是缓存在内存中,会周期性把数据缓存在磁盘中,并且可以很方便实现master-slave(主从)同步。
一、String
String是Redis最基本的数据类型,它是一个键值对,一个key对应一个value。它经常使用的命令有set、get、del、exists。注意:redis的命令在命令行中,是不区分大小写的。
set
设置一个值到对应的键中
语法:SET key value
示例:
# 将身高设置为1.8
set height 1.8
get
获取键对应的值,如果不存在,则返回空。
语法:GET key
示例:
# 获取身高的值
get height
del
删除键值对,会将key对应的value一起删除,key对应的value可以是任何类型。返回0说明数据库中没有这个键,返回1说明删除成功。
语法:DEL key
示例:
# 删除身高的数据
del height
exists
查看某个键是否在数据库中,返回0则说明不存在,返回1说明存在
语法:EXISTS key
示例:
# 查看height的键是否存在
exists height
二、List
List是一个双向链表,在头尾都可以进行插入、删除,有时会称它为列表。它经常使用的命令:lpush、lpop、rpush、rpop、lrange、blpop、brpop、ltrim。
lpush
在链表的头部插入值,可以插入多个。返回一个数值,代表插入了多少个值。
语法:LPUSH key value1, value2, ...
示例:
# 将jack放入names链表中
lpush names jack
lpop
从链表的头部移除一个值,并将这个值返回
语法:LPOP key
示例:
# 将names从头部删除一个值
lpop names
rpush
在链表的尾部插入值,可以插入多个值。返回一个数值,代表插入了多少个值。
语法:RPUSH key value1, value2, ...
示例:
# 将jack、lucy先后插入names链表的尾部
rpush names jack lucy
rpop
从链表的尾部移除一个值,并将这个值返回
语法:RPOP key
示例:
# 从names从尾部删除一个值
rpop names
lrange
返回链表中start到stop的值,注意它包括了首尾,例如lrange names 0 1,返回的是3个值。比较方便的是,它可以使用负数来代表倒数第几个元素,例如-1就是最后一个元素。
语法:LRANGE key start stop
示例:
# 返回names集合中所有元素
lrange names 0 -1
blpop/brpop
blpop类似lpop,brpop类似rpop,它们会弹出列表中的一个元素,区别的是若是列表没有元素,它会一直阻塞等待直到列表中有元素或者超时为止。
应用场景:在项目中,我用到两个地方:一是生产消费者模式,也就是生成一个任务,然后其它服务器谁抢到了,谁就去完成;二是通过生成一个唯一资源,从而控制多台电脑按顺序执行。
ltrim
对列表进行裁剪,保留start到stop间的元素
语法:ltrim key start stop
示例:
# 对names进行裁剪
lrange names 1 2
三、Set
Set是无序、没有重复元素的集合,它是通过哈希表实现的,添加、删除、查找的复杂度是O(1)。它常用命令有sadd、scard、smembers、sismeber、spop、srem。
sadd
在集合中添加元素,可以一次性添加多个。返回一个数值,代表添加元素的个数。
语法:sadd key member [member ...]
示例:
# 添加beijing和shanghai到集合city中
sadd city beijing shanghai
scard
返回集合中元素个数
语法:scard key
示例:
# 返回集合city中的元素个数
scard city
smembers
返回集合中所有元素
语法:smembers key
示例:
# 返回集合city中所有元素
smembers city
sismeber
查看元素是否在集合中存在。返回1说明元素存在,返回0元素不存在
语法:sismember key member
示例:
# 查看集合city中是否存在beijing, 返回1,说明存在
sismember city beijing
# 查看集合city中是否存在changsha, 返回0,说明不存在
sismember city changsha
spop
随机从集合中删除元素,count代表删除元素的个数,默认随机删除一个
语法:spop key [count]
示例:
# 随机删除一个元素
spop city
# 随机删除两个元素
spop city 2
srem
从集合中删除元素,删除成功返回删除的元素数量,0代表没有删除元素
语法:srem key member [member ...]
示例:
# 从集合city中删除wuhan
srem city wuhan
# 删除wuhan和changsha两个元素
srem city wuhan changsha
四、Zset
Zset是一个有序、没有重复元素的集合,和Set不同的是它是有序的,因为它每个元素都会关联一个double类型的score,然后通过score来为集合中的成员进行从小到大排序。它常用的命令有:zadd、zrange、zrem、zcard、zcount、zscore。
zadd
在有序集合中添加元素,score对应分数,member对应元素,集合会按照这个分数进行排序。
语法:ZADD key score member [score member ...]
示例:
zadd student 1 Jack 2 Lucy
zrange
返回有序集合中的元素,start是开始位置,stop是结束位置。
语法: ZRANGE key start stop
示例:
# 返回student集合所有元素
zrange student 0 -1
zrem
删除集合中元素,可以删除多个。返回一个数值,代表删除的元素个数
语法:zrem key member [member ...]
示例:
# 删除student中Jack元素
zrem student Jack
zcard
查看集合的元素个数
语法:zcard key
示例:
# 返回student集合的元素个数
zcard student
zcount
返回有序集key中,score值在min和max之间(默认包括min或max)的成员数量。
语法:zcount key min max
示例:
# 返回score在1到2之间的元素个数
zcount student 1 2
zscore
返回集合中某个元素的分数
语法:zscore key member
示例:
# 返回student集合中Lucy的score值
zscore student Lucy
五、Hash
Hash是一个键值对集合,它就像我们编程语言中的Dictionary一样。常用的方法有:hset、hsetnx、hmset、hget、hmget、hgetall、hdel、hlen、hexists、hincryby、hkeys、hvals。
hset
设置哈希表中key对应域filed的值,如果key不存在,则创建新的哈希表。如果域field已经存在,则旧值被覆盖。返回1说明设置成功,返回0说明失败或值已存在。
语法:hset key field value
示例:
# 设置jack的身高为1.8
hset jack height 1.8
hsetnx
它和hset一样,也是将哈希表中key的域field的值设置为value,当且仅当域field不存在。当域存在时,不会覆盖旧值。返回1说明设置成功,返回0说明设置无效。
语法:HSETNX key field value
示例:
# 设置jack的身高为1.9,由于jack的身高已经设置过了,这里是无效的
hsetnx jack height 1.9
# 设置jack的体重为80,这里设置成功
hsetnx jack weigh 80
hmset
它和hset一样,唯一的区别就是可以设置多个值。
语法:HMSET key field value [field value ...]
hget
返回哈希表key中给定域field的值
语法:HGET key field
示例:
# 获取jack的身高
hget jack height
hmget
和hget差不多,只是可以返回多个值
语法:HMGET key field [field ...]
示例:
# 获取jack的身高和姓名
hget jack height weight
hgetall
返回哈希表中key对应的所有域和值
语法:HGETALL key
示例:
# 获取jack所有域和值,返回了jack的身高和体重
hgetall jack
hdel
删除哈希表中key中的一个或多个指定域
语法:HDEL key field [field ...]
示例:
# 删除jack的身高
hdel jack height
hlen
返回哈希表key中域的数量
语法:HLEN key
示例:
# 返回jack设置过几个域了,这里会返回1,因为只有weight了
hlen jack
hexists
查看哈希表key中给定域是否存在
语法:HEXISTS key field
示例:
# 查看身高是否存在
HEXISTS jack height
HEXISTS jack weight
hincrby
为哈希表key中的域field的值加上增量increment,也就是加上一个数。增量也可以为负数,相当于给指定域进行减法操作。不能用在字符串上。
语法:HINCRBY key field increment
示例:
# jack的体重增加了0.1
hincrby jack weight 0.1
hkeys
返回哈希表key中的所有域
语法:HKEYS key
hvals
返回哈希表key中的所有值
语法:HVALS key
总结
刚开始使用Redis的时候,只是使用String、List、Set,后来要存储对象的时候,发现这远远不够,然后又不知道Hash(当时感觉太复杂,然后就忽略了...),所以当存对象的数据时,使用的Json成字符串然后Set进去,相当不方便。后来,仔细看了数据类型,才知道Hash,功能就类似Dictionary。今天就好好梳理下,总结下,也方便以后查找,也许官方就有更方便的方法。
当然,这些是不够的,后期还得了解底层的数据结构和工作机制。
网友评论