Redis笔记(二)

Redis 订阅与发布

概述

Redis发布订阅(pub/sub)是一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。Redis客户端可以订阅任何数量的频道。

实践

  1. 1. 打开两个redis客户端,客户端1输入指令 subscribe channel channel ...

  2. 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
客户端和服务器通过网络连接。这样的链接可以非常快(环回接口),也可以非常慢(在两台主机之间通过Internet建立的多跳连接)。无论网络延迟是多少,数据包从客户端到服务器以及从服务器返回到客户端以携带应答都需要时间。
这个时间称为RTT(往返时间)。当客户端需要在一行中执行许多请求时(例如向同一个列表中添加许多元素,或者用许多键填充数据库),很容易看出这会如何影响性能。例如,如果RTT时间是250毫秒(在Internet上非常慢的链接的情况下),即使服务器每秒能够处理100k个请求,我们每秒最多只能处理4个请求。如果使用的接口是环回接口,则RTT要短得多,通常为亚毫秒级,但如果需要在一行中执行许多写入操作,则即使是这样,RTT也会增加很多。

|Redis pipelining

可以实现一个请求/响应服务器,这样即使客户端还没有读取旧的响应,它也能够处理新的请求。这样就可以向服务器发送多个命令,而根本不需要等待响应,最后在一个步骤中读取响应。这被称为流水线,是一种广泛使用了几十年的技术。例如,许多POP3协议已经支持这一功能,极大加快了从服务器下载新邮件的过程。Redis从早期就支持流水线,所以无论你运行的是什么版本,你都可以在Redis中使用流水线。

Redis的事务与锁机制

Redis事务的定义和执行顺序

  • • Redis事务是一个单独隔离的操作,事务中所有命令都会被序列化、按顺序执行。事务在执行过程中不会被其他客户端发送过来的命令请求所打断。

  • • 一个事务从开始到执行会经历三个阶段

    1. 1. 开始事务

    2. 2. 命令入队

    3. 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)

持久化操作

概述

Redis将数据保存到内存中,带来的好处是Redis的读写效率非常高。但同样缺点也很明显,一旦遇到宕机或断电,内存中的数据将会全部丢失。于是Redis持久化即将内存数据持久化到硬盘文件,以及通过备份文件来恢复数据。Redis通过RDBAOF进行持久化操作。

RDB

RDB持久化方案是按照指定时间间隔对数据集生成的时间点快照(point-to-time snapshot)。它以紧缩的二进制文件保存Redis数据库某一时所有数据对象的内存快照。

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. 1. RDB是Redis数据的一个非常紧凑的单文件时间点表示。RDB文件非常适合备份。例如,您可能希望在最近24小时内每小时存档RDB文件,并在30天内每天保存RDB快照。这允许您在发生灾难时轻松地恢复数据集的不同版本。

  2. 2. RDB非常适合于灾难恢复,它是一个紧凑的文件,可以传输到远端的数据中心,也可以传输到Amazon S3(可能是加密的)。

  3. 3. RDB最大化了Redis的性能,因为Redis父进程需要做的唯一工作就是创建一个子进程来完成其余的工作。父进程永远不会执行磁盘I/O或类似的操作。

  4. 4. 与AOF相比,RDB允许更快地重新启动大数据集。

  5. 5. 在副本上,RDB支持重启和故障转移后的部分重新同步。

RDB缺点:

  1. 1. 如果你需要在Redis停止工作(例如断电后)时尽量减少数据丢失的机会,RDB不是很好。您可以在生成RDB的位置配置不同的保存点(例如,在至少5分钟并对数据集进行100次写入之后,您可以拥有多个保存点)。然而,你通常每五分钟或更久就会创建一个RDB快照,所以万一Redis因为任何原因停止工作而没有正确关闭,你应该准备好丢失最近几分钟的数据。

  2. 2. RDB经常需要fork(),以便使用子进程在磁盘上持久化。如果数据集很大,fork()可能会很耗时,如果数据集非常大,CPU性能不佳,可能会导致Redis停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但频率较低,您可以调整您想要重写日志的频率,而不需要任何持久性的权衡。

AOF优点:

  1. 1. 使用AOF Redis性能更好。在默认的每秒fsync策略下,写性能仍然很好。Fsync是使用后台线程执行的,主线程在没有Fsync正在进行的时候会努力执行写操作,所以你只能损失一秒钟的写操作。

  2. 2. AOF日志是一个只能追加的日志,因此在停电时不存在寻标问题,也不存在损坏问题。即使由于某些原因(磁盘已满或其他原因),日志以写了一半的命令结束,redis-check-aof工具也能够轻松地修复它。

  3. 3. 当AOF在后台变得太大时Redis能够自动重写。重写是完全安全的,因为当Redis继续追加到旧文件时,一个全新的文件会用创建当前数据集所需的最小操作集产生,一旦第二个文件准备好,Redis就会切换这两个文件并开始追加到新文件。

  4. 4. AOF以易于理解和解析的格式包含所有操作的一个接一个的日志。可以导出AOF文件。例如,即使您不小心使用FLUSHALL命令刷新了所有内容,只要在此期间没有执行重写日志,您仍然可以通过停止服务器、删除最新命令并重新启动Redis来保存数据集。

AOF缺点:

  1. 1. 对于相同的数据集,AOF文件通常比等效的RDB文件大。

  2. 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

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!