redis当中一共支持五种数据类型,分别是string字符串类型,list列表类型,集合set类型,hash表类型以及有序集合zset类型,通过这五种不同的数据类型,我们可以实现各种不同的功能,也可以应用与各种不同的场景,接下来我们来看看五种数据类型的操作语法
redis当中各种数据类型结构如上图:
下表列出了常用的 redis 字符串命令
SET key value 设置指定 key 的值
示例:SET hello world
GET key 获取指定 key 的值。
示例:GET hello
GETRANGE key start end 返回 key 中字符串值的子字符
示例:GETRANGE hello 0 3
GETSET key value将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
示例:GETSET hello world2
MGET key1 [key2..]获取所有(一个或多个)给定 key 的值。
示例:MGET hello world
SETEX key seconds value将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
示例:SETEX hello 10 world3
SETNX key value只有在 key 不存在时设置 key 的值。
示例:SETNX itcast redisvalue
SETRANGE key offset value用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
示例:SETRANGE itcast 0 helloredis
STRLEN key返回 key 所储存的字符串值的长度。
示例:STRLEN itcast
MSET key value [key value ...]同时设置一个或多个 key-value 对。
示例:MSET itcast2 itcastvalue2 itcast3 itcastvalue3
MSETNX key value [key value ...] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
示例:MSETNX itcast4 itcastvalue4 itcast5 itcastvalue5
PSETEX key milliseconds value这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
示例:PSETEX itcast6 6000 itcast6value
INCR key将 key 中储存的数字值增一。
示例:
set itcast7 1
INCR itcast7
INCR key将 key 中储存的数字值增一。
示例:
set itcast7 1
INCR itcast7
GET itcast7
INCRBY key increment将 key 所储存的值加上给定的增量值(increment) 。
示例:INCRBY itcast7 2
get itcast7
INCR key将 key 中储存的数字值增一。
示例:
set itcast7 1
INCR itcast7
GET itcast7
INCRBY key increment将 key 所储存的值加上给定的增量值(increment) 。
示例:INCRBY itcast7 2
get itcast7
DECR key将 key 中储存的数字值减一。
示例:
set itcast8 1
DECR itcast8
GET itcast8DECRBY key decrementkey 所储存的值减去给定的减量值(decrement) 。
示例:DECRBY itcast8 3
APPEND key value如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
示例: APPEND itcast8 helloRedis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)
下表列出了 redis hash 基本的相关命令:
HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。
示例:HSET key1 field1 value1
HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。
示例:HSETNX key1 field2 value2
HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。
示例:HMSET key1 field3 value3 field4 value4
HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。
示例:
HEXISTS key1 field4
HEXISTS key1 field6
HGET key field 获取存储在哈希表中指定字段的值。
示例:HGET key1 field4
HGETALL key 获取在哈希表中指定 key 的所有字段和值
示例:HGETALL key1
HKEYS key 获取所有哈希表中的字段
示例:HKEYS key1
HLEN key 获取哈希表中字段的数量
示例:HLEN key1
HMGET key field1 [field2] 获取所有给定字段的值
示例:HMGET key1 field1 field2
HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。
示例:
HSET key2 field1 1
HINCRBY key2 field1 1
HGET key2 field1
HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
示例:HINCRBYFLOAT key2 field1 0.8
HVALS key 获取哈希表中所有值
示例:HVALS key1
HDEL key field1 [field2] 删除一个或多个哈希表字段
示例:
HDEL key1 field1
HVALS key1
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
下表列出了列表相关的基本命令:
LPUSH key value1 [value2] 将一个或多个值插入到列表头部
示例:LPUSH list1 value1 value2
LRANGE key start stop
查看list当中所有的数据
示例:LRANGE list1 0 -1
LPUSHX key value 将一个值插入到已存在的列表头部
示例:LPUSHX list1 value3
LINDEX list1 0
RPUSH key value1 [value2] 在列表中添加一个或多个值
示例:
RPUSH list1 value4 value5
LRANGE list1 0 -1
RPUSHX key value 为已存在的列表添加值
示例:RPUSHX list1 value6
LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素
示例:LINSERT list1 BEFORE value3 beforevalue3
LINDEX key index 通过索引获取列表中的元素
示例:LINDEX list1 0
LSET key index value 通过索引设置列表元素的值
示例:LSET list1 0 hello
LLEN key 获取列表长度
示例:LLEN list1
LPOP key 移出并获取列表的第一个元素
示例:LPOP list1
RPOP key 移除列表的最后一个元素,返回值为移除的元素。
示例:RPOP list1
BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
示例:BLPOP list1 2000
BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
示例:BRPOP list1 2000
RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
示例:RPOPLPUSH list1 list2
BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
示例:BRPOPLPUSH list1 list2 2000
LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
示例:LTRIM list1 0 2
DEL key1 key2
删除指定key的列表
示例:DEL list2
redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
下表列出了 Redis 集合基本命令:
SADD key member1 [member2] 向集合添加一个或多个成员
示例:SADD set1 setvalue1 setvalue2
SMEMBERS key 返回集合中的所有成员
示例:SMEMBERS set1
SCARD key 获取集合的成员数
示例:SCARD set1
SDIFF key1 [key2] 返回给定所有集合的差集
示例:
SADD set2 setvalue2 setvalue3
SDIFF set1 set2
SDIFFSTORE destination key1 [key2] 返回给定所有集合的差集并存储在 destination 中
示例:SDIFFSTORE set3 set1 set2
SINTER key1 [key2] 返回给定所有集合的交集
示例:SINTER set1 set2
SINTERSTORE destination key1 [key2] 返回给定所有集合的交集并存储在 destination 中
示例:SINTERSTORE set4 set1 set2
SISMEMBER key member 判断 member 元素是否是集合 key 的成员
示例:SISMEMBER set1 setvalue1
SMOVE source destination member 将 member 元素从 source 集合移动到 destination 集合
示例:SMOVE set1 set2 setvalue1
SPOP key 移除并返回集合中的一个随机元素
示例:SPOP set2
SRANDMEMBER key [count] 返回集合中一个或多个随机数
示例:SRANDMEMBER set2 2
SREM key member1 [member2] 移除集合中一个或多个成员
示例:SREM set2 setvalue1
SUNION key1 [key2] 返回所有给定集合的并集
示例:SUNION set1 set2
SUNIONSTORE destination key1 [key2] 所有给定集合的并集存储在 destination 集合中
示例:SUNIONSTORE set5 set1 set2
下表给出了与 Redis 键相关的基本命令
DEL key该命令用于在 key 存在时删除 key。
示例:del itcast5
DUMP key 序列化给定 key ,并返回被序列化的值。
示例:DUMP key1
EXISTS key 检查给定 key 是否存在。
示例:exists itcast
EXPIRE key seconds为给定 key 设置过期时间,以秒计。
示例:expire itcast 5
PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。
示例:PEXPIRE set2 3000000
KEYS pattern 查找所有符合给定模式( pattern)的 key 。
示例:keys *
PERSIST key 移除 key 的过期时间,key 将持久保持。
示例:persist set2
PTTL key 以毫秒为单位返回 key 的剩余的过期时间。
示例:pttl set2
TTL key 以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
示例:ttl set2
RANDOMKEY 从当前数据库中随机返回一个 key 。
示例: randomkey
RENAME key newkey 修改 key 的名称
示例:rename set5 set8
RENAMENX key newkey 仅当 newkey 不存在时,将 key 改名为 newkey 。
示例:renamenx set8 set10
TYPE key 返回 key 所储存的值的类型。
示例:type set10
由于redis是一个内存数据库,所有的数据都是保存在内存当中的,内存当中的数据极易丢失,所以redis的数据持久化就显得尤为重要,在redis当中,提供了两种数据持久化的方式,分别为RDB以及AOF,且redis默认开启的数据持久化方式为RDB方式,接下来我们就分别来看下两种方式的配置吧
Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。可以在配置文件中配置Redis进行快照保存的时机:
save [seconds] [changes]
意为在[seconds]秒内如果发生了[changes]次数据修改,则进行一次RDB快照保存,例如
save 60 100
会让Redis每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。可以配置多条save指令,让Redis执行多级的快照保存策略。Redis默认开启RDB快照。也可以通过SAVE或者BGSAVE命令手动触发RDB快照保存。
SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同:
SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。cd /export/servers/redis-3.2.8/
vim redis.conf
save 900 1
save 300 10
save 60 10000
save 5 1
重新启动redis服务
每次生成新的dump.rdb都会覆盖掉之前的老的快照
ps -ef | grep redis
kill -9 69632 74217
src/redis-server redis.conf
AOF方案介绍:
采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:
appendonly yes
AOF提供了三种fsync配置,always/everysec/no,通过配置项[appendfsync]指定:
appendfsync no:不进行fsync,将flush文件的时机交给OS决定,速度最快appendfsync always:每写入一条日志就进行一次fsync操作,数据安全性最高,但速度最慢
appendfsync everysec:折中的做法,交由后台线程每秒fsync一次
随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。
AOF rewrite可以通过BGREWRITEAOF命令触发,也可以配置Redis定期自动进行:
auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
上面两行配置的含义是,Redis在每次AOF rewrite时,会记录完成rewrite后的AOF日志大小,当AOF日志大小在该基础上增长了100%后,自动进行AOF rewrite。同时如果增长的大小没有达到64mb,则不会进行rewrite。
AOF的缺点:
AOF文件通常比RDB文件更大性能消耗比RDB高数据恢复速度比RDB慢Redis的数据持久化工作本身就会带来延迟,需要根据数据的安全级别和性能要求制定合理的持久化策略:
AOF + fsync always的设置虽然能够绝对确保数据安全,但每个操作都会触发一次fsync,会对Redis的性能有比较明显的影响
AOF + fsync every second是比较好的折中方案,每秒fsync一次
AOF + fsync never会提供AOF持久化方案下的最优性能使用RDB持久化通常会提供比使用AOF更高的性能,但需要注意RDB的策略配置
每一次RDB快照和AOF Rewrite都需要Redis主进程进行fork操作。fork操作本身可能会产生较高的耗时,与CPU和Redis占用的内存大小有关。根据具体的情况合理配置RDB快照和AOF Rewrite时机,避免过于频繁的fork带来的延迟
Redis在fork子进程时需要将内存分页表拷贝至子进程,以占用了24GB内存的Redis实例为例,共需要拷贝24GB / 4kB * 8 = 48MB的数据。在使用单Xeon 2.27Ghz的物理机上,这一fork操作耗时216ms。
在redis中,aof的持久化机制默认是关闭的
AOF持久化,默认是关闭的,默认是打开RDB持久化
appendonly yes,可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓
打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下
而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整
可以配置AOF的fsync策略,有三种策略可以选择,一种是每次写入一条数据就执行一次fsync; 一种是每隔一秒执行一次fsync; 一种是不主动执行fsync
always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了
在redis当中默认的AOF持久化机制都是关闭的
配置redis的AOF持久化机制方式
cd /export/servers/redis-3.2.8
vim redis.conf
appendonly yes
# appendfsync always
appendfsync everysec
# appendfsync no
