reiss-持久化、数据类型、消息队列

1.持久化

redis虽然是一个内存级别的缓存程序,即redis是使用内存进行数据的缓存,但是其可以将内存的数据按照一定的策
略保存到硬盘上,从而实现数据持久保存的目的,redis支持两种不同方式的数据持久化保存机制,分别是RDB和AOF

1.1RDB

RDB基于时间的快照,只保留当前最新的一次快照
#特点
执行速度比较快
#缺点
可能会丢失从上次快照到当前快照未完成之间的数据。

#RDB实现的具体过程:
Redis从主进程先fork出一个子进程,使用写时复制机制,子进程将内存的数据保存为一个临时文件,比如dump.rdb.temp,
当数据保存完成之后再将上一次保存的RDB文件替换掉,
然后关闭子进程,
这样可以保证每一次做RDB快照的时候保存的数据都是完整的,因为直接替换RDB文件的时候可能会出现突然断电等问
题而导致RDB文件还没有保存完整就突然关机停止保存而导致数据丢失的情况,可以手动将每次生成的RDB文件进程备
份,这样可以最大化保存历史数据。

#优点:
(1)RDB快照保存了某个时间点的数据,可以通过脚本执行bgsave非阻塞或者save(阻塞)命令自定义时间点备份,可以
保留多个备份,当出现问题可以恢复到不同时间点的版本。
(2)可以最大化IO的性能,因为父进程在保存RDB文件的时候唯一要做的是fork出一个子进程,然后的操作都会由这个
子进程操作,父进程无需任何的IO操作
(3)RDB在大量数据比如几个G的数据,恢复的速度比AOF的快

#缺点
(1)不能时时的保存数据,会丢失自上一次执行RDB备份到当前的内存数据
(2)数据量非常大的时候,从父进程fork的时候需要一点时间,可能是毫秒或者秒

写时复制原理(copy-on-write)

写时复制一般是用来节省内存的使用,一般用于读多写少的情况,用于提高读取数据的效率
注意的是:读数据并不能保证实时性,因为读取时,读取的是旧数组的数据
缺点:占用内存(每添加一次就需要复制一个数据),和数据一致性问题(不能保证实时数据)

写的时候会复制一份数据,等处理完毕会把新数组覆盖旧数组

对象涉及到内存的分配而且需要频繁拷贝对象,这时候写实复制就有很大的用处。

1.2AOF

AOF:按照操作顺序依次将操作添加到指定的日志文件当中,
特点:是数据安全性相对较高;
缺点:是即使有些操作是重复的也会全部记录。

#AOF和RDB一样使用了写时复制机制
AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF文件当中,这样即使redis服务器发生故障的话,顶多也就
丢失1秒钟之内的数据,也可以设置不同的fsync策略,
或者设置每次执行命令的时候执fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受到
写入AOF文件的IO影响

AOF的文件大小要大于RDB格式的文件,根据所使用的fsync策略(fsync是同步内存中redis所有已经修改的文件到存
储设备),默认是appendfsync everysec 即每秒执行一次fsync

2.数据类型

数据类linux型参考:数据类型用于说明数据在计算机中​​http://wlinux删除文件命令ww.redis.c数据类型n/topics/data-types.html​​

2消息队列优缺点.1字符串(str系统运维工作内容ing)

字符串是所有编程语言中,最常见的和最常用的数据类型,而且也是redis最基本的数据类型之一,而且redis中所有的
key的类型都是字符串。
set key value [expiration EX seconds |PX milliseconds] [NX|XX]
#范例:
#设置值
127.0.0.1:6379> set key1 value1
#获取值
127.0.0.1:6379> get key1
"value1"
#获取类型
127.0.0.1:6379> TYPE key1
string
#设置自动过期时间
127.0.0.1:6379> SET name2 jack2 ex 3
#删除
127.0.0.1:6379> DEL key1

#批量设置多个 key
127.0.0.1:6379> MSET key1 value1 key2 value2
#批量获取多个key
127.0.0.1:6379> mget key1 key2
#追加数据:
127.0.0.1:6379> APPEND key1 append
#数值递增/递减
127.0.0.1:6379> set num 1
OK
127.0.0.1:6379> incr num #increase
(integer) 2
127.0.0.1:6379> decr num #decrease
(integer) 1
#返回字符串长度
127.0.0.1:6379> get key1
"taott"
127.0.0.1:6379> strlen key1
(integer) 5

2.2列表(消息队列是什么list)

列表是一个双向可读写的管道,其头部是左侧,尾部是右侧,一个列表最多可以包含2^32-1个元素;即4294967295个
元素。
#范例
127.0.0.1:6379> lpush list1 tao wen wu
(integer) 3
127.0.0.1:6379> lpush list1 china #左侧追加
(integer) 4
127.0.0.1:6379> rpush list1 ziyang #右侧追加
(integer) 5
127.0.0.1:6379> llen list1 #获取列表长度
(integer) 5
127.0.0.1:6379> rpop list1 #移除最后一个
"ziyang"
127.0.0.1:6379> lpop list1 #移除第一个
"china"

2.3集合(set)

Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据
#范例:
#生成集合key
127.0.0.1:6379> sadd set v1
(integer) 1
127.0.0.1:6379> sadd set2 v2 v4
(integer) 2
127.0.0.1:6379> type set
set
127.0.0.1:6379> type set2
set
#追加数值
127.0.0.1:6379> sadd set v2 v3 v4
(integer) 3
127.0.0.1:6379> sadd set v2 #重复的,无法追加成功
(integer) 0
#查看
127.0.0.1:6379> smembers set
1) "v1"
2) "v3"
3) "v4"
4) "v2"

#获取并集/交集
127.0.0.1:6379> smembers set
1) "v1"
2) "v3"
3) "v4"
4) "v2"
127.0.0.1:6379> smembers set2
1) "v4"
2) "v2"
127.0.0.1:6379> sinter set2 set
1) "v4"
2) "v2"
127.0.0.1:6379> sunion set set2
1) "v3"
2) "v4"
3) "v2"
4) "v1"

2.4有序集合(sorted set)

Redis有序集合和集合一样也是 string 类型元素的集合 且不允许重复的成员,
不同的是每个元素都会关联一个double双精度浮点型类型的分数,redis正是通过分数,来为集合中的成员进行从小到
大的排序,有序集合的成员是唯一的,但分数(scpre)却可以重复
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1),集合中最大的成员数为:2^32-1(4294967295),
每个集合可存储40多亿个成员
#范例:
127.0.0.1:6379> zadd zset1 1 v1
(integer) 1
127.0.0.1:6379> zadd zset1 2 v2
(integer) 1
127.0.0.1:6379> zadd zset1 2 v3
(integer) 1
127.0.0.1:6379> zadd zset1 3 v4
(integer) 1
127.0.0.1:6379> type zset1
zset

127.0.0.1:6379> zadd paihangbang 10 key1 20 key2 30 key3
(integer) 3
127.0.0.1:6379> zrevrange paihangbang 0 -1 withscores
1) "key3"
2) "30"
3) "key2"
4) "20"
5) "key1"
6) "10"

127.0.0.1:6379> zadd zset2 1 v1 2 v2 4 v3 5 v5
(integer) 4
127.0.0.1:6379> zcard zset1 #获取集合的长度
(integer) 4
127.0.0.1:6379> zrange zset2 1 2
1) "v2"
2) "v3"
127.0.0.1:6379> zrange zset2 1 4
1) "v2"
2) "v3"
3) "v5"
127.0.0.1:6379> zrange zset2 0 4
1) "v1"
2) "v2"
3) "v3"
4) "v5"
127.0.0.1:6379> zrange zset2 0 3
1) "v1"
2) "v2"
3) "v3"
4) "v5"
#返回某个数值的索引
127.0.0.1:6379> zrank zset2 v3
(integer) 2

2.5hash

hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,Redis中每个hash可以存储2^32-1
键值对(40多亿)。
#范例:
127.0.0.1:6379> hset hset1 name tom age 18
(integer) 2
127.0.0.1:6379> type hset1
hash
127.0.0.1:6379> hget hset1 name
"tom"
127.0.0.1:6379> hget hset1 age
"18"
127.0.0.1:6379> hdel hset1 age
(integer) 1
127.0.0.1:6379> hkeys hset1
1) "name"
2) "age"

3.消息队列

消息队列主要分为两种,分别是生产者消费者模式和发布者订阅者模式,这两种模式Redis都支持

3.1生产者消费者模式linux

在生产者消费者 Producer/Consumer 模式下, 
上层应用接收到外部请求后,开始处理其当前步骤的操作,在执行完成后。将已经完成的操作发送至指定的频道channel
当中,并由其下层的应用监听该频道并继续下一步的操作,
如果其处理完成后,没有下一步的操作就直接返回数据给外部请求,
如果还有下一步的操作,就再将任务发布到另外一个频道,由另外一个消费者继续监听和处理。


#模式介绍
生产者消费者模式下, 多个消费者同时监听一个队里,但是一个消息只能被最先抢到消息的消费者消费,即消息任务是
一次性读取和处理,此模式在分布式业务架构中非常常用
比较常用的软件还有RabbitMQ、 Kafka 、RocketMQ 、ActiveMQ等


                                            reiss-持久化、数据类型、消息队列

#队列介绍:
队列当中的消息由不同的生产者写入,也会有不同的消费者取出进行消费处理,但是一个消息一定是只能被取出一次,
也就是被消费一次。


                                            reiss-持久化、数据类型、消息队列

#生产者发布消息
127.0.0.1:6379> lpush channel msg1
(integer) 1
127.0.0.1:6379> lpush channel msg2
(integer) 2
127.0.0.1:6379> lpush channel msg3
(integer) 3
127.0.0.1:6379> lpush channel msg4
(integer) 4
127.0.0.1:6379> lpush channel msg5
(integer) 5

#查看队列所有消息
127.0.0.1:6379> lrange channel 0 -1
1) "msg5"
2) "msg4"
3) "msg3"
4) "msg2"
5) "msg1"

#消费者消费消息
127.0.0.1:6379> rpop channel
"msg1"
127.0.0.1:6379> rpop channel
"msg2"
127.0.0.1:6379> rpop channel
"msg3"
127.0.0.1:6379> rpop channel
"msg4"
127.0.0.1:6379> rpop channel
"msg5"
127.0.0.1:6379> rpop channel
(nil)

#再次验证队列消息
127.0.0.1:6379> lrange channel 0 -1
(empty list or set)

3数据类型的作用.2发布者订阅者模式

在发布者订阅者模式下,发布者将消息发布到指定的 channel 里面,凡是监听该channel的消费者都会收到同样的一
份消息
这种模式类似于是收音机模式,即凡是收听某个频道的听众都会收到主持人发布的相同的消息内容。
此模式常用于:群聊天、群通知、群公告等场景。
Subscriber :订阅者
Publisher 发布者
Channel 频道


                                            reiss-持久化、数据类型、消息队列

#订阅者订阅指定的频道
127.0.0.1:6379> subscribe channel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel"
3) (integer) 1

#发布者发布消息
publish channel test1
publish channel test2

#订阅多个频道
SUBSCRIBE channel1 channel2
#订阅所有频道
PSUBSCRIBE *
#订阅匹配的频道
PSUBSCRIBE chann* #匹配订阅多个频道