redis当中一共支持五种数据类型,分别是string字符串类型,list列表类型,集合set类型,hash表类型以及有序集合zset类型,通过这五种不同的数据类型,我们可以实现各种不同的功能,也可以应用与各种不同的场景,接下来我们来看看五种数据类型的操作语法
redis当中各种数据类型结构如上图:
、redis当中对字符串string的操作
下表列出了常用的 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 itcast8
DECRBY key decrement
key 所储存的值减去给定的减量值(decrement) 。示例:DECRBY itcast8 3
APPEND key value
示例: APPEND itcast8 hello
如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
redis当中对hash列表的操作
Redis 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当中对list列表的操作
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集合
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中对key的操作
下表给出了与 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的数据持久化就显得尤为重要,在redis当中,提供了两种数据持久化的方式,分别为RDB以及AOF,且redis默认开启的数据持久化方式为RDB方式,接下来我们就分别来看下两种方式的配置吧
RDB持久化方案介绍
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 执行期间仍然可以继续处理客户端的请求。
RDB方案优点
- 对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
- 每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。
- 使用RDB文件进行数据恢复比使用AOF要快很多
RDB方案缺点
- 快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。
- 如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
RDB方案配置
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方案介绍:
采用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优点:
- 最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据
- AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。
- AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
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。
AOF方案配置
在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