redis知识(二)
Redis数据类型
一、字符串类型
介绍:字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据。可以存储JSON化的对象、字节数组等。一个字符串类型键允许存储的数据最大容量是512MB。
赋值与取值:
set key value
get key
当键不存在的时候返回空结果
1.1、递增数字
INCR key
当存储的字符串是整数时,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值
1.2、增加制定的整数
INCRBY key increment
1.3、减少指定的整数
DECR key
DECRBY key decrement
1.4、向尾部增加值
APPEND key value
APPEND的作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,即相当于 SET key value。返回值是追加后字符串的总长度。
1.5、获取字符串长度
STRLEN key
STRLEN命令返回键值的长度,如果键不存在则返回0。
1.6、同时设置/获取多个键值
MSET key value[key value......]
MGET key [key......]
二、散列类型
介绍:散列类型存储了字段(filed)和字段值的映射,但字段值只能是字符串,不支持其他类型,也就是说,散列类型不能嵌套其他的数据类型。一个散列类型才可以包含最多2^32-1个字段
2.1、赋值与取值
HSET key field value
HGET key field
HMSET key field value[field value........]
HMGET key field[field........]
HGETALL key
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0.
2.2、判断字段是否存在
HEXISTS key field
当字段不存在时赋值,类似HSET,区别在于如果字段已经存在,该命令不执行任何操作。
HSETNX key field value
2.3、增加数字
HINCRBY key field increment
2.4、删除字段
删除字段,可以删除一个或多个字段,返回值是被删除的字段个数
HDEL key field[field.........]
2.5、只获取字段名或字段值
HKEYS key
HVALS key
2.6、获取字段数量
HLEN key
三、ArrayList与LinkedList的区别
ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。LinkedList使用双向链接方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢。
双向链接添加节点:
双向链接删除节点:
四、列表类型
介绍:列表类型(List)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一片段。列表类型内部是使用双向链表实现,所有向列表两端添加元素 的时间复杂度几乎为0,获取越接近两端的元素速度越快。这就意味着即使是一个几千万个元素的类别,获取头部或者尾部的10条记录也是非常快的。与hash数据类型一样,一个列表类型键最多能容纳2^32-1个元素。使用场景:微博、日志系统。
4.1、向列表两端增加元素
LPUSH key value [value ...]
RPUSH key value [value ...]
4.2、从列表两端弹出元素
LPOP key
RPOP key
LPOP命令从列表左边弹出一个元素,会分两步完成,第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。
4.3、获取列表中元素的个数
LLEN key
4.4、获取列表片段
LRANGE key start stop
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
4.5、删除列表中指定的值
LREM key count value
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
当count>0时, LREM会从列表左边开始删除。
当count<0时, LREM会从列表后边开始删除。
当count=0时, LREM删除所有值为value的元素。
4.6、获得/设置指定索引的元素值
LINDEX key index
LSET key index value
4.7、只保留列表指定片段,指定范围和LRANGE一致
LTRIM key start stop
4.8、向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。
4.9、将元素从一个列表转移到另一个列表中
RPOPLPUSH source destination
五、集合(Set)
介绍:在集合中的每个元素都是不同的,没有顺序,一个集合类型键最多可以存储2^32-1个字符串。
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。 Redis还提供了多个集合之间的交集、并集、差集的运算。
5.1、增加/删除元素
SADD key member [member ...]
SREM key member [member ...]
5.2、获得集合中的所有元素
SMEMBERS key
5.3、判断元素是否在集合中,无论集合中有多少个元素都可以急速的返回结果。
SISMEMBER key member
5.4、集合的差集运算A-B,属于A并不属于B的元素构成的集合。
SDIFF key [key ...]
5.5、集合的交集运算,属于A并且属于B的元素构成的集合。
SINTER key [key ...]
5.6、集合的并集运算,属于A或者属于B的元素构成的集合。
SUNION key [key ...]
5.7、获取集合中的元素个数
SCARD key
5.8、从集合中弹出一个元素
SPOP key
六、有序集合
介绍:在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
6.1、增加元素
增加元素,向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
ZADD key score member [score member ...]
6.2、获取元素的分数
ZSCORE key member
6.3、获得排名在某个范围的元素列表
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
该命令会按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数
6.4、获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
6.5、增加某个元素的分数,返回值是更改后的分数。
ZINCRBY key increment member
6.6、获得集合中元素的数量
ZCARD key
6.7、获得指定分数范围内的元素个数
ZCOUNT key min max
6.8、按照排名范围删除元素
ZREMRANGEBYRANK key start stop
ZREMRANGEBYSCORE key min max
6.9、获取元素的排名
ZRANK key member(从小到大)
ZREVRANK key member(从大到小)
七、Redis生存时间
介绍:Redis在实际使用过程中更多的用作缓存,然而缓存的数据一般都是需要设置生存时间的,即:到期后数据销毁。
EXPIRE key seconds
清除生存时间
PERSIST key
生存时间设置单位为:毫秒
PEXPIRE key milliseconds
八、Redis应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
分布式集群架构中的session分离。
聊天室的在线好友列表。
任务队列。(秒杀、抢购、12306等等)(左进右出、右进左出)
应用排行榜。
网站访问统计。
数据过期处理(可以精确到毫秒)
九、Redis持久化
Redis的强大功能很大程度上是由于其将所有数据都存储在内存中,为了使Redis在重启后仍能保证数据不丢失,需要将数据从内存中以某种形式持久化到硬盘中。Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将两种结合使用。
RDB方式是通过快照完成的,当符合一定条件时Redis会自动将内存中的所有数据进行快照并且存储到硬盘上。进行快照的条件在配置文件中指定,有2个参数构成:时间和改动的键的个数,当在指定时间内被更改的键的个数大于指定数值时就会进行快照。RDB是Redis的默认持久化方式。
9.1、RDB持久化
在配置文件中已经预置了3个条件:
save 900 1 #15分钟内有至少1个键被更改则进行快照
save 300 10 #5分钟内至少有10个键被更改则进行快照
save 60 10000 #1分钟内至少有10000个键被更改则进行快照
以上条件之间是“或”的关系。默认的rdb的文件路径是在当前目录,文件名是:dump.rdb,可以在配置文件中修改路径和文件名,分别是dir和dbfilename。Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存,一般情况下1GB的快照文件载入到内存的时间约为20~30秒钟。(不同服务器会有差异)
RDB的快照过程如下:
1.Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
2.父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入到硬盘中的临时文件;
3.当子进程写入完所有数据后会用该临时文件替换旧的RDB文件。
RDB文件是通过压缩的,可以通过配置rdbcompression参数来禁用压缩。
思考? 压缩与不压缩的优缺点是什么?
可以通过SAVE和BGSAVE命令来手动快照,两个命令的区别是前者是由主进程进行快照,会阻塞其他请求,后者是通过fork子进程快照操作。 注意:由于Redis使用fork来复制一份当前进程,那么子进程就会占有和主进程一样的内存资源,比如说主进程8G内存,那么在备份的时候必须保证有16G的内存,要不然会启用虚拟内存,性能非常差。
9.2、AOF持久化
Redis的AOF持久化策略是将发送到Redis服务端的每一条命令都记录下来,并且保存到硬盘中的AOF文件,AOF文件的位置和RDB文件的位置相同,都是通过dir参数设置,默认的文件名是appendonly.aof,可以通过appendfilename参数修改。
127.0.0.1:6379> set test 123 OK 127.0.0.1:6379> set test2 234 OK
执行以上命令,可以看到appendonly.aof文件中保存了操作命令:
*2 $6 SELECT $1 0 *3 $3 set $4 test $3 123 *3 $3 set $5 test2 $3 234
可以使用BGREWRITEAOF命令来重写AOF文件。
重写策略的参数设置:
auto-aof-rewrite-percentage 100
当前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会再次进行重写,如果之前没有重写过,则以启动时的AOF文件大小为依据
auto-aof-rewrite-min-size 64mb
限制了允许重写的最小AOF文件大小,通常在AOF文件很小的时候即使其中有些冗余的命令也是可以忽略的。
文件写入默认情况下会先写入到系统的缓存中,系统每30秒同步一次,才是真正的写入到硬盘,如果在这30秒服务器宕机那数据也会丢失的,Redis可以通过配置来修改同步策略:
# appendfsync always 每次都同步 (最安全但是最慢)
appendfsync everysec 每秒同步 (默认的同步策略)
# appendfsync no 不主动同步,由操作系统来决定 (最快但是不安全)