Redis 订阅与发布
概述
实践
-
1. 打开两个redis客户端,客户端1输入指令
subscribe channel channel ...
-
2. 客户端2输入指令
publish channel message
// 客户端1
127.0.0.1:6379> subscribe channel1
// 客户端2
127.0.0.1:6379> publish channel1 "1 1 1"
(integer) 1
// 客户端1
1) "message"
2) "channel1"
3) "1 1 1"
Redis pipelining
-
• Redis pipelining(流水线)操作有助于客户端向服务器发送多个请求,而无需等待回复,最后只需一步即可读取回复。
-
• 大多数Redis客户端都支持pipelining。
请求/响应协议和往返时间(RTT)
-
• Redis是一个TCP服务器,使用客户机-服务器模型请求/响应协议。这意味着通常通过以下步骤来完成请求:客户端向服务器发送一个查询,并从socket中读取服务器响应,通常以阻塞的方式。服务器处理命令并将响应发送回客户端。四个命令顺序是这样的:
客户:INCR X
服务器:1
客户:INCR X
服务器:2
客户:INCR X
服务器:3
客户:INCR X
服务器:4
|Redis pipelining
Redis的事务与锁机制
Redis事务的定义和执行顺序
-
• Redis事务是一个单独隔离的操作,事务中所有命令都会被序列化、按顺序执行。事务在执行过程中不会被其他客户端发送过来的命令请求所打断。
-
• 一个事务从开始到执行会经历三个阶段
-
1. 开始事务
-
2. 命令入队
-
3. 执行事务
-
• 当
组队阶段
发生失败(如输入执行有语法错误),任意一条指令失败则所有指令都不会执行;到了执行阶段
则每条拼接的指令单独成功。 -
• 事务冲突解决思想
-
• 乐观锁。每次读数据的时候认为别人不会修改,所以不会上锁。但更新的时候会判断在此期间有没有数据更新,使用版本号等机制。乐观锁适用于多读类类型,可以提高吞吐量。
-
• 悲观锁。每次拿数据时都认为别人会修改,因此每次拿数据时都会上锁。
Redis事务指令
Multi
Multi -> 组队命令
Exec
Exec -> 执行命令
discard
组队时能通过discard
指令来放弃组队
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> sadd k2 one two three
QUEUED
127.0.0.1:6379> smembers k2
QUEUED
127.0.0.1:6379> exec
1) OK
2) "v1"
3) (integer) 3
4) 1) "three"
2) "one"
3) "two"
Watch & UnWatch
-
• Redis Watch命令用于监视一个(或多个)key,如果在事务执行之前key被其他命令所改动,那么事务将被打断。
//客户端1
127.0.0.1:6379> watch k1
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379>
// 客户端2
127.0.0.1:6379> set k1 v50
OK
127.0.0.1:6379>
// 客户端1
127.0.0.1:6379> exec
(nil)
持久化操作
概述
RDB
和AOF
进行持久化操作。RDB
RDB配置
save seconds changes
-
• 如果给定的秒数和给定的操作都发生了,Redis就会保存数据库
-
• save 3600 1 (一小时后,如果至少有一个键改变Redis会保存DB)
-
• save 300 100 (5分钟后,如果至少有100个键改变Redis会保存DB)
-
• 手动执行备份使用
save
,自动间隔执行bgsave
-
•
save
命令会阻塞Redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何命令请求的 -
•
bgsave
则会fork
一个子进程,然后该子进程会负责创建RDB文件,服务器进程会继续处理请求。
dbfilename dump.rdb
-
• 配置保存数据库的文件名称 -> dir ./
-
• 工作目录
RDB备份过程
-
• Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这能确保性能。如果需要大规模数据的恢复,且对数据恢复的完整性不是特别敏感,那RDB比AOF方式更加高效,RDB的缺点是最后一次持久化的数据可能丢失。
-
• 默认情况下如果启用RDB并且最近的后台保存失败,redis将停止接受写入。如果后台保存进程重新开始工作,redis将自动允许再次写入。
AOF
AOF(Append Only File),是以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有指令记录下来(读操作不记录),只追加文件但不可以改写文件。Redis启动之后会读取该文件并重新构建数据。Redis从后根据日志文件内容从前到后执行一遍以完成数据恢复工作。
AOF配置
appendonly yes
RDB VS AOF
RDB优点:
-
1. RDB是Redis数据的一个非常紧凑的单文件时间点表示。RDB文件非常适合备份。例如,您可能希望在最近24小时内每小时存档RDB文件,并在30天内每天保存RDB快照。这允许您在发生灾难时轻松地恢复数据集的不同版本。
-
2. RDB非常适合于灾难恢复,它是一个紧凑的文件,可以传输到远端的数据中心,也可以传输到Amazon S3(可能是加密的)。
-
3. RDB最大化了Redis的性能,因为Redis父进程需要做的唯一工作就是创建一个子进程来完成其余的工作。父进程永远不会执行磁盘I/O或类似的操作。
-
4. 与AOF相比,RDB允许更快地重新启动大数据集。
-
5. 在副本上,RDB支持重启和故障转移后的部分重新同步。
RDB缺点:
-
1. 如果你需要在Redis停止工作(例如断电后)时尽量减少数据丢失的机会,RDB不是很好。您可以在生成RDB的位置配置不同的保存点(例如,在至少5分钟并对数据集进行100次写入之后,您可以拥有多个保存点)。然而,你通常每五分钟或更久就会创建一个RDB快照,所以万一Redis因为任何原因停止工作而没有正确关闭,你应该准备好丢失最近几分钟的数据。
-
2. RDB经常需要fork(),以便使用子进程在磁盘上持久化。如果数据集很大,fork()可能会很耗时,如果数据集非常大,CPU性能不佳,可能会导致Redis停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但频率较低,您可以调整您想要重写日志的频率,而不需要任何持久性的权衡。
AOF优点:
-
1. 使用AOF Redis性能更好。在默认的每秒fsync策略下,写性能仍然很好。Fsync是使用后台线程执行的,主线程在没有Fsync正在进行的时候会努力执行写操作,所以你只能损失一秒钟的写操作。
-
2. AOF日志是一个只能追加的日志,因此在停电时不存在寻标问题,也不存在损坏问题。即使由于某些原因(磁盘已满或其他原因),日志以写了一半的命令结束,redis-check-aof工具也能够轻松地修复它。
-
3. 当AOF在后台变得太大时Redis能够自动重写。重写是完全安全的,因为当Redis继续追加到旧文件时,一个全新的文件会用创建当前数据集所需的最小操作集产生,一旦第二个文件准备好,Redis就会切换这两个文件并开始追加到新文件。
-
4. AOF以易于理解和解析的格式包含所有操作的一个接一个的日志。可以导出AOF文件。例如,即使您不小心使用FLUSHALL命令刷新了所有内容,只要在此期间没有执行重写日志,您仍然可以通过停止服务器、删除最新命令并重新启动Redis来保存数据集。
AOF缺点:
-
1. 对于相同的数据集,AOF文件通常比等效的RDB文件大。
-
2. AOF可能比RDB慢,这取决于fsync策略。一般来说,将fsync设置为每秒一次,性能仍然非常高,禁用fsync,即使在高负载下,它也应该和RDB一样快。RDB仍然能够提供更多关于最大延迟的保证,即使在巨大的写负载的情况下。
阅读资料: https://redis.io/docs/management/persistence/
原文始发于微信公众号(ProgrammerHe):Redis笔记(二)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207958.html