前言
最近因项目需要用到redis,所以借助《Redis入门指南》(李子骅 编著)这本书快速入门了一下,此处记录下一些知识点(主要是命令),方便以后查阅。
简介
Redis是一个开源的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案。
Redis的三个主要特点:
- Redis数据库完全在内存中,使用磁盘仅用于持久性。
- 相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
- Redis可以将数据复制到任意数量的从服务器。
Redis的优势
- 异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
- 支持丰富的数据类型:Redis支持最大多数开发人员已经知道的像列表,集合,有序集合,散列等数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以通过它的数据类型更好地处理。
- 操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
- 多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
启动与停止
启动
1.直接启动
$ redis-server
默认使用6379端口。
趣闻一则:
6379是手机键盘上MERZ对应的数字,MERZ是一名意大利歌女的名字。
2.通过初始化脚本启动redis,可以使得redis随机启动(适合生产环境)。具体参见《Redis入门指南》。
停止
$ redis-cli SHUTDOWN
redis收到SHUTDOWN命令后会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出。
此外也可以使用“kill redis进程的PID”来正常结束redis。
redis命令行客户端
我们可以通过redis-cli向redis发送命令,同时可以获取命令执行后的返回值。
配置
redis可以通过配置文件和命令行参数进行配置,配置文件模板参见redis.conf,它位于源代码目录的根目录中。
多数据库
redis是一个字典结构的存储服务器,一个redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。
同一个实例中的每个字典相当于一个独立的数据库,它对外是以一个从0开始的递增数字命名,不支持自定义名字。默认使用0号,可以通过SELECT命令来切换。
另外redis也不支持位每个数据库设置不同的访问密码,且多个数据库之间并不是完全隔离的,比如FLUSHALL命令可以清空一个实例中的所以数据库。
因此不同的字典适合当做命名空间来使用,比如0号用于生产环境,1号用于测试环境等等。
而不同应用的数据最好存储在不同实例当中。
入门-数据类型
热身
1.获取符合规则的键名列表
KEYS pattern
其中pattern支持glob风格通配符格式。
? 匹配一个字符
* 匹配任意个字符
[ ] 匹配括号间的任一字符
\ 用于转义
例子:
> SET bar 1
OK
> KEYS *
1) "bar"
(redis不区分命令大小写)
2.判断一个键是否存在
EXISTS key
存在返回1,不存在返回0。
3.删除键
DEL key [key ...]
可以删除多个键,返回值是删除的键的个数。
DEL的参数不支持通配符,但可以结合Linux的管道和xargs命令自己实现删除所以符合规则的键,比如删除所有以”user:”开头的键:
redis-cli KEYS "user:*" | xargs redis-cli DEL
4.获取键值的数据类型
TYPE key
返回值可能是:
string(字符串类型)
hash(散列类型)
list(列表类型)
set(集合类型)
zset(有序集合类型)
字符串类型
Redis的字符串是字节序列。在Redis中字符串是二进制安全的,这意味着他们有一个已知的长度,是没有任何特殊字符终止决定的,所以可以存储任何东西,最大长度可达512兆。
Redis使用一个sdshdr类型的变量来存储字符串,而redisObject的ptr字段指向的是该变量的地址。
struct sdshdr {
int len; //字符串长度
int free; //buf中剩余的空间
char buf[]; //字符串内容
};
相关命令:
1.赋值与取值
SET key value
GET key
例子:
redis 127.0.0.1:6379> SET name "jiange"
OK
redis 127.0.0.1:6379> GET name
"jiange"
2.递增数字
当存储的内容是整数形式时,可以进行自增,当键值不存在时会默认为0,因此第一次递增之后结果为1。
INCR key
生成自增id:
对于文章数据 post:$postID:data ,我们需要每一篇文章有一个唯一的自增id->”\$postID”,可使用名为 对象类型(复数形式):count(命名仅供参考,可以使用其他任意名字)的键来存储当前类型对象的数量,每增加一个新对象就对它使用INCR:
$postID = INCR posts:count
$serializedPost = serialize($title,$content,$author,$time)
SET post:$postID:data, $serializedPost
3.增加指定整数
INCRBY key increment
4.减少指定整数
DECR key
DECRBY key decrement
5.增加指定浮点数
INCRBYFLOAT key increment
6.向尾部追加值
APPEND key value
7.获取字符串长度
STRLEN key
8.同时获得/设置多个键值
MGET key [key ...]
MSET key value [key value ...]
9.位操作
GETBIT key offset
SETBIT key offset value
BITCOUNT key [start] [end] //获得二进制中1的个数
BITOP operation destkey key [key ...]
//operation包括AND,OR,XOR,NOT
散列类型
散列类型的键值也是一种字典类型,其存储了字段和字段值的映射,字段值只能是字符串,一个散列类型键可以包含至多2^32-1个字段。
散列类型适合存储对象:使用对象类别和ID构成key,使用字段表示对象的属性,而字段值则存储属性值。
比如:
键 字段 字段值
color 白色
car:2 name 奥迪
price 90万
该汽车对象的ID为2。
相关命令:
1.赋值和取值
HSET key field value
HGET key field
HMSET key field value [field value ...]
HMGET key field [field ...]
HGETALL key
HSET命令不区分插入和更新操作,当执行的是插入时返回1,更新时返回0。当键本身不存在时,HSET命令会自动建立它。
2.判断字段是否存在
HEXISTS key field
3.当字段不存在时赋值
HSETNX key field value
如果字段已存在,将不执行任何操作。
4.增加数字
HINCRBY key field increment
5.删除字段
HDEL key field [field ...]
6.只获取字段名或字段值
HKEYS key
HVALS key
7.获得字段数量
HLEN key
列表类型
list可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。其内部使用双向链表实现,因此在头部和尾部添加和获取元素的速度很快,缺点是通过索引访问元素比较慢。
一个列表类型的键最多能容纳2^32-1个元素。
相关命令:
1.向列表两端增加元素
LPUSH key value [value ...]
RPUSH key value [value ...]
分别向键值位key的列表左边和右边添加元素,返回值表示增加元素后列表的长度。
2.向列表两端弹出元素
LPOP key
RPOP key
3.获取列表中元素的个数
LLEN key
当键值不存在时会返回0;
4.获得列表片段
LRANGE key start stop
LRANGE支持负索引,表示从右边开始计算序数,-1表示最右边第一个元素,-2表示最右边第二个元素;
LRANGE numbers 0 -1 可以获得列表所有元素
当start的索引位置在stop的索引位置后面时,返回空列表;
当stop超过实际的索引范围时,则返回到列表最右边的元素;
5.删除列表中指定的值
LREM key count value
rem位remove的缩写;
以上命令删除列表中前count个值为value的元素,返回的是实际删除的元素个数;
当count > 0时,从列表左边开始删除;
当count < 0时,从列表右边开始删除;
当count = 0时,从列表中删除【所有】值为value的元素;
6.获得/设置指定索引的元素值
LINDEX key index
LSET key index value
LINDEX用来返回指定索引的元素,索引从0开始,index是负数则表示从右边开始计算;
7.只保留列表指定字段
LTRIM key start end
该命令可以删除指定索引范围之外的所有元素(左右都是闭区间);
8.向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
在值为pivot的元素前面or后面插入值value;
9.将元素从一个列表转到另一个列表
RPOPLPUSH source destination
集合类型
集合中每个元素都是不同的,且没有顺序,一个集合类型的键可以存储至多2^32-1个字符串。
集合类型在redis内部是使用值为空的散列表实现的。
多个集合类型键之间可以进行并集,交集和差集运算。
相关命令:
1.增加/删除元素
SADD key member [member ...]
SREM key member [member ...]
返回值是成功加入/删除的元素数量;
2.获得集合中的所有元素
SMEMBERS key
3.判断元素是否在集合中
SISMEMBER key member
时间复杂度为O(1);
4.集合间运算
SDIFF key [key ...]
SINTER key [key ...]
SUNION key [key ...]
5.获得集合中元素个数
SCARD key
6.进行集合运算并存储结果
SDIFFSTORE destination key [key ...]
SINTERSTORE destination key [key ...]
SUNIONSTORE destination key [key ...]
7.随机获得集合中的元素
SRANDMEMBER key [count]
事实上,这里的随机是随机挑选一个桶(上面提到,set是用hash实现的),再从桶里随机选择一个元素,因此每个元素被选中的概率并不一样。
8.从集合中弹出一个元素
SPOP key
随机弹出一个元素。
有序集合类型
有序集合类似集合。不同的是,一个有序集合的每个元素带有分数,便于排序。
有序集合类型是使用散列表和跳跃表实现的,所以即使读取位于中间部分的数据,速度也很快(时间复杂度为O(log(N)))。
相关命令:
1.增加元素
ZADD key score member [score member ...]
如果一个元素已经存在,则用新的分数替换原有的分数。
返回值为新加入到集合中的元素个数。
2.获得元素的个数
ZSCORE key member
3.获得排名在某个范围的元素列表
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANGE会按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。
WITHSCORES可以同时获得元素的分数。
ZREVRANGE则是按分数从大到小排序。
4.获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
按照分数从小到大的顺序返回分数在min和max之间(包含min和max)的元素。
LIMIT offset count 在获得的元素列表的基础上向后偏移offset个元素,并且只获取前count个元素。
5.增加某个元素的分数
ZINCRBY key increment member
6.获得集合中元素的数量
ZCARD key
7.获得指定分数范围内的元素个数
ZCOUNT key min max
8.删除一个或多个元素
ZREM key member [member ...]
9.按照排名范围删除元素
ZREMRANGEBYRANK key start stop
10.按照分数范围删除元素
ZREMRANGEBYSCORE key min max
11.获得元素的排名
ZRANK key member
ZREVRANK key member
12.计算有序集合的交集
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]