首页 科技正文

(伊春三)中:Redis「服务器」和客〖户端的〗通讯

admin 科技 2020-05-08 30 0

Redis〖客户端使用〗RESP(Redis序列化协议)与Redis服务器举行通讯,RESP在位于TCP之上,而网络模子上客户端和服务器是保持的双工的毗邻。如图1

而一个简朴的请求/响应的串行通讯模子如下图:

“串行”化通讯

“串行”化通讯比较简朴,上面那张图就很外面的反映出来这种通讯方式,同一个Connction需要在等上一个下令执行完成之后在执行下一个下令,我们在前面文章讲Redis各种类型的时刻做的测试,就是用这种方式。客户端发送一个指令到Redis实例,Redis实例处置完成之后将效果返回给客户端。

前面文章说Redis(为什)么要用多线程中有说过,Redis处置请求的速率稀奇快,我们一个请求的瓶颈主要是在I/O上面,而对于“串行”化通讯,每一个请求的发送都要等到上一个请求的响应先容,因此在串行模式下,单毗邻的大部分时间都虚耗在网络守候上,没有充实的行使服务器的处置能力

管道手艺

Redis在很早的时刻就支持管道手艺了,简朴来说,就是可以完全无需守候服务端应答地发送多条指令给服务端,并最终一次性读取所有应答。管道手艺最显著的优势是提高了redis服务的性能,通过管道手艺来举行大批量的操作的时刻,可以节约许多在网络延迟上的时间。

在.net core 的Redis客户端StackExchange.Redis则是基于Task来实现管道手艺,而StackExchangeRedis自己的异步也都是通过管道手艺来实现。

事务

在菜鸟教程中是这么先容的

Redis 事务可以一次执行多个下令, 而且带有以下三个主要的保证:

  • 批量操作在发送 EXEC 下令前被放入行列缓存。
  • 收到 EXEC 下令后进入事务执行,事务中随便下令执行失败,其余的下令依然被执行。
  • 在事务执行历程,其他客户端提交的下令请求不会插入到事务执行下令序列中。

一个事务从最先到执行会履历以下三个阶段:

  • 最先事务。
  • 下令入队。
  • 执行事务
  • 放弃事务

原理很简朴,客户端发送下令MULTI,服务器会将后续的下令都放入行列缓存,直到收到EXEC下令才会依次执行下令。单个Redis的下令是原子性的,然则Redis并没有在事务上增添任何的维持原子性的机制,当中心某条下令失败并不会导致其他下令的回滚,这个跟我们在关系型数据库的明白不一样,更多的像一个打包的批处置剧本。

菜鸟中有这么一句话

在事务执行历程,其他客户端提交的下令请求不会插入到事务执行下令序列中。

大略一看我还明白为事务开启会壅闭其他客户端的下令,吓得我马上做了一下测试

在客户端1中开启事务multi,并发送一个set 和 get 的下令,能看到都是QUEUED的状态,注释是准确的入队了

接着在客户端2中获取key1发现值是null,说明客户端1的下令还没有真正执行,接着设置key1的值为value2,接着取得key1的值,在客户端1中开启事务后,在客户端2是可以顺遂执行下令的,菜鸟中的话的意思实在客户端的下令不会进入开启事务谁人客户端的下令行列中。

我们接着在客户端1提交下令,key1《的值变为》value1,客户端2中设置的value2被更改为value1了。

我们将Redis事务与数据库事务的四大特征对比下

原子性 不支持 Redis单个指令是具有原子性的,然则事务没有
一致性 不支持 在上面的例子就可以瞥见,在客户端1的事务开启的时刻,我仍然能修改key1的值,在关系型数据库中我们有消极锁和乐观锁来解决这种并发问题,Redis也通过Watch可以实现乐观锁的效果,然则我照样没有体会出来有什么用处。在关系型数据中的事务,我们可能会先取出来值,在举行修改,最后提交事务,若是没有锁来保证,那么我们最后的数据就没有一致性了,然则对于Redis我照样没想出来什么场景下会需要用乐观锁来控制并发,知道的小伙伴贫苦见告一声。
隔离性 支持 Redis自己是没有隔离性这个说法的,之以是我以为是支持隔离性,由于我以为Redis的事务都是在最后才执行,而自己下令又是原子性的,以是隔离性对Redis是无意义的。
持久性 不支持 Redis有持久化方案,然则最高数据安全性的方式-AOF中的修改同步,仍然会在异常情况下导致数据丢失。

实在这个对比不太适当,Redis的事务只是顶着事务这个名字,做的照样批量处置的事情,它的关注点不应该在正真的事务上

剧本

在说事务的时刻有说事务更像是批处置的感受,而剧本也是批处置,差别的是,我们可以凭据上一个指令的效果作为我们下个<指令的>参数,《这是》处置逻辑问题的时刻稀奇有用。

Redis剧本是通过Eval下令实现,当客户都安使用Eval下令的时刻,Redis实例会通过lua注释器来执行剧本,我们这里的剧本也是lua剧本,用Abp中消灭缓存的的源码作 为示[例

EVAL "local keys = redis.call('keys', ARGV[1]) 
                for i=1,#keys,5000 
                do 
                redis.call('del', unpack(keys, i, math.min(i+4999, #keys)))
                end" 
                0 'Test_*'

这个剧本第一步将以Test做为前缀的key所有取出来存入变量keys,接着从1最先,以keys的长度为最大值,步长为5000举行遍历,每一步都是删除5000个key。为什么要用每次5000遍向来执行呢?由于unpack函数在数目太多的时刻会泛起 'too many results to unpack' 的错误,我们来实际操作下,往实例中添加10个用Test_为前缀的值,然后执行上面的剧本

可以看到我们以Test_做为前缀的Key都被删除了

公布/订阅模式

前面有讲到过,Redis实例和客户都之间是双工毗邻的,‘然则’前面所说的不管是简朴的下令照样事务剧本都是客户端自动提议请求,Redis「实例被动回应的」,而公布/订阅模式则是可以由Redis『实例自动给客户端』发送〖新〗闻,在下一节会详细说这种模式。

,

全讯网APP

全讯网APP是全讯网APP、皇冠最〖新〗网址的线路登入备用网址。〖新〗2皇冠备用网址提供多条〖新〗2皇冠最〖新〗、最快的登录线路,包括〖新〗2代理线路、〖新〗2会员线路,并提供〖新〗2皇冠最〖新〗网址APP下载。

版权声明

本文仅代表作者观点,
不代表本站Allbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论