String类型
1 . 赋值 语法:SET key value
127.0.0.1:6379> set test 1
OK
2 . 取值 语法:GET key
127.0.0.1:6379> get test
"1"
3 . 设置多个值 语法:mset key value [key value…]
127.0.0.1:6379> mset id 1 name zhangsan age 14
OK
4 .获取多个值 语法:mget key [key…]
127.0.0.1:6379> mget id name age
1) "1"
2) "zhangsan"
3) "14"
5 . 取值并赋值 语法:getset key value
127.0.0.1:6379> getset name lisi
"zhangsan"
127.0.0.1:6379> get name
"lisi"
6 .删除 语法:del key
7 . 递增
当存储的数字是整数的时候,Redis提供了一个实用的命令INCR,其作用是让当前键值递增,并返回递增后的值。
语法:incr key
127.0.0.1:6379> incr id
(integer) 2
127.0.0.1:6379>
127.0.0.1:6379> incr id
(integer) 3
127.0.0.1:6379> incr id
(integer) 4
127.0.0.1:6379> incr id
(integer) 5
127.0.0.1:6379> incr id
(integer) 6
8 . 指定增加的整数 语法: incrby key increment
127.0.0.1:6379> incrby id 2
(integer) 10
127.0.0.1:6379>
127.0.0.1:6379> incrby id 2
(integer) 12
127.0.0.1:6379> incrby id 2
(integer) 14
9 . 递减数值 语法:decr key
127.0.0.1:6379> decr id
(integer) 13
127.0.0.1:6379> decr id
(integer) 12
10 . 减少指定的整数 语法:decrby key decrement
127.0.0.1:6379> set str hello
OK
127.0.0.1:6379> get str
"hello"
127.0.0.1:6379> append str world
(integer) 10
127.0.0.1:6379> get str
"helloworld"
11 . 获取字符串的长度 语法: strlen key
STRLEN命令返回键值的长度,如果键不存在则返回0。
127.0.0.1:6379> strlen str
(integer) 10
hash类型
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下:
保存、更新:
User对象 json(string) redis 如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,hash可以很好的解决这个问题。
hash叫散列类型,它提供了字段和字段值的映射。字段值只能是字符串类型,不支持散列类型、集合类型等其它类型.key value {key value} value必须是string类型
1 . 赋值 语法: hset key field value
HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0
127.0.0.1:6379> hset user username zhangsan
(integer) 1
127.0.0.1:6379> hset user username lisi
(integer) 0
2.设置多个字段 语法: hmsethmset key field value [field value …]
127.0.0.1:6379> hmset use name lisi age 20
OK
3.当字段不存在时赋值,类似HSET,如果字段存在,不执行任何操作返回0, 语法:hsetnx key field value
127.0.0.1:6379> hsetnx user username wangwu
(integer) 0
4 . 取值 语法:hget key field
127.0.0.1:6379> hget user username
"lisi"
5.取得多个字段值 语法:hmget key field [field …]
127.0.0.1:6379> hmget user username age
1) "lisi"
2) "20"
6.取得所有字段值 语法:hgetall key
127.0.0.1:6379> hgetall user
1) "username"
2) "lisi"
3) "age"
4) "20"
7.删除字段(一个或多个) 语法:hdel key field [field …]
8.增加数字 语法:hincrby key field increment
127.0.0.1:6379> hincrby user age 2
(integer) 22
127.0.0.1:6379> hincrby user age 2
(integer) 24
9.判断字段是否存在 语法:hexists key field
127.0.0.1:6379> hexists user age
(integer) 1
127.0.0.1:6379> hexists user name
(integer) 0
10.只获取字段名或字段值 语法:
HKEYS key
HVALS key
127.0.0.1:6379> hkeys user
1) "username"
2) "age"
127.0.0.1:6379> hvals user
1) "lisi"
2) "24"
11.获取字段的数量 语法:
127.0.0.1:6379> hlen user
(integer) 2
list类型
列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
1 .向列表两端增加元素
1.1 向列表左边增加元素 语法:lpush key value [value …]
127.0.0.1:6379> lpush list 1 1 2 3 3
(integer) 5
1.2 向列表右边增加元素 语法:rpush key value [value …]
127.0.0.1:6379> rpush list 5 5 7 8
(integer) 9
2 .查看列表 语法:lrange key start stop
LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),
索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。
127.0.0.1:6379> lrange list 0 9
1) "3"
2) "3"
3) "2"
4) "1"
5) "1"
6) "5"
7) "5"
8) "7"
9) "8"
3 .从列表两端弹出元素 语法:lpop key rpop key
LPOP命令从列表左边弹出一个元素,会分两步完成:
第一步是将列表左边的元素从列表中移除
第二步是返回被移除的元素值。
127.0.0.1:6379> lpop list
"3"
127.0.0.1:6379> rpop list
"8"
127.0.0.1:6379>
4 .获取列表中元素的个数 语法:llen key
127.0.0.1:6379> llen list
(integer) 7
5 .删除列表中指定的值 语法:lrem key count value
LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同:
- 当count>0时, LREM会从列表左边开始删除。
- 当count<0时, LREM会从列表后边开始删除。
- 当count=0时, LREM删除所有值为value的元素。
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"
4) "1"
5) "5"
6) "5"
7) "7"
127.0.0.1:6379> lrem list 1 1
(integer) 1
127.0.0.1:6379> lrem list -1 5
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "3"
2) "2"
3) "1"
4) "5"
5) "7"
6.1 获得/设置指定索引的元素值 语法: lindex key index
127.0.0.1:6379> lindex list 0
"3"
6.2 设定指定索引元素的值 语法:lset key index value
127.0.0.1:6379> lset list 0 1
OK
7 . 只保留指定片段 语法:ltrim list start stop
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "2"
3) "1"
4) "5"
5) "7"
127.0.0.1:6379> ltrim list 1 3
OK
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "5"
8 .向列表中插入元素 语法:linsert key BEFORE|AFTER pivot value
该命令首先会在列表中从左到右查找值为pivot的元素,
然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "5"
127.0.0.1:6379> linsert list before 1 1
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "1"
4) "5"
127.0.0.1:6379> linsert list after 1 6
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "6"
4) "1"
5) "5"
127.0.0.1:6379>
9 . 将元素从一个列表转移到另一个列表中 语法:rpoplpush source destination
127.0.0.1:6379> rpoplpush list newlist
"5"
127.0.0.1:6379> lrange newlist 0 -1
1) "5"
127.0.0.1:6379> rpoplpush list newlist
"1"
127.0.0.1:6379> lrange newlist 0 -1
1) "1"
2) "5"
set类型
set类型 | list类型 | |
有序性 | 否 | 是 |
唯一性 | 是 | 否 |
集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。
Redis还提供了多个集合之间的交集、并集、差集的运算。
1 .增加元素 语法:sadd key member [member …]
127.0.0.1:6379> sadd set a b c
(integer) 1
2 .获得集合中的所有元素 语法:smembers key
127.0.0.1:6379> smembers set
1) "c"
2) "b"
3) "a"
3 .删除元素 语法:srem key member [member …]
127.0.0.1:6379> srem set a b
(integer) 2
4 .判断元素是否在集合中 语法:sismember key member
存在返回1,不存在返回0
127.0.0.1:6379> sismember set c
(integer) 1
5 .差运算 语法:sdiff key [key …]
127.0.0.1:6379> sadd setA a b c
(integer) 3
127.0.0.1:6379> sadd setB a d b
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) "c"
6 .交运算 语法:sinter key [key …]
127.0.0.1:6379> sinter setA setB
1) "b"
2) "a"
7 .并运算 语法: sunion key [key …]
127.0.0.1:6379> sunion setA setB
1) "b"
2) "c"
3) "a"
4) "d"
8 .获得集合中元素的个数 语法:scard setA
127.0.0.1:6379> scard setA
(integer) 3
9 .从集合中弹出一个元素 语法:spop key [count]
由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出
127.0.0.1:6379> spop setA 1
1) "a"
zset类型
SortedSet类型zset ,在集合类型的基础上,有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。
在某些方面有序集合和列表类型有些相似。
1、二者都是有序的。
2、二者都可以获得某一范围的元素。
但是,二者有着很大区别:
1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。
2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。
3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现)
4、有序集合要比列表类型更耗内存。
1 .增加元素 语法:zadd key score member [score member …]
向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
127.0.0.1:6379> zadd zset 20 lisi 30 zhangsan 50 wangwu
(integer) 3
127.0.0.1:6379> zadd zset 80 lisi
(integer) 0
2 .获取元素的分数 语法:zscore key member
127.0.0.1:6379> zscore zset lisi
"80"
3 .删除元素 语法:zrem key member [member …]
移除有序集key中的一个或多个成员,不存在的成员将被忽略。
当key存在但不是有序集类型时,返回一个错误
4 .获得排名在某个范围的元素列表
4.1按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
语法:zrange key start stop [WITHSCORES]
127.0.0.1:6379> zrange zset 0 2
1) "zhangsan"
2) "wangwu"
3) "lisi"
4.2按照元素分数从大到小的顺序返回索引从start到stop之间的所有元素(包含两端的元素)
语法:zrevrange key start stop [WITHSCORES]
127.0.0.1:6379> zrevrange zset 0 2
1) "lisi"
2) "wangwu"
3) "zhangsan"
4.3如果需要获得元素的分数的可以在命令尾部加上WITHSCORES参数
127.0.0.1:6379> zrange zset 0 2 withscores
1) "zhangsan"
2) "30"
3) "wangwu"
4) "50"
5) "lisi"
6) "80"
5 .获取指定分数范围的元素 语法:zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
127.0.0.1:6379> zrangebyscore zset 20 50 withscores
1) "zhangsan"
2) "30"
3) "wangwu"
4) "50"
127.0.0.1:6379> zrangebyscore zset 20 50 limit 1 2
1) "wangwu"
6 .增加元素的分数 语法:zincrby key increment member
127.0.0.1:6379> zincrby zset 2 zhangsan
"32"
127.0.0.1:6379> zincrby zset 2 zhangsan
"34"
7 .获取集合中元素的个数 语法:zcard key
127.0.0.1:6379> zcard zset
(integer) 3
8 .获得指定分数范围内的元素个数 语法:zcount key min max
127.0.0.1:6379> zcount zset 20 50
(integer) 2
9 .获取元素排名(索引)
9.1 从小到大 语法:zrank key member
127.0.0.1:6379> zrank zset zhangsan
(integer) 0
127.0.0.1:6379> zrank zset wangwu
(integer) 1
9.2从大到小 语法:zrevrank key member
127.0.0.1:6379> zrevrank zset zhangsan
(integer) 2
10 .按照元素范围删除元素 语法:zremrangebyscore key min max
11 .按照排名范围删除元素 语法:zremrangebyrank key start stop
keys命令
1 . keys 返回满足给定pattern 的所有key
127.0.0.1:6379> mset test1 1 test2 2 test3 3 test4 4
OK
127.0.0.1:6379> keys test*
1) "test2"
2) "test4"
3) "test3"
4) "test1"
2 . exists key [key …] 确认一个key 是否存在, 存在返回1,不存在返回0
127.0.0.1:6379> exists test1
(integer) 1
127.0.0.1:6379> exists test5
(integer) 0
127.0.0.1:6379>
3.重命名 rename key newkey
4 . 获取返回值类型 type
127.0.0.1:6379> type zset
zset
127.0.0.1:6379> type setB
set
127.0.0.1:6379> type user
hash
127.0.0.1:6379> type id
string
127.0.0.1:6379>
5 .
EXPIRE key seconds 设置key的生存时间(单位:秒)key在多少秒后会自动删除
TTL key 查看key生于的生存时间
PERSIST key 清除生存时间
PEXPIRE key milliseconds 生存时间设置单位为:毫秒
127.0.0.1:6379> expire test 10 //设置生存时间为10秒
(integer) 1
127.0.0.1:6379> ttl test //查看生存剩余时间 还剩5秒
(integer) 5
127.0.0.1:6379> ttl test
(integer) 3
127.0.0.1:6379> ttl test
(integer) 1
127.0.0.1:6379> ttl test
(integer) -2
127.0.0.1:6379> get test
(nil)
127.0.0.1:6379>
Redis持久化方案
RDB 持久化
RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。
RDB是Redis默认采用的持久化方式。
- 持久化配置
在 redis.conf文件中, save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系。
save 900 1 //表示15分钟(900秒钟)内至少1个键被更改则进行快照。
save 300 10 //表示5分钟(300秒)内至少10个键被更改则进行快照。
save 60 10000 //表示1分钟(60秒)内至少10000个键被更改则进行快照。
- 配置快照文件目录
# Note that you must specify a directory here, not a file name.
dir ./
- 配置快照文件的名称
设置dbfilename指定rdb快照文件的名称
# The filename where to dump the DB
dbfilename dump.rdb
- 使用默认的rdb持久化方案会出现的问题
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化
AOF持久化
使用AOF持久化,每修改一次数据库都会进行一次持久化,默认情况下Redis没有开启AOF(append only file)方式的持久化。
1 . 可以通过修改redis.conf配置文件中的appendonly参数开启
appendonly yes
2 . 开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬 盘中的AOF文件。
3 . AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。
dir ./
4 .默认的文件名是appendonly.aof,可以通过appendfilename参数修改:
appendfilename appendonly.aof