哈希
哈希是由与值关联的字段组成的映射。字段和值都是字符串,哈希类型中的映射关系叫作field-value
设值取值
hset key field value hget key field
例如:
127.0.0.1:6379> hset ha name wanger (integer) 1 127.0.0.1:6379> hget ha name "wanger"
批量设值取值
hmset key field1 value1 field2 value2 hmget key field1 field2
例如:
127.0.0.1:6379> hmset he name wanger sex nan OK 127.0.0.1:6379> hmget he name sex 1) "wanger" 2) "nan"
删除field
hdel key field1 field2
例如:
127.0.0.1:6379> hdel he name (integer) 1 127.0.0.1:6379> hget he name (nil)
获取field个数
hlen key
例如:
127.0.0.1:6379> hmset he name wanger sex nan age 18 OK 127.0.0.1:6379> hlen he (integer) 3
获取哈希中的所有字段和值
hgetall key
例如:
127.0.0.1:6379> hgetall he 1) "sex" 2) "nan" 3) "name" 4) "wanger" 5) "age" 6) "18"
获取哈希中的所有字段
hkeys key
例如:
127.0.0.1:6379> hkeys he 1) "sex" 2) "name" 3) "age"
判断哈希字段是否存在
hexists key field
例如:
127.0.0.1:6379> hexists he name (integer) 1 127.0.0.1:6379> hexists he sex (integer) 1
将哈希字段的值递增
hincrby key field increment
例如:
127.0.0.1:6379> hincrby asd asdf 2 (integer) 3 127.0.0.1:6379> hget asd asdf "3" 127.0.0.1:6379> hincrby asd asdf 2 (integer) 5 127.0.0.1:6379> hget asd asdf "5"
获取哈希中的所有值
hvals key
例如:
127.0.0.1:6379> hvals he 1) "nan" 2) "wanger" 3) "18"
内部编码:
- ziplist(压缩列表):
当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。 - hashtable(哈希表):
当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)
例如:
127.0.0.1:6379> hset ziplist hash 12335452335235fwgvsfwbhfbwhhfwuesrfhwueywhufgbrewfghusfhwueughsajkifo34ejigji (integer) 1 127.0.0.1:6379> hmset hash asd fcfg zdf fty OK
集合
唯一且无序的字符串元素的集合。
将一个或多个成员添加到集合中
sadd key member1 member2
例如
127.0.0.1:6379> sadd set s1 s2 (integer) 0
获取集合所有值
smembers key
例如:
127.0.0.1:6379> smembers set 1) "s2" 2) "s1" 3) "s3"
删除集合的元素
srem key member1 members2
例如:
127.0.0.1:6379> srem set s2 (integer) 1 127.0.0.1:6379> smembers set 1) "s1" 2) "s3"
获取元素的长度
scard key
例如:
127.0.0.1:6379> scard set (integer) 2
随机获取指定个数的元素
srandmember key [count]
例如:
127.0.0.1:6379> srandmember set 1 1) "s1"
判断元素是否在集合中
sismember key member
例如:
127.0.0.1:6379> sismember set s2 (integer) 0 127.0.0.1:6379> sismember set s3 (integer) 1
从集合中弹出指定数量的元素
spop key [count]
例如:
127.0.0.1:6379> smembers set 1) "s5" 2) "s4" 3) "s1" 4) "s3" 127.0.0.1:6379> spop set "s4" 127.0.0.1:6379> spop set 3 1) "s5" 2) "s1" 3) "s3" 127.0.0.1:6379> smembers set (empty list or set)
集合间的并集运算
sunion key1 key2
例如:
127.0.0.1:6379> sadd set1 1 2 3 (integer) 3 127.0.0.1:6379> sadd set2 2 3 4 5 (integer) 4 127.0.0.1:6379> sunion set1 set2 1) "1" 2) "2" 3) "3" 4) "4" 5) "5"
集合间的交集运算
sinter key1 key2
例如:
127.0.0.1:6379> sinter set1 set2 1) "2" 2) "3"
集合间的差集运算
sdiff key1 key2
例如:
127.0.0.1:6379> sdiff set1 set2 1) "1" 127.0.0.1:6379> sdiff set2 set1 1) "4" 2) "5"
内部编码
- intset(整数集合):
当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。 - hashtable(哈希表):
当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
例如:
127.0.0.1:6379> sadd set3 s1 s2 s3 (integer) 3 127.0.0.1:6379> object encoding set3 "hashtable" 127.0.0.1:6379> sadd set4 1 2 3 (integer) 3 127.0.0.1:6379> object encoding set4 "intset"
有序集合
每个字符串元素都与一个称为score的浮点值相关联。元素总是按它们的分数排序,因此与Sets不同,可以检索一系列元素
添加元素
zadd key [NX|XX] [CH] [INCR] score1 member1 score2 member2
例如:
127.0.0.1:6379> zadd score xx 80 wanger 80 huazai 95 dongdong +inf a (integer) 0 127.0.0.1:6379> zrange score 0 -1 1) "huazai" 2) "wanger" 3) "dongdong" 4) "a" +inf和-inf分别表示正无穷和负无穷
获取某个成员的分数
zscore key member
例如:
127.0.0.1:6379> zscore score dongdong "95"
对成员进行排名,从0开始
zrange key start end [withscores] #升序排列 zrevrange key start end [withscores] #降序排列
例如:
127.0.0.1:6379> zadd score 95 huazai 90 wanger 85 dongdong +inf a (integer) 0 127.0.0.1:6379> zrank score huazai (integer) 2 127.0.0.1:6379> zrevrank score huazai (integer) 1 127.0.0.1:6379> zrevrank score a (integer) 0 127.0.0.1:6379> zrange score 0 -1 WITHSCORES 1) "dongdong" 2) "85" 3) "wanger" 4) "90" 5) "huazai" 6) "95" 7) "a" 8) "inf"
获取成员个数
zcard key
例如:
127.0.0.1:6379> zcard score (integer) 4
删除成员
zrem key member1 member2
例如:
127.0.0.1:6379> zrem score dongdong (integer) 1 127.0.0.1:6379> zrange score 0 -1 1) "wanger" 2) "huazai" 3) "a"
增加成员的分数
zincrby key increment member
例如:
127.0.0.1:6379> zincrby score 5 wanger "95"
获取指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count] #升序 zrevrangebyscore key max min [withscores] [limit offset count] #降序
例如:
127.0.0.1:6379> zrangebyscore score 80 90 withscores 1) "dongdong" 2) "85" 3) "wanger" 4) "90" 127.0.0.1:6379> zrevrangebyscore score 95 80 withscores 1) "huazai" 2) "95" 3) "wanger" 4) "90" 5) "dongdong" 6) "85"
获取指定分数范围成员个数
zcount key min max
例如:
127.0.0.1:6379> zcount score 85 95 (integer) 3
删除指定分数范围的成员
zremrangebyscore key min max
例如:
127.0.0.1:6379> zremrangebyscore score 85 90 (integer) 2
有序集合的交集运算
zinterstore destination numkeys key1 key2 [WEIGHTS weight]
- destination:
交集计算结果保存到这个键。 - numkeys:
需要做交集计算键的个数。 - key[key…]:
需要做交集计算的键。 - weights weight[weight…]:
每个键的权重,在做交集计算时,每个键中 - 的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
- aggregate sum|min|max:
计算成员交集后,分值可以按照sum(和)、 - min(最小值)、max(最大值)做汇总,默认值是sum。
最终的结果就是权重乘分数,之后再进行聚合
例如:
127.0.0.1:6379> zadd user 10 wanger 20 huazai 30 dongdong (integer) 3 127.0.0.1:6379> zadd user1 15 wanger 35 huazai (integer) 2 127.0.0.1:6379> zinterstore userset 2 user user1 (integer) 2 127.0.0.1:6379> zrange userset 0 -1 withscores 1) "wanger" 2) "25" 3) "huazai" 4) "55" 127.0.0.1:6379> zinterstore user2set 2 user user1 weights 1 0.5 aggregate min (integer) 2 127.0.0.1:6379> zrange user2set 0 -1 withscores 1) "wanger" 2) "7.5" 3) "huazai" 4) "17.5"
有序集合的并集计算
zunionstore destination numkeys key [key ...] [WEIGHTS weight]
例如:
127.0.0.1:6379> zadd user 10 wanger 20 huazai 30 dongdong (integer) 3 127.0.0.1:6379> zadd user1 15 wanger 35 huazai (integer) 2 127.0.0.1:6379> zunionstore user3set 2 user user1 weights 1 0.5 aggregate max (integer) 3 127.0.0.1:6379> zrange user3set 0 -1 withscores 1) "wanger" 2) "10" 3) "huazai" 4) "20" 5) "dongdong" 6) "30"
内部编码
- ziplist(压缩列表):
当有序集合的元素小于zset-max-ziplist-entries配置(默认是128个),同时每个元素的值都小于zset-max-ziplist-value(默认是64字节)时,Redis会用ziplist来作为有序集合的内部编码实现,ziplist可以有效的减少内存的使用 - skiplist(跳跃表):
当ziplist的条件不满足时,有序集合将使用skiplist作为内部编码的实现,来解决此时ziplist造成的读写效率下降的问题.
例如:
127.0.0.1:6379> zadd sortset1 10 a 20 b 30 c (integer) 3 127.0.0.1:6379> object encoding sortset1 "ziplist" 127.0.0.1:6379> zadd sortset2 10 a 20 b 30 cddddddddddddddddddddddffffffffffffffffffffffffwfwfwggggggggggggggggggwg4yhhhhhhhhhhhhhhhh (integer) 3 127.0.0.1:6379> object encoding sortset2 "skiplist"
Redis持久化
redis提供了两种持久化的方法来将数据以二进制的方式存储到硬盘,一种为在某一时刻生成快照的RDB持久化,另一种为将写入命令追加到aof的持久化文件的持久化
RDB
在 Redis 运行时,RDB 程序将当前内存中的数据库快照保存到磁盘文件中,在 Redis 重启动
时,RDB 程序可以通过载入 RDB 文件来还原数据库的状态。RDB文件非常适合备份以及用于灾难恢复
rdb持久化的过程
- Redis 会fork 一个子进程。
这样就有了一个子进程和一个父过程。 - 子进程开始将数据集写入临时RDB文件。
- 当子进程完成新的RDB文件的写入后,它将替换旧的RDB文件。
rdb分为手动触发和自动触发,自动触发需要在配置文件中定义
自动触发
rdb持久化默认在配置文件中开启的
vim /etc/redis/6379.conf
此配置表示在15分钟内至少修改一次,或者在5分钟内至少修改十次,或者在1分钟内修改10000次会触发rdb操作
是否对快照数据进行压缩存储
rdbcompression yes
是否使用CRC64算法进行数据校验,如果开启那么将增加10的性能消耗
rdbchecksum yes
指定生成的文件名
dbfilename dump.rdb
指定文件存放的目录
dir /var/lib/redis/6379
手动触发
rdb的手动触发需要手动调用SAVE或BGSAVE命令
- SAVE命令:
在当前进程执行,阻塞当前Redis服务器,直到RDB过程完成为止,在主进程阻塞期间,服务器不能处理客户端的任何请求。 - BGSAVE命令:
当前进程会 fork 出一个子进程,父进程继续处理请求,子进程开始将数据写入临时RDB文件 ,并在保存完成之后向主进程发送信号,通知保存已完成。
因为在子进程被调用,所以 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求
AOF
AOF持久性会记录服务器接收的每个写入操作,这些操作将在服务器启动时再次运行,以重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且采用仅追加方式。当日志太大时,Redis可以在后台重写日志。AOF的主要作用是解决了数据持久化的实时性
AOF持久化流程
- 所有的写入命令会追加到aof_buf(缓冲区)中。
- AOF缓冲区根据对应的策略向硬盘做同步操作。
- 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
- 当Redis服务器重启时,可以加载AOF文件进行数据恢复
AOF持久化策略
- appendfsync always:
每次将新命令附加到AOF时。
虽然很慢,但是数据不会丢失 - appendfsync everysec:
每秒钟保存一次。
如果发生灾难,可能会丢失1秒的数据。 - appendfsync no:
不主动进行同步操作,由操作系统来完成。
更快,更不安全的方法。
通常,Linux使用此配置每30秒刷新一次数据,但这取决于内核的精确调整。
默认采用everysec模式
AOF重写
当AOF太大时,Redis会简单地从头开始将其重写到临时文件中。重写不是通过读取旧的文件,而是由Redis fork一个子进程直接访问内存中的数据,将其转换为写命令同步到新的aof文件,因此Redis可以创建更小的AOF文件,并且在写入新的AOF时不需要读取磁盘。
重写终止后,临时文件将被fsync同步在磁盘上,并覆盖旧的AOF文件。
当aof被重写的过程中又有新数据写入怎么办?这可能会导致数据不一致
新写入的数据会放到旧的aof文件里,同时也会追加到aof的重写缓冲区中,最后替换掉旧的aof文件
AOF配置持久化
vim /etc/redis/6379.conf
是否在后台aof文件重写期间调用fsync,默认为no,表示调用
no-appendfsync-on-rewrite no
当前aof文件增长量超过上次afo文件大小的100%时,则触发rewrite,如果为0,则禁用自动触发重写
auto-aof-rewrite-percentage 100
aof文件重写最小的文件大小,低于这个值将不会触发重写操作
auto-aof-rewrite-min-size 64mb
当子进程重写AOF文件时,每生成32 MB的数据,文件就会把数据落盘,防止单次文件数据过大造成阻塞
aof-rewrite-incremental-fsync yes
使用rdb和aof混合持久化方式,会将aof重写操作时的数据状态保存为rdb格式,而重写之后的redis命令会继续追加到rdb数据之后
aof-use-rdb-preamble yes
rdb与aof同时存在时,优先使用aof进行数据恢复
欢迎各位一起交流