Redis基础知识(一)(下)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis基础知识(一)

哈希


哈希是由与值关联的字段组成的映射。字段和值都是字符串,哈希类型中的映射关系叫作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操作


640.png


是否对快照数据进行压缩存储


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持久化流程


  1. 所有的写入命令会追加到aof_buf(缓冲区)中。
  2. AOF缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
  4. 当Redis服务器重启时,可以加载AOF文件进行数据恢复


AOF持久化策略


  1. appendfsync always:
    每次将新命令附加到AOF时。
    虽然很慢,但是数据不会丢失
  2. appendfsync everysec:
    每秒钟保存一次。
    如果发生灾难,可能会丢失1秒的数据。
  3. 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


640.png


是否在后台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进行数据恢复


欢迎各位一起交流

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6月前
|
存储 缓存 NoSQL
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化
|
6月前
|
存储 缓存 NoSQL
Redis 基础知识和核心概念解析:理解 Redis 的键值操作和过期策略
Redis 基础知识和核心概念解析:理解 Redis 的键值操作和过期策略
74 1
|
6月前
|
存储 缓存 NoSQL
Redis 基础知识和核心概念解析:探索 Redis 的数据结构与存储方式
Redis 基础知识和核心概念解析:探索 Redis 的数据结构与存储方式
90 0
|
7月前
|
存储 缓存 NoSQL
【Redis从头学-14】一文带你学会Redis Cluster集群模式、数据分片基础知识以及三主三从结构分片集群搭建全过程
【Redis从头学-14】一文带你学会Redis Cluster集群模式、数据分片基础知识以及三主三从结构分片集群搭建全过程
80 0
|
10月前
|
存储 NoSQL API
【Redis基础知识 十】Redis底层数据编码之压缩列表
【Redis基础知识 十】Redis底层数据编码之压缩列表
67 0
|
10月前
|
NoSQL 安全 API
【Redis基础知识 九】Redis底层数据编码之整数集合
【Redis基础知识 九】Redis底层数据编码之整数集合
55 0
|
10月前
|
存储 NoSQL API
【Redis基础知识 八】Redis底层数据编码之跳跃表
【Redis基础知识 八】Redis底层数据编码之跳跃表
65 0
|
10月前
|
NoSQL 算法 Serverless
【Redis基础知识 七】Redis底层数据编码之字典
【Redis基础知识 七】Redis底层数据编码之字典
58 0
|
10月前
|
缓存 NoSQL API
【Redis基础知识 六】Redis底层数据编码之链表
【Redis基础知识 六】Redis底层数据编码之链表
37 0
【Redis基础知识 六】Redis底层数据编码之链表
|
10月前
|
存储 NoSQL 安全
【Redis基础知识 五】Redis底层数据编码之动态字符串
【Redis基础知识 五】Redis底层数据编码之动态字符串
67 0

热门文章

最新文章