Redis是一个开源的高性能键值对数据库(C语言开发,开源)。
提供多种键值数据类型来适应不同场景下的数据存储需求,并借助许多高层级的接口使其可以胜任诸如缓存、队列系统等不同角色。
Redis是单线程模型。
Redis 以字典结构存储数据,并允许其他应用通过TCP协议读写字典内容,同大多数字典一样,字典中键值除了字符串还可以是其他数据类型,目前Redis支持的五大类型:
这种字典形式的存储结构与MySQL等关系型数据库的二维表形式有很大差异。
内存存储与持久化
Redis虽然是作为数据库开发的,但是鉴于其出色性能,让Redis可以作为缓存、队列系统来用。
Redis可以为每个键设置生存时间(Time To Live)TTL , 到期后会自动删除。该功能可以使Redis当缓存来用。Redis支持持久化和丰富的数据类型,使其成为另一个非常流行缓存系统Memcached(支持多线程,多核服务器上其性能更高)的有力竞争者。虽然Redis是单线程,但是其性能足够优异,绝大部分场合下,其性能不会成为瓶颈。
Redis列表类型键可以用来实现队列。并支持阻塞式读取,很容易实现高性能队列。更高层面上,Redis支持发布、订阅消息模式,可以基于此构建聊天室等系统。
首先,需要安装Redis,具体步骤可以根据自己的环境来百度。
启动与停止:
reids-server :启动Redis服务器 Redis默认端口:6379 (redis-server --port 6380 // 自定义端口号)
redis-cli: Redis自带命令客户端
终止:
redis-cli SHUTDOWN
or kill Redis 进程pid 也能正常结束Redis
除了设置port外,Redis还支持设置是否开启持久化,日志级别等。Redis支持通过使用配置文件的方法, 在启动Redis时将配置文件路径作为参数传递给redis-server:
eg: redis-server /path/to/redis.conf
多数据库:
Redis实例提供多个字典来存储数据,可以将每个字典理解成一个独立的数据库。从0号递增,默认支持16个数据库。
SELECT 1 # 选择1号数据库。
注意Redis不支持自定义数据库名字。每个数据库以编号命名。开发者必须记得每个数据库存的数据是那些。另外,不支持为每个数据库设置密码。要么可以全部访问,要么全部不能访问。一个空的Redis实例占用内存只有1MB左右,所以不用担心内存负担。
详解五大类型
3.1字符串类型
Redis的最基本数据类型,能存储任何形式的字符串,包括二进制数据。可以存储邮箱,json化对象甚至图片,一个字符串类型允许存储的最大容量是512MB。
字符串类型是其他四种类型的基础。其他类型数据与字符串类型的差别从某种角度来说只是阻止字符串的形式不同。
eg:列表型是列表形式组织的字符串。集合型是集合形式组织的字符串。
3.2 命令
1. set key value
get key
是Redis中最简单的两个命令
2. incr num # 递增数字,让当前的键值递增,并返回递增后的值。
redis 中所有的操作都是原子操作(原子不可拆分的意思,最小的执行单位,不会在执行的过程中被其他命令插入打断)
incrby key increment # same with incr but this words can define the value of increment
such as
redis > incrby bar 2
(integer) 2
redis > incrby bar 3
(integer) 5
decr key # 键值递减
decrby key decrement # 减少指定的证书, 让键值递减
3. incrbyfloat key increment # 增加指定浮点数
increbyfloat bar 2.7
"6.7"
4. append key value # 向尾部追加
5. strlen key # 获取字符串长度,如果键不存在则返回0。
6. mget key [key ....] # 同时获取多个值
mset key value [ key value .....] # 同时设置多个值
7. 位操作
3.3 散列类型
应用场景:比如博客系统,只希望列表页中的每个文章只显示标题部分,用字符串只能把文章数据字符串取出进行反序列化。其中大部分内容是不必要的。
散列型的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值,只能是字符串,不支持其他数据类型。
散列类型不支持其他数据类型。
散列类型适合存储对象,适用对象类别与ID组成键名,使用字段表示对象的属性值。
命令:
1.赋值取值
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
3.4列表类型
应用场景:新鲜事,队列。
列表类型 可以存储一个有序的字符串列表,常用的操作是想列表的两端添加元素,或者获得列表的一个片段。
列表类型内部是采用双向链表实现的。所以向列表两端添加元素的时间复杂度为O(1)。
获取越接近两端的元素就越快。使用链表的代价是通过索引访问元素比较慢。这种特性使我们能非常快速的完成关系型数据库难以应付的场景,如社交网站新鲜事,人们只关心最新的内容。
借助列表类型,Redis还可以做队列使用。
命令:
1.向列表两端添加元素
2.从列表两端弹出元素
3.获取列表中元素的个数
llen key
4.获取列表片段
lrange key start stop
lrange numbers -2 -1
5.删除列表中指定的值
6.获得、设置指定索引的元素值
lindex key index
lset key index value
7.只保留列表指定片段
ltrim key start end # 可以删除指定索引之外的所有元素,其指定列表范围的方法与lrange命令相同。
8.向列表中插入元素
9.将元素从一个列表转到另一个列表
rpoplpush source destination # source右出后左进destination
3.5集合类型
应用场景:博客中的文章标签。
集合中每个元素都是不同且没有顺序。列表是有序的。集合具有唯一性,列表不具备。
集合类型在Redis中使用值为空的散列表实现。所以这些操作的时间复杂度都是O(1)多个集合类型键之间还可以进行并集交集,差集运算。
命令:
1.增加、删除
2.获取集合中所有元素
smembers key # 返回集合中所有的元素
3.判断元素是否在集合中
sismember key member
4.集合间运算
5.获取集合元素个数
scard key
6.进行集合运算并将结果存储
7.随机获取集合中的元素
srandmember key [count]
3.6 有序集合类型
应用场景:实现按点击量排序 改进按时间排序
有序集合类型,在集合类型的基础上,为集合中每个元素关联一个分数,使得我们不仅可以完成插入,删除,判断元素是否存在等集合类型支持的操作,还能够获得分数最高,最低的前N个元素,获得分数范围内的元素等与分数有关的操作,虽然集合中每个元素都是不同的。但是他们的分数是相同的。
有序集合一些非方面与列表相似。
二者区别:
命令:
1.增加
zadd key score member [score member ...]
2.获得元素分数
zscore key member
3.获得排名在某个范围内的元素列表
4.获得分数范围的元素
zrangebyscore key min max [withscores] [limit 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.获得元素的排名
12.计算有序集合交集
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
4.1事务
所谓事务就是一组命令的集合,事务同命令一样都是Redis最小执行单位,一个事务中的命令要么执行,要么都不执行。
127.0.0.1:6379> multi # 告诉Redis 接下来要发送的命令同属于一个事务,先不执行
OK
127.0.0.1:6379> sadd "user:1:following" 2
QUEUED
127.0.0.1:6379> sadd "user:2:followers" 1
QUEUED
127.0.0.1:6379> exec # 告诉Redis将事务队列中的所有命令按照发送顺序执行
1) (integer) 1
2) (integer) 1
另外,Redis事务还能保证一个事务内的命令依次执行而不被其他命令插入。
4.1.2错误处理
Redis没有回滚,开发者必须在事务执行出错后自己处理。有利有弊,正因为不支持回滚,使Redis事务可以保持简洁和快速。
4.1.3 watch命令
事务可以解决一些问题(保证事务内的命令不被其他命令插入、影响),但有时,事物内部的一个命令会需要另一个命令的的返回值,例如GET, SET ,因为事务中的命令执行结果都是最后一起返回的,所以无法将上一条命令结果作为下一条命令的参数。
watch:监控一个或多个键,一旦其中有一个键被修改或删除,之后的事务就不会执行。监控一致持续到EXEC命令。执行EXEC取消对所有键的监控。
4.2 生存时间
Redis中使用EXPIRE命令设置一个键的生存时间,到时间后Redis会自动删除它。
EXPIRE key seconds seconds 表示键生存时间。
查看一个键还有多久被删除使用TTL
eg: TTL foo
PERSIST 取消键生存时间,设置成永久。